Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Книга Лекции Паскаль

.pdf
Скачиваний:
23
Добавлен:
24.02.2016
Размер:
902.53 Кб
Скачать

Василькова И.В.

Лекции

Паскаль

 

 

if a < c then m := a else m := c

 

else

 

{3}

if b < c then m := b else m := c;

Если требуется проверить несколько условий, их объединяют знаками логических операций. Так, выражение в примере 5.1 будет истинно в том случае, если выполнится одновременно условие a < b и хотя бы одно из условий a > d и a = 0.

Частая ошибка при программировании условных операторов –

неверная запись проверки на принадлежность диапазону. Например, условие

0 < x < 1 нельзя записать непосредственно. Правильный способ: if(0 < x) and (x < 1) then..., поскольку фактически требуется задать проверку выполнения одновременно двух условий: x > 0 и x < 1.

Вторая ошибка – отсутствие блока после else, если на самом деле по этой ветви требуется выполнить более одного действия. Эта ошибка не может быть обнаружена компилятором, поскольку является не синтаксической, а семантической, то есть смысловой.

5.2. Оператор варианта case

Оператор варианта (выбора) предназначен для разветвления процесса вычислений на несколько направлений. Структурная схема оператора приведена на рис. 5.3. Формат оператора:

case выражение of константа_1 : оператор_1; константа_2 : оператор_2;

*

константа_n : оператор_n; [ else : оператор ]

end;

Рис. 5.3.

Выполнение оператора начинается с вычисления выражения. Затем управление передается на оператор, помеченный константами, значение одной из которых совпало с результатом вычисления выражения. После

21

Василькова И.В.

Лекции

Паскаль

этого выполняется выход из оператора. Если совпадения не произошло, выполняются операторы, расположенные после слова else, а при его отсутствии управление передается оператору, следующему за case.

Выражение после ключевого слова case должно быть порядкового типа, константы – того же типа, что и выражение. Чаще всего после case используется имя переменной. Перед каждой ветвью оператора можно записать одну или несколько констант через запятую или операцию диапазона, обозначаемую двумя идущими подряд точками, например:

case a of

4 : writeln('4');

5, 6 : writeln('5 или 6'); 7..12: writeln('от 7 до 12');

end;

ВНИМАНИЕ Если по какой-либо ветви требуется записать не один, а несколько операторов, они заключаются в блок с помощью ключевых слов begin и end.

Пример #5.2

Написать программу, которая запрашивает у пользователя номер дня недели, затем выводит название дня недели или сообщение об ошибке, если введены неверные данные.

program name_day;

var nom_day : integer; begin

writeln('Vvedite nomer '); readln(nom_day);

case nom_day of

1:writeln('Ponedelnik');

2:writeln('Vtornik');

3:writeln('Sreda');

4:writeln('Chetverg');

5:writeln('Pjatnica');

6:writeln('Subbota');

7:writeln('Voskresenje');

else: writeln('error'); end;

readln;

end.

6. Операторы цикла

Операторы цикла используются для вычислений, повторяющихся многократно. В Паскале три вида циклов: цикл с предусловием while, цикл с

22

Василькова И.В.

Лекции

Паскаль

постусловием repeat и цикл с параметром for. Каждый из них состоит из определенной последовательности операторов.

Блок, ради выполнения которого и организуется цикл, называется телом цикла. Остальные операторы служат для управления процессом повторения вычислений: это начальные установки, проверка условия продолжения цикла и модификация параметра цикла (рис. 6.1). Один проход цикла называется итерацией.

Начальные установки служат для того, чтобы до входа в цикл задать значения переменных, которые в нем используются.

Проверка условия продолжения цикла выполняется на каждой итерации либо до тела цикла (тогда говорят о цикле с предусловием, рис. 6.1, а), либо после тела цикла (цикл с постусловием, рис. 6.1, б). Разница между ними состоит в том, что тело цикла с постусловием всегда выполняется хотя бы один раз, после чего проверяется, надо ли его выполнять еще раз. Проверка необходимости выполнения цикла с предусловием делается до тела цикла, поэтому возможно, что он не выполнится ни разу.

Параметром цикла называется переменная, которая используется при проверке условия цикла и принудительно изменяется на каждой итерации, причем, как правило, на одну и ту же величину. Если параметр цикла целочисленный, он называется счетчиком цикла. Количество повторений такого цикла можно определить заранее. Параметр есть не у всякого цикла.

Цикл завершается, если условие его продолжения не выполняется. Возможно принудительное завершение как текущей итерации, так и цикла в целом. Для этого служат операторы break, continue и goto.

23

Василькова И.В.

Лекции

Паскаль

Рис. 6.1.

6.1. Цикл с предусловием while

Формат оператора прост:

while выражение do оператор

Выражение должно быть логического типа. Например, это может быть операция отношения или просто логическая переменная. Если результат вычисления выражения равен true, выполняется расположенный после служебного слова do простой или составной оператор. Эти действия повторяются до того момента, пока результатом выражения не станет значение false. После окончания цикла управление передается на следующий за ним оператор.

ВНИМАНИЕ Если в теле цикла необходимо выполнить более одного оператора, необходимо заключить их в блок с помощью begin и end.

Пример #6.1.

Программа печати таблицы значений функции для аргумента, изменяющегося в заданных пределах с заданным шагом.

y= {

t ,

x < 0

t x,

10 > x ≥ 0

2 t,

x ≥ 10

Опишем алгоритм в словесной форме.

1.Ввести исходные данные.

2.Взять первое значение аргумента.

3.Определить, какому из интервалов оно принадлежит.

4.Вычислить значение функции по соответствующей формуле.

5.Вывести строку таблицы.

6.Перейти к следующему значению аргумента.

7.Если оно не превышает конечное значение, повторить шаги 3 - 6, иначе закончить.

Шаги 3 - 6 повторяются многократно, поэтому для их выполнения надо организовать цикл. Назовем в программе начальное значение аргумента Xn, конечное значение аргумента Xk, шаг изменения аргумента dX, параметр - t. Все величины вещественные. Программа выводит таблицу, состоящую из двух столбцов - значений аргумента и соответствующих им значений функции.

program tabl_fun;

24

Василькова И.В.

 

Лекции

 

Паскаль

 

 

 

var Xn, Xk, dX, t, x, y : real;

 

 

begin

 

 

 

 

writeln('Введите Xn, Xk, dX, t');

 

readln(Xn, Xk, dX, t);

 

');

writeln('

--------------------------- X

|

Y

writeln('|

|');

writeln(' ---------------------------

 

 

 

');

x := Xn;

 

 

{ Начальные

установки }

while

x <= Xk do begin

t;

{ Заголовок

цикла }

if

x < 0 then y :=

 

 

if

(x >= 0)

and (x

< 10) then y := t * x;

 

if

x >= 10

then y

:=

2 * t;

 

writeln('|', x:9:2,'

|', y:9:2,'

|');

x := x + dX;

{ Модификация

параметра цикла }

end;

');

writeln(' ---------------------------

end.

6.2. Цикл с постусловием repeat

Тело цикла с постусловием заключено между служебными словами repeat и until, поэтому заключать его в блок не требуется:

repeat

тело цикла until выражение

В отличие от цикла while, этот цикл будет выполняться до тех пор, пока логическое выражение после слова until ложно. Как только результат выражения станет истинным, произойдет выход из цикла. Вычисление выражения выполняется в конце каждой итерации цикла.

Этот вид цикла применяется в тех случаях, когда тело цикла необходимо обязательно выполнить хотя бы один раз.

Пример #6.2.

Программа, вычисляющая квадратный корень вещественного аргумента X с заданной точностью eps по итерационной формуле:

yn = 1/2(yn-1 + x/yn-1),

где yn-1 - предыдущее приближение к корню (в начале вычислений выбирается произвольно), yn - последующее приближение. Процесс вычислений прекращается, когда приближения станут отличаться друг от друга по абсолютной величине менее, чем на величину заданной точности.

program square_root;

точность }

var X,

eps,

{ аргумент и

Yp,

Y : real;

{ предыдущее

и последующее приближение }

begin

 

 

 

repeat

writeln('Введите аргумент и точность (больше нуля): '); readln(X, eps);

until (X > 0) and (eps > 0);

25

Василькова И.В.

Лекции

Паскаль

Y := 1; repeat

Yp := Y;

Y := (Yp + X / Yp) / 2; until abs(Y - Yp) < eps;

writeln('Корень из ', X:6:3, ' с точноcтью ', eps:7:5, 'равен ', Y:9:5);

end.

6.3. Цикл с параметром for

Этот оператор применяется, если требуется выполнить тело цикла заранее заданное количество раз. Параметр порядкового типа на каждом проходе цикла автоматически либо увеличивается, либо уменьшается на единицу:

for параметр := выражение_1 to выражение_2 do оператор for параметр := выражение_2 downto выражение_1 do оператор Выражения должны быть того же типа, что и переменная цикла,

оператор – простым или составным.

Пример #6.3.

Программа выводит на экран в столбик числа от 10 до 1 и подсчитывает их сумму:

var i, sum : integer; begin

sum := 0;

for i := 10 downto 1 do begin writeln(i); inc(sum, i)

end;

writeln('Сумма чисел: ', sum); end.

ВНИМАНИЕ Если в теле цикла необходимо выполнить более одного оператора, необходимо заключить их в блок с помощью begin и end.

Выражения, определяющие начальное и конечное значения счетчика, вычисляются один раз до входа в цикл. Цикл for реализован в Паскале как цикл с предусловием, то есть его можно представить в виде эквивалентного оператора while. После нормального завершения цикла значение счетчика не определено.

6.4. Рекомендации по использованию циклов

Часто встречающимися ошибками при программировании циклов являются использование в теле цикла переменных, которым не были присвоены начальные значения, а также неверная запись условия продолжения цикла. Нужно помнить и о том, что в операторе while истинным

26

Василькова И.В.

Лекции

Паскаль

должно являться условие повторения вычислений, а в операторе repeat – условие их окончания.

Чтобы избежать ошибок, рекомендуется:

не забывать о том, что если в теле циклов while и for требуется выполнить более одного оператора, нужно заключать их в блок;

убедиться, что всем переменным, встречающимся в правой части операторов присваивания в теле цикла, до этого присвоены значения, а также возможно ли выполнение других операторов;

проверить, изменяется ли в теле цикла хотя бы одна переменная, входящая в условие продолжения цикла;

предусматривать аварийный выход из итеративного цикла по достижению некоторого предельно допустимого количества итераций.

6.5.Процедуры передачи управления

ВПаскале есть несколько стандартных процедур, изменяющих последовательность выполнения операторов:

break – завершает выполнение цикла, внутри которого записана;

continue – выполняет переход к следующей итерации цикла;

exit – выходит из программы или подпрограммы, внутри которой

записана;

halt – немедленно завершает выполнение программы.

Кроме того, для передачи управления используется оператор перехода

goto.

Рассмотрим пример применения процедур передачи управления.

Пример #6.4.

Программа вычисления значения функции Сh x (гиперболический косинус) с помощью бесконечного ряда Тейлора с точностью eps по формуле:

Y = 1 + x2/2! + x4/4! + x6/6! + ... + x2n/(2n)! + ...

Этот ряд сходится при любых значениях аргумента. При увеличении номера n модуль члена ряда Cn стремится к нулю. При некотором n неравенство |Cn| >= eps перестает выполняться, и вычисления прекращаются.

Общий алгоритм прост: задать начальное значение суммы ряда, а затем многократно вычислять очередной член ряда и добавлять его к ранее найденной сумме, пока абсолютная величина очередного члена ряда не станет меньше заданной точности.

До выполнения программы предсказать, сколько членов ряда потребуется просуммировать, невозможно. В цикле такого рода есть опасность, что он никогда не завершится - как из-за возможных ошибок в вычислениях, так и из-за ограниченной области сходимости ряда. Кроме того, в данном случае при увеличении абсолютной величины аргумента значения функции сильно возрастают и могут переполнить разрядную сетку. Поэтому для надежности программы необходимо

27

Василькова И.В.

Лекции

Паскаль

предусмотреть аварийный выход из цикла с печатью предупреждающего сообщения по достижении некоторого максимально допустимого количества итераций.

Прямое вычисление члена ряда по приведенной выше общей формуле, когда х возводится в степень, вычисляется факториал, а затем числитель делится на знаменатель, имеет два недостатка, которые делают этот способ непригодным. Первый недостаток большая погрешность вычислений. Второй недостаток связан с эффективностью вычислений: как легко заметить, при вычислении очередного члена ряда нам уже известен предыдущий, поэтому вычислять каждый член ряда "от печки" нерационально.

Для уменьшения количества выполняемых действий следует воспользоваться рекуррентной формулой получения последующего

члена ряда через предыдущий Cn+1 = Cn * T, где T - некоторый множитель. Подставив в эту формулу Cn и Cn+1, получим выражение для вычисления Т:

Ниже приведен текст программы с комментариями.

program ch;

{

максимальное количество итераций }

const MaxIter = 500;

var x, eps : double;

{

аргумент и точность

}

 

 

c, y : double;

{

член ряда и его сумма }

 

 

n : integer;

{

номер

члена ряда }

 

 

}

done : boolean;

{

признак достижения

точности

begin

 

 

 

 

 

 

writeln('Введите аргумент и точность:');

 

 

 

readln(x, eps);

 

 

 

 

 

 

done := true;

{первый член

ряда и нач. значение

суммы}

c := 1; y := c;

n := 0;

 

 

 

 

 

 

while abs(c) > eps do begin

 

 

 

 

c := c * sqr(x) /(2

* n + 1)/(2 * n + 2);

 

 

y := y + c;

{ очередной член ряда }

 

}

 

{ добавление

члена ряда к

сумме

 

inc(n);

 

begin

{аварийный

 

из цикла }

if n > MaxIter then

выход

writeln('Ряд расходится!'); done := false; break

end end;

if done then

writeln('Для аргумента ', x, ' значение функции: ', y:5:3, #13#10,'вычислено с точностью', eps, ' за ', n, ' итераций');

28

Василькова И.В.

Лекции

Паскаль

readln;

end.

6.6. Оператор перехода goto

Этот оператор имеет простой синтаксис: в точке программы, из которой требуется организовать переход, после слова goto через пробел записывается имя метки, например, goto 1 или goto error. При программировании на Паскале необходимость в применении оператора перехода возникает в очень ограниченном количестве ситуаций, в большинстве же случаев используются операторы циклов вместе с процедурами передачи управления.

Использование оператора безусловного перехода оправдано, как правило, в двух случаях:

принудительный выход вниз по тексту программы из нескольких вложенных циклов или переключателей;

переход из нескольких мест программы в одно (например, если перед выходом из программы необходимо всегда выполнять какие-либо действия).

Во всех остальных случаях следует привести алгоритм к структурному

виду, то есть преобразовать его так, чтобы он мог быть записан с помощью базовых конструкций.

7. Простые типы данных

Информация, которую требуется обрабатывать в программе, имеет различную структуру. Для ее адекватного представления используются типы данных, которые программист определяет сам в разделе описания типов type. При описании типу дается произвольное имя. Его можно использовать для описания программных объектов так же, как и стандартные имена типов:

type имя_типа = описание_типа

...

var имя_переменной : имя_типа

Применяется и задание типа непосредственно при описании переменных. Его удобно применять, если тип используется только в одном месте программы:

var имя_переменной : описание_типа

7.1. Перечисляемый тип данных

При написании программ часто возникает потребность определить несколько связанных между собой именованных констант, имеющих различные значения. Для этого удобно воспользоваться перечисляемым типом данных, все возможные значения которого задаются списком констант:

type имя_типа = (список имен констант)

29

Василькова И.В.

Лекции

Паскаль

Константы в списке перечисляются через запятую, например: type Menu = (READ, WRITE, EDIT, QUIT)

Переменным перечисляемого типа можно присвоить либо значение одной из перечисленных констант, либо другой переменной того же типа:

var m, n : Menu;

...

m := READ; n := m;

Перечисляемый тип относится к порядковым типам данных. Использовать перечисляемый тип в операциях ввода-вывода нельзя. Имена констант в пределах области их описания (программы или подпрограммы) должны быть уникальными.

7.2.Интервальный тип данных

Спомощью интервального типа задается диапазон значений какоголибо типа:

type имя_типа = константа_1 .. константа_2

Константы должны быть одного и того же порядкового типа. Тип, на котором строится интервал, называется базовым. Константа_1 должна быть меньше или равна константе_2. Примеры описания интервальных типов:

Type Hour = 0 .. 23; Range = -100 .. 100;

Letters = 'a' .. 'z';

Как и для других типов, определяемых программистом, интервальный тип можно задать прямо при описании переменной, например:

var r : -100 .. 100;

С переменной интервального типа можно делать все, что допустимо для ее базового типа. Интервальный тип используется в программах как самостоятельно, так и в составе определения составного типа – массива.

7.3. Массивы

При использовании простых переменных каждой области памяти, предназначенной для хранения какого-либо значения, соответствует свое имя. Если с группой величин одинакового типа требуется выполнять однообразные действия, им дают одно имя, а различают по порядковому номеру (индексу). Это позволяет компактно записывать множество операций с помощью циклов.

Конечная именованная последовательность однотипных величин называется массивом. Чтобы описать массив, надо задать, какого типа его элементы и каким образом они пронумерованы:

type имя_типа = array [тип_индекса] of тип_элемента Здесь array и of – ключевые слова, тип индекса задается в квадратных скобках. Примеры:

30