Программирование. Условные операторы Pascal

advertisement
Программирование. Условные операторы Pascal-Паскаль

Оператор выбора Паскаля
Условные операторы Pascal-Паскаль
Условные операторы позволяют выбирать для выполнения те или иные части программы в зависимости от
некоторых условий. Если, например, в программе используются вещественные переменные x и z, и на какомто этапе решения задачи требуется вычислить z=max(x, y), то желаемый результат получается в результате
выполнения либо оператора присваивания z:=x, либо оператора присваивания z:=y. Поскольку значения
переменных x и y заранее неизвестны, а определяются в процессе вычислений, то в программе необходимо
предусмотреть оба эти оператора присваивания. Однако на самом деле должен выполниться один из них.
Поэтому в программе должно содержаться указание о том, в каком случае надо выбирать для исполнения тот
или иной оператор присваивания.
Это указание естественно сформулировать с использованием отношения x>y. Если это отношение при
текущих значениях x и y справедливо (принимает значение true), то для исполнения должен выбираться
оператор z:=x; в противном случае для исполнения должен выбираться оператор z:=y (при x=y безразлично,
какой оператор выполнять, так что выполнение оператора z:=y в этом случае даст правильный результат).
Для задания подобного рода разветвляющихся вычислительных процессов в языках программирования
существуют условные операторы. Рассмотрим полныйусловный оператор Паскаля:
if B then S1 else S2
Здесь if (если), then (то)
и else (иначе)
являются
служебными
словами, В –
логическое
выражение,
а S1 и S2 – операторы.
Выполнение такого условного оператора в Паскале сводится к выполнению одного из входящих в него
операторов S1 или S2: если заданное в операторе условие выполняется (логическое выражение В принимает
значение true), то выполняется оператор S1, в противном случае выполняется оператор S2.
Алгоритм решения упомянутой выше задачи вычисления z= max( x, y) можно задать в виде условного
оператора Паскаля
if x>y then z:= x else z:= y
При формулировании алгоритмов весьма типичной является такая ситуация, когда на определенном этапе
вычислительного процесса какие-либо действия надо выполнить только при выполнении некоторого условия,
а если это условие не выполняется, то на данном этапе вообще не нужно выполнять никаких действий.
Простейшим примером такой ситуации является замена текущего значения переменной х на абсолютную
величину этого значения: если x<0, то необходимо выполнить оператор присваивания x:= - x; если же x>=0,
то текущее значение х должно остаться без изменений, т.е. на данном этапе вообще не надо выполнять
каких-либо действий.
В подобных ситуациях удобна сокращенная форма записи условного оператора в Паскале:
if B then S
Правило выполнения сокращенного условного оператора Паскаля достаточно очевидно: если значение
логического выражения В есть true, то выполняется оператор S; в противном случае никаких иных действий
не производится.
В языке программирования Паскаль в условном операторе между then и else, а также после else по
синтаксису может стоять только один оператор. Если же при выполнении (или невыполнении) заданного
условия надо выполнить некоторую последовательность действий, то их надо объединить в единый,
составной оператор, т.е. заключить эту последовательность действий в операторные скобки begin... end (это
важно!). Если, например, при x< y надо поменять местами значения этих переменных, то условный
оператор будет записан следующим образом в Паскале:
if x<y then begin r:=x; x:=y; y:=r end
Наличие
сокращенной
формы условного
оператора
Паскаля требует
большой
осторожности
при
использовании. Например, условный оператор
if B1 then if B2 then S1 else S2
допускает, вообще говоря, две разные трактовки:

как полный условный оператор Паскаля вида
if B1 then begin
if B2 then S1 end
else S2

как сокращенный условный оператор Паскаля вида
if B1 then begin
if B2 then S1 else S2 end
По правилам Паскаля имеет место вторая трактовка, т.е. считается, что каждое слово else соответствует
первому предшествующему ему слову then. Для избежания возможных ошибок и недоразумений можно
порекомендовать во всех подобных случаях четко выделять желаемую форму условного оператора
Паскаля путем взятия в операторные скобки.
Оператор выбора Паскаля
Оператор выбора Паскаля позволяет выбрать одно из нескольких возможных продолжений программы.
Параметром, по которому осуществляется выбор, служит ключ выбора – выражение любого порядкового типа.
Структура оператора выбора в Паскале такова:
Case <ключ_выбора> of
<список_выбора>
[else <оператор_иначе>] end
Здесь case, of, else, end – зарезервированные слова (случай, из, иначе, конец);

<ключ_выбора> - выражение порядкового типа;

<список_выбора> - одна или более конструкций вида:
o

o
<константа_выбора>: <оператор>;
<константа_выбора> - константа того же типа, что и выражение
<ключ_выбора>;
<операторы> - произвольные операторы Паскаля.
Оператор выбора Паскаля работает следующим образом. Вначале вычисляется значение выражения
<ключ_выбора>,
а
затем
в
последовательности
<список_выбора>
отыскивается
константа,
равная
вычисленному значению. Выполняется оператор, который следует за найденной константой, после чего
оператор выбора завершает работу. Если в списке выбора не будет найдена константа, соответствующая
вычисленному значению ключа выбора, управление передается операторам, стоящим за словом else. Часть
else <оператор_иначе> можно опустить, тогда при отсутствии в списке выбора нужной константы не будет
выполнено никаких действий, и оператор выбора просто завершит свою работу.
Например, составим программу, которая по номеру дня недели выводит на экран его название:
Пример программы с использованием Case of
Program dni_nedeli;
Var n: byte;
Begin
Readln(n);
Case n of
1: writeln(‘понедельник ’);
2: writeln(‘вторник ’);
3: writeln(‘среда ’);
4: writeln(‘четверг ’);
5: writeln(‘пятница ’);
6: writeln(‘суббота ’);
7: writeln(‘воскресенье’);
else writeln(‘дня недели с номером’, n,’нет’);
end;
end.
Следует помнить, что все константы из списка выбора должны быть различны.
Любому из операторов списка выбора может предшествовать не одна, а несколько констант выбора,
разделенных запятыми. Например, следующая программа при вводе одного из символов ‘ y’ или ‘ Y’ выведет
на экран «Да», а при вводе ‘ n’ или ‘ N’ – слово «Нет».
Пример программы с использованием Case of с несколькими переменными
Var ch: char;
Begin
Readln(ch);
Case ch of
N, n: writeln(‘Да ’);
Y, y: writeln(‘Нет ’);
End;
End.
Очевидно, что рассмотренные выше программы можно записать с помощью вложенных или последовательно
расположенных условных операторов, но в подобных задачах использование оператора выбора является
более простым. Основное отличие условного оператора от оператора выбора состоит в том, что в условном
операторе условия проверяются одно за другим, а в операторе выбора значение ключа выбора
непосредственно определяет одну из возможностей.
Разветвляющиеся алгоритмы. Оператор If
До сих пор Вы использовали линейные алгоритмы, т.е. алгоритмы, в которых все этапы решения
задачи выполняются строго последовательно. Сегодня Вы познакомитесь с разветвляющимися
алгоритмами.
Определение. Разветвляющимся называется такой алгоритм, в котором выбирается один из
нескольких возможных вариантов вычислительного процесса. Каждый подобный путь называется
ветвью алгоритма.
Признаком разветвляющегося алгоритма является наличие операций проверки условия.
Различают два вида условий - простые и составные.
Простым условием (отношением) называется выражение, составленное из двух арифметических
выражений или двух текстовых величин (иначе их еще называют операндами), связанных одним
из знаков:
< - меньше, чем...
> - больше, чем...
<= - меньше, чем... или равно
>= - больше, чем... или равно
<> - не равно
= - равно
Например, простыми отношениями являются следующие:
x-y>10; k<=sqr(c)+abs(a+b); 9<>11; ‘мама’<>‘папа’.
В приведенных примерах первые два отношения включают в себя переменные, поэтому об
истинности этих отношений можно судить только при подстановке конкретных значений:

если х=25, у=3, то отношение x-y>10 будет верным, т.к. 25-3>10

если х=5, у=30, то отношение x-y>10 будет неверным, т.к. 5-30<10
Проверьте истинность второго отношения при подстановке следующих значений:
1. k=5, a=1, b=-3, c=-8
2. k=65, a=10, b=-3, c=2
Определение. Выражение, о котором после подстановки в него значений переменных можно
сказать, истинно (верно) оно или ложно (неверно), называется булевым (логическим) выражением.
Примечание. Название “булевы” произошло от имени математика Джорджа Буля, разработавшего
в XIX веке булеву логику и алгебру логики.
Определение. Переменная, которая может принимать одно из двух значений: True (правда) или
False (ложь), называется булевой (логической) переменной. Например,
К:=True;
Flag:=False;
Second:=a+sqr(x)>t
Рассмотрим пример.
Задача. Вычислить значение модуля и квадратного корня из выражения (х-у).
Для решения этой задачи нужны уже знакомые нам стандартные функции нахождения квадратного
корня - Sqr и модуля - Abs. Поэтому Вы уже можете записать следующие операторы
присваивания:
Koren:=Sqrt(x-y);
Modul:=Abs(x-y)
В этом случае программа будет иметь вид:
Program Znachenia;
Uses
Crt;
Var
x, y : integer;
Koren, Modul : real;
Begin
ClrScr;
write ('Введите значения переменных х и у через пробел ');
readln (x, y);
Koren:=Sqrt(x-y);
Modul:=Abs(x-y);
write ('Значение квадратного корня из выражения (х-у) равно ', Koren);
write ('Значение модуля выражения (х-у) равно ', Modul);
readln;
End.
Казалось бы, задача решена. Но мы не учли области допустимых значений для нахождения
квадратного корня и модуля. Из курса математики Вы должны знать, что можно найти модуль
любого числа, а вот значение подкоренного выражения должно быть неотрицательно (больше или
равно нулю).
Поэтому наша программа имеет свою допустимую область исходных данных. Найдем эту область.
Для этого запишем неравенство х-у>=0, то есть х>=у. Значит, если пользователем нашей
программы будут введены такие числа, что при подстановке значение этого неравенства будет
равно True, то квадратный корень из выражения (х-у) извлечь можно. А если значение неравенства
будет равно False, то выполнение программы закончится аварийно.
Задание. Наберите текст программы. Протестируйте программу со следующими значениями
переменных и сделайте вывод.
1. х=23, у=5;
2. х=-5, у=15;
3. х=8, у=8.
Каждая программа, насколько это возможно, должна осуществлять контроль за допустимостью
величин, участвующих в вычислениях. Здесь мы сталкиваемся с разветвлением нашего алгоритма
в зависимости от условия. Для реализации таких условных переходов в языке Паскаль используют
операторы If и Case, а также оператор безусловного перехода Goto.
Рассмотрим оператор If.
Для нашей задачи нужно выполнить следующий алгоритм:
если х>=у,
то вычислить значение квадратного корня,
иначе выдать на экран сообщение об ошибочном введении данных.
Запишем его с помощью оператора If. Это будет выглядеть так.
if x>=y
then
Koren:=Sqr(x-y)
else
write ('Введены недопустимые значения переменных');
Теперь в зависимости от введенных значений переменных х и у, вычисление квадратного корня
может выполняться или не выполняться.
В общем случае полная форма конструкции условного оператора имеет вид:
if <логическое выражение>
then
<оператор 1>
else
<оператор 2>
Условный оператор работает по следующему алгоритму.
Сначала вычисляется значение логического выражения, расположенного за служебным словом IF.
Если его результат истина, выполняется <оператор 1>, расположенный после слова THEN, а
действия после ELSE пропускаются; если результат ложь, то, наоборот, действия после слова
THEN пропускаются, а после ELSE выполняется <оператор 2>.
Управляющая структура if может показаться негибкой, так как выполняемые действия могут быть
описаны только одним оператором. Иногда может потребоваться выполнение последовательности
операторов. В этом случае хотелось бы заключить всю последовательность в воображаемые
скобки. В Паскале предусмотрен этот случай.
Если в качестве оператора должна выполниться серия операторов, то они заключаются в
операторные скобки begin-end. Конструкция Begin ... End называется составным оператором.
if <логическое
then
begin
оператор
оператор
...
end
else
begin
оператор
оператор
...
end;
выражение>
1;
2;
1;
2;
Определение. Составной оператор - объединение нескольких операторов в одну группу. Группа
операторов внутри составного оператора заключается в операторные скобки (begin-end).
begin
оператор 1;
оператор 2;
end;
С учетом полученных знаний преобразуем нашу программу.
Program Znachenia;
Uses
Crt;
Var
x, y : integer;
Koren, Modul : real;
Begin
ClrScr;
write ('Введите значения переменных х и у через пробел ');
read (x, y);
if x>=y
then
begin
Koren:=Sqr(x-y);
Modul:=Abs(x-y);
write ('Значение квадратного корня из выражения (х-у) равно ',
Koren);
write ('Значение модуля выражения (х-у) равно ', Modul);
end
else
write ('Введены недопустимые значения переменных');
readln;
End.
Составным оператором является и такой оператор
begin
S:=0;
end.
Cимвол “;” в данном случае разделяет оператор присваивания S:=0 и пустой оператор.
Пустой оператор не влечет никаких действий и в записи программы никак не обозначается.
Например, составной оператор
begin
end.
включает лишь один пустой оператор.
Если Вы обратили внимание, программа на языке Паскаль всегда содержит один составной
оператор - раздел операторов программы.
Внимание! Перед служебным словом Else разделитель (точка с запятой) не ставится.
Отметим, что большинство операторов в программах на языке Паскаль заканчиваются точкой с
запятой, но после некоторых операторов точка с запятой не ставится. Сформулируем общие
правила употребления точки с запятой:
1. Каждое описание переменной и определение константы заканчиваются точкой с запятой.
2. Каждый оператор в теле программы завершается точкой с запятой, если сразу за ним не
следуют зарезервированные слова End, Else, Until.
3. После определенных зарезервированных слов, таких, как Then, Else, Var, Const, Begin,
никогда не ставится точка с запятой.
Рассмотрим еще один пример.
Задача. Вывести на экран большее из двух данных чисел.
Program Example1;
Var
x, y : integer; {вводимые числа}
Begin
writeln('Введите 2 числа '); {вводим два целых числа через пробел}
readln(x,y);
if x>y
then
writeln (x) {если х больше y, то выводим х}
else
writeln (y); {иначе выводим y}
readln;
End.
Можно также использовать и сокращенную (неполную) форму записи условного оператора. Эта
форма используется тогда, когда в случае невыполнения условия ничего делать не надо.
Неполная форма условного оператора имеет следующий вид.
if <логическое выражение>
then
<оператор>
Тогда если выражение, расположенное за служебным словом IF. в результате дает истину,
выполняются действия после слова THEN, в противном случае эти действия пропускаются.
Задача. Составить программу, которая, если введенное число отрицательное, меняет его на
противоположное.
Program Chisla;
Var
x : integer; {вводимое число}
Begin
writeln('Введите число '); {вводим целое число}
readln(x);
if x<0
then
x:=-x;
writeln (x);
readln;
End.
Операторы цикла в Pascal
В языке Turbo Pascal имеются три различных оператора, с помощью
которых можно запрограммировать повторяющиеся фрагменты программы.
Счетный оператор цикла или оператор цикла с
параметром
Оператор цикла с параметром используется в программе в случае,
когда заранее известно количество повторений в цикле.
Этот оператор имеет следующую структуру:
For <пар_цик> : = <нач_знач> to <кон_знач> do <оператор>;
Здесь: For, to, do - зарезервированные слова;
<пар_цик> - параметр цикла - переменная типа Integer (точнее
любого порядкового типа);
<нач_знач> - начальное значение - выражение того же типа;
<кон_знач> - конечное значение - выражение того же типа;
<оператор> - произвольный оператор Turbo Pascal.
При выполнении оператора For вначале вычисляется начальное
значение и осуществляется его присваивание параметру цикла. Затем
производится проверка условия <пар_цик> <= <кон_знач>, если условие
имеет значение ИСТИНА, то выполняется оператор следующий за
словом do, в противном случае оператор Forпрекращает свою работу.
Отметим два обстоятельства. Во-первых, условие, управляющее
работой оператораFor, проверяется перед выполнением оператора
<оператор>: если условие не выполняется в самом начале работы
циклического оператора, исполняемый оператор не будет выполнен ни
разу. Другое обстоятельство - шаг наращивания параметр строго постоянен
и равен +1. Существует другая форма оператора:
For <пар_цик> : = <нач_знач> downto <кон_знач> do <оператор>;
Замена зарезервированного слова to на downto означает, что шаг
наращивания параметра цикла равен -1.
В случае использования в цикле не одного, а нескольких операторов,
то принято заключать эти группы операторов в логические
скобки begin и end.
Пример 1.
Дана последовательность целых чисел, состоящая из 25 элементов.
Вычислить сумму элементов последовательности.
Program primer1;
Var i, a, s : integer;
Begin
x := 0;
For i := 1 to 25 do
begin
Read (a);
x := x + a;
end;
Write ('Сумма
элементов равна ', x);
End.
....
....
Пример 2.
Решим задание из примера 1 используя конструкцию оператора For, в
которой шаг наращивания будет равен -1.
Program primer2;
Var i, a, s : integer;
Begin
x := 0;
For i := 25 downto 1
do
begin
Read (a);
x := x + a;
end;
Write ('Сумма
элементов равна ', x);
End.
....
....
Операторы цикла
Операторы цикла используются для вычислений, повторяющихся многократно. В
Паскале три вида циклов: цикл с предусловием while, цикл с постусловием repeat и цикл
с параметром for. Каждый из них состоит из определенной последовательности
операторов.
Блок, ради выполнения которого и организуется цикл, называется телом цикла.
Остальные операторы служат для управления процессом повторения вычислений: это
начальные установки, проверка условия продолжения цикла и модификация параметра
цикла (рис. 1). Один проход цикла называется итерацией.
Рис. 1
Начальные установки служат для того, чтобы до входа в цикл задать значения
переменных, которые в нем используются.
Проверка условия продолжения цикла выполняется на каждой итерации либо до тела
цикла (тогда говорят о цикле с предусловием, рис. 1, а), либо после тела цикла (цикл с
постусловием, рис. 1, б). Разница между ними состоит в том, что тело цикла с
постусловием всегда выполняется хотя бы один раз, после чего проверяется, надо ли его
выполнять еще раз. Проверка необходимости выполнения цикла с предусловием
делается до тела цикла, поэтому возможно, что он не выполнится ни разу.
Параметром цикла называется переменная, которая используется при проверке условия
цикла и принудительно изменяется на каждой итерации, причем, как правило, на одну и
ту же величину. Если параметр цикла целочисленный, он называется счетчиком цикла.
Количество повторений такого цикла можно определить заранее. Параметр есть не у
всякого цикла.
Цикл завершается, если условие его продолжения не выполняется. Возможно
принудительное завершение как текущей итерации, так и цикла в целом. Для этого
служат операторы break, continue (подробнее>>) и goto.
Цикл с предусловием while
Формат оператора прост:
while выражение do оператор
Выражение должно быть логического типа. Например, это может быть операция
отношения или просто логическая переменная. Если результат вычисления выражения
равен true, выполняется расположенный после служебного слова do простой или
составной оператор. Эти действия повторяются до того момента, пока результатом
выражения не станет значение false. После окончания цикла управление передается на
следующий за ним оператор.
ВНИМАНИЕ Если в теле цикла необходимо выполнить более одного оператора,
необходимо заключить их в блок с помощьюbegin и end.
Пример 1
Пример. Программа печати таблицы значений функции
Рис. 2
для аргумента, изменяющегося в заданных пределах с заданным шагом.
Опишем алгоритм в словесной форме.
1. Ввести исходные данные.
2. Взять первое значение аргумента.
3. Определить, какому из интервалов оно принадлежит.
4. Вычислить значение функции по соответствующей формуле.
5. Вывести строку таблицы.
6. Перейти к следующему значению аргумента.
7. Если оно не превышает конечное значение, повторить шаги 3 - 6, иначе закончить.
Шаги 3 - 6 повторяются многократно, поэтому для их выполнения надо организовать цикл. Назовем
значение аргумента Xk, шаг изменения аргумента dX, параметр - t. Все величины вещественные. П
значений аргумента и соответствующих им значений функции.
program tabl_fun;
var Xn, Xk, dX, t, x, y : real;
begin
writeln('Введите Xn, Xk, dX, t');
readln(Xn, Xk, dX, t);
writeln(' --------------------------- ');
writeln('| X
| Y
|');
writeln(' --------------------------- ');
x := Xn;
{ Начальные установки }
while x <= Xk do begin
{ Заголовок цикла }
if x < 0 then y := t;
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.
Цикл с постусловием repeat
Тело цикла с постусловием заключено между служебными словами repeat и until,
поэтому заключать его в блок не требуется:
repeat
тело цикла
until выражение
В отличие от цикла while, этот цикл будет выполняться до тех пор, пока логическое
выражение после слова until ложно. Как только результат выражения станет истинным,
произойдет выход из цикла. Вычисление выражения выполняется в конце каждой
итерации цикла.
Этот вид цикла применяется в тех случаях, когда тело цикла необходимо обязательно
выполнить хотя бы один раз.
Пример 2
Программа, вычисляющая квадратный корень вещественного аргумента X с заданной точностью e
yn = 1/2(yn-1 + x/yn-1),
где yn-1 - предыдущее приближение к корню (в начале вычислений выбирается произвольно
прекращается, когда приближения станут отличаться друг от друга по абсолютной величине менее
program square_root;
var X, eps,
{ аргумент и точность }
Yp, Y : real;
{ предыдущее и последующее приближение }
begin
repeat
writeln('Введите аргумент и точность (больше нуля): ');
readln(X, eps);
until (X > 0) and (eps > 0);
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.
Цикл с параметром for
Этот оператор применяется, если требуется выполнить тело цикла заранее заданное
количество раз. Параметр порядкового типа на каждом проходе цикла автоматически
либо увеличивается, либо уменьшается на единицу:
for параметр := выражение_1 to выражение_2 do оператор
for параметр := выражение_2 downto выражение_1 do оператор
Выражения должны быть того же типа, что и переменная цикла, оператор - простым или
составным.
Пример 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. После нормального
завершения цикла значение счетчика не определено.
Рекомендации по использованию циклов
Часто встречающимися ошибками при программировании циклов являются
использование в теле цикла переменных, которым не были присвоены начальные
значения, а также неверная запись условия продолжения цикла. Нужно помнить и о том,
что в операторе while истинным должно являться условие повторения вычислений, а в
операторе repeat - условие их окончания.
Чтобы избежать ошибок, рекомендуется:

не забывать о том, что если в теле циклов while и for требуется выполнить более
одного оператора, нужно заключать их в блок;

убедиться, что всем переменным, встречающимся в правой части операторов
присваивания в теле цикла, до этого присвоены значения, а также возможно ли
выполнение других операторов;

проверить, изменяется ли в теле цикла хотя бы одна переменная, входящая в
условие продолжения цикла;

предусматривать аварийный выход из итеративного цикла по достижению
некоторого предельно допустимого количества
Download