- •Тема 13. Программирование на языке паскаль
- •13.1. Базовые элементы языка Паскаль
- •13.1.1. Алфавит языка Паскаль
- •13.1.2. Элементарные конструкции
- •13.1.3. Концепция типа для данных
- •13.1.4. Стандартные типы данных
- •13.1.5.Перечисляемый тип. Интервальный тип
- •13.1.6. Константы
- •13.1.7. Переменные. Инициализация переменных
- •13.1.8. Выражения
- •13.2. Структура программы
- •13.3. Оператор присваивания
- •13.4. Операторы ввода и вывода
- •13.5. Пример линейной программы
- •13.5.1. Понятие сложности выражения. Оптимизация вычислений
- •13.5.2.Оптимизация линейных программ
- •13.6. Ветвящиеся программы
- •13.6.1. Понятие условия. Тип данных Boolean (логический)
- •13.6.2. Составной оператор
- •13.6.3.Выбирающие операторы: условный оператор
- •13.6.4.Ветвящиеся программы. Пример.
- •13.6.5. Оптимизация ветвящихся программ по времени
- •13.6.6.Выбирающие операторы: оператор варианта
13.5. Пример линейной программы
Пример 1. Программа вычисления площади круга, вписанного в треугольник и площади круга, описанного около треугольника.
Program Triangle; {программа вычисляет площади, вписанного в треугольник и описанного около треугольника кругов}
Const Pi = 3.1415926;
Line = ‘_______________________________’;
Var a, b, c : Real;
Sint, Sout : Real;
S, p : Real;
Begin
{ ввод данных }
Write (‘введите стороны треугольника a b c ‘);
Readln (a, b, c);
{ вычисления }
p := (a + b + c)/2;
S := Sqrt(p*(p – a)*(p – b)*(p – c));
Sout := Pi*sqrt(a*b*c/4/S);
Sint := Pi*sqrt(2*S/p);
{ печать ответа }
Writeln; Writeln (Line);
Writeln(‘Sвпис = ‘, Sout); Writeln(Line);
Writeln(‘Sопис = ‘, Sint); Writeln(Line)
End .
Для оформления вывода в операторах Write, Writeln можно использовать строку. Например: writeln(‘***’, ‘площадь вписанной окружности = ‘, sint, ‘***’).
13.5.1. Понятие сложности выражения. Оптимизация вычислений
Основной критерий качества программы – ее правильность. Строгое математическое понятие правильности программы пока выходит за рамки нашего рассмотрения. Будем предполагать, что наши программы выполняют именно те действия, которые мы от них ожидаем.
В этом предположении критериями качества программы являются, например, ее размер, объем памяти, отведенной под данные, скорость выполнения и т.д.
Скорость выполнения неветвящейся программы определяется количеством вычислений, необходимых для получения значений выражений, содержащихся в операторах присваивания и операторах вывода.
Количество вычислений, необходимых для получения значения выражения, будем называть его сложностью. Рассмотрим пример:
U := X*Cos(Alfa) + Y*Sin(Alfa) (1)
V := –X*Sin(Alfa) + Y*Cos(Alfa) (2)
Для вычисления значения U неoбходимо выполнить два вычисления значения тригонометрической функции, два умножения и одно сложение. Это и есть сложность правой части оператора (1). Правая часть оператора (2) имеет по существу ту же сложность, что и оператора (1).
Разумеется, скорости вычислений значений элементарных функций, операций умножения и сложения различны и зависят от реализации языка программирования. Однако реально предполагать, что скорости вычислений всех элементарных трансцендентных функций равны между собой, скорости выполнения мультипликативных операций равны, и скорости выполнения аддитивных операций также равны.
Пусть Tf, Tm и Ta – времена вычисления соответственно функций, умножений и сложений, а T(U) – время вычисления значения U. Тогда
T(U) = 2Tf + 2Tm + Ta, T(V) = T(U) (3)
Время вычисления значения выражения и есть мера его сложности. Понятно, что программист должен заботиться об уменьшении сложности выражений, входящий в программу. Для этого используют:
а)Тождественные пребразования, уменьшающие сложность;
б) Предварительные вычисления общих подвыражений;
Примеры:
U := 4*Sin(X)*Cos(X) + 3 U := 2*Sin(2*X) + 3
U := Sin(X)^2 – 3*Sin(X) + 2 U := (Sin(X) – 2)*(Sin(X) – 1) Y := Sin(X); U := (Y – 2)*(Y – 1)
Между величинами Tf, Tm и Ta существуют соотношения
Tf >> Tm > Ta (4)
которые при программировании вычислений нельзя игнорировать. Поэтому особенное внимание нужно уделять уменьшению функциональной и мультипликативной сложности за счет аддитивной.
Следующий пример по существу определяет оптимальную форму записи многочлена для задачи вычисления его значения.
Пример 2 ( Схема Горнера)
Вычислить значение Y = a0x3 + a1x2 + a2x + a3;
Поскольку операции возведения в степень в языке нет, можно заменить его умножениями:
Y = a0*x*x*x + a1*x*x + a2*x + a3;
В этом варианте T(Y) = 6Tm + 3Tа;
Вынося x за скобки там, где это возможно, получим:
Y = ((a0x + a1)x + a2)x + a3; {Схема Горнера}. T(Y) = 3Tm + 3Tа.
Можно показать, что схема Горнера вычисления многочлена является оптимальной.