Смекни!
smekni.com

Турбо Паскаль 7.0 (стр. 2 из 3)

Пример. Имеется логическое выражение not a and b xor с. Требуется вы­вести на печать значения логических переменных а, Ь, с, при которых дан­ное выражение истинно. Мы предлагаем перебор всех возможных зна­чений а, b, с с проверкой выполнения условия для каждого сочетания значений.

Program Sample;

Vara, b, с : boolean;

begin

for a := false to true do

for b := false to true do

for с := false to true do

if not a and b xor с then

begin

Write('a=',a);

Write('b=',b);

WriteLn('c=',c)

End

End.

В результате выполнения этой программы на экран будет выведено:

a =FALSE

b =FALSE

с =TRUE

a =FALSE

b =TRUE

с =FALSE

a =TRUE

b =FALSE

c =TRUE

a =TRUE

b =TRUE

с =TRUE

Программа состоит из одного сложного оператора for a := false to true do, в который вложены последовательно еще два оператора for и оператор if. Часть then последнего содержит сложный оператор, состоящий из трех простых операторов, охваченных программными скобками begin и end.

Циклы с логическими условиями

Введенный в предыдущей главе оператор цикла for обеспечивает выполне­ние цикла заданное количество раз, однако часто циклические действия за­канчиваются по условию, то есть выполняются до достижения определен­ного результата. В Паскале есть два таких оператора цикла, отличающиеся тем, что в одном из них условие проверяется в начале цикла (while...do), а в другом — в конце цикла (repeat...until).

Оператор while.. do

Оператор цикла while (пока, в то время как) имеет вид:

While<логическое выражение> do<тело цикла>;

Цикл While обеспечивает выполнение тела цикла, следующего за сло­вом do до тех пор, пока условие имеет значение true (истина). В качестве те­ла цикла может использоваться простой или сложный оператор. Условие проверяется перед началом каждого выполнения тела цикла, поэтому, если до первого выполнения цикла условие имеет значение false (ложь), опера­тор не выполняется ни одного раза (рис. 5.2).

Пример. Необходимо преобразовать значение угла в градусах к стандарт­ному диапазону ±180° путем исключения полных оборотов окружности ±360°. Эта процедура может быть выполнена с помощью оператора цикла

While abs(Angle) > 180 do

if Angle > 0 then Angle := Angle — 360

else Angle := Angle + 360;

Оператор while в начале цикла проверяет, превышает ли угол по абсо­лютному значению 180 градусов. Если это не справедливо, тело цикла не вы­полняется. Если угол больше допустимого, начинается выполнение цикла.

Цикл состоит из оператора if. Допустим, угол равен —700. Тогда условие An­gle > 0 в операторе if имеет значение false, при этом выполняется часть else оператора if, и угол получит значение —340. Снова происходит проверка условия выполнения цикла, и цикл выполняется второй раз, после чего угол равен 20. При третьей проверке условия выполнения цикла он заканчивает­ся, поскольку условие его выполнения Abs(20)>180 приняло значение false.

Оператор repeat... until...

Оператор цикла repeat... until... (повторять до тех пор, пока) имеет вид Repeat <тело цикла> until -<логическое выражение>;

Принципиальное отличие оператора repeat...until от оператора while...do в том, что проверка условия производится не перед началом выполнения оператора, а в его конце, когда решается вопрос, повторить ли еще раз дей­ствия. Поэтому тело этого цикла всегда выполняется по крайней мере один раз (рис. 5.3). Это важное отличие: приведенный для цикла while... do при­мер реализовать с оператором цикла repeat... until невозможно без дополни­тельных проверок и усложнений.

Второе отличие от оператора while...do — в логике завершения цикла. Цикл оператора repeat...until выполняется до тех пор, пока не станет истинным логическое выражение, следующее за словом until. Таким образом, использование логического выражения здесь имеет противоположный опе­ратору while...do смысл. Здесь при истинности логического выражения (условия) цикл прекращается, а у оператора while...do при истинности ло­гического выражения цикл продолжается.

Третье отличие в том, что оператор repeat...until имеет две части:

начальную и завершающую, которые охватывают группу операторов, со­ставляющих тело цикла. Оператор while...do не имеет завершающей части и требует для организации тела цикла из нескольких операторов програм­мных скобок begin-end. Для оператора repeat...until таких скобок не требу­ется — их роль выполняют составные части оператора.

Пример. Найти методом подбора целочисленное решение Диофантова уравнения 5x-3y=1. В качестве первой пробы берутся единичные значения. Далее, если 5x-3y>1, то у увеличивается на 1, если 5x-3y<1, то на 1 увеличивается х.

Program Diophant;

var х, у: byte;

begin

x:=1;y:=1;

repeat

if(5*x-3*y)>1theny:=y+1;

if (5 * x - 3 * у) < 1 then х := х + 1 until(5*x-3*y)=1;

writeln('x= ',x, 'y=',y) end.

В результате на экране получим х=2у=3.

Пример. С помощью цикла repeat...until можно организовать процедуру ввода данных с защитой программы от завершения при ошибочном наборе. Если тип данных не соответствует инициализируемой при стандартном вводе переменной (например, требуется ввести целое число, а набрано дробное), то возникает ошибка в выполнении программы, и мы должны снова запускать программу, и, естественно, повторить набор. Чтобы защи­титься от последствий таких ошибок, можно использовать собственную процедуру ввода. Такая процедура должна отключить автоматическую про­верку правильности ввода и проводить ее самостоятельно, причем при ошибке требовать повторного набора. Отключение проверки правильности ввода производится директивой компилятора {$!-} (Input/Output checking в окне настройки опций компилятора). После каждого действия по вводу-выводу специальная функция lOResult возвращает целое значение, соответ­ствующее ошибкам ввода-вывода. Правильной работе ввода-вывода соответствует нулевое значение, возвращаемое этой функцией. Надежный ввод целого числа i выполняет фрагмент программы:

{$!-} {отключение проверки ввода-вывода}repeat

Write ('Введите i = '); {вывод на экран предложения для ввода}

ReadLn (i) {ввод целого числа}

until lOResult = 0; {lOResult — функция, равная 0, если нет ошибки} {$!+} {восстановление проверки ввода-вывода}

По крайней мере один раз вводится число; если при вводе была сделана ошибка, условие lOResult = 0 имеет значение false, и ввод будет повторяться до тех пор, пока он не будет сделан правильно.

Операторы Break и Continue

В последних версиях языка Borland Pascal введены два новых оператора, Break и Continue, применяемые внутри циклов. Они расширяют возможности использова­ния циклов и улучшают структуру программ. В процессе выполнения тела цикла до его завершения могут возникнуть дополнительные условия, требующие завер­шения цикла. В этом случае цикл может быть прекращен оператором Break.

Пример. Игра с ЭВМ в кости. Условия игры. Компьютер выдает себе или Вам случайные числа от 1 до 6. Задача — набрать максимальную сум­му очков. Набравший больше 21 очка проигрывает, в любой момент один из игроков может отказаться от набора очков (спасовать).

Program Bones;

Const MaxSum = 1; {максимальное число очков}

var SumYour, {сумма очков игрока}

SumComp,{сумма очков компьютера}

count: byte; {очередные выпавшие очки}

reply: string;{ответ на запрос ЭВМ}

begin

SumYour := 0;

SumComp:=12;{начальное количество очков}

Randomize; {установка датчика случайных чисел}

repeat {начало общего цикла, организующего игру}

write ('Бросить кость для Вас? (у/n)');

repeat {Начало цикла для ввода корректного ответа} readln(reply) {ввод ответа}

{выход из цикла — при корректном ответе}

until (reply = 'у') or (reply = 'Y') or (reply ='n') or (reply = 'N');

{метание кости для игрока при положительном ответе}

if (reply = 'у') or (reply = 'Y') then {если ответ »да»}

begin Count := Random(6) + 1; {число очков игрока}

{Random(6) дает случайные числа от 0 до 5}

WriteLn( вам выпало ', count,' очков.'); {вывод выпавшего количества очков} SumYour := SumYour + count; {подсчет суммы очков игрока}

Writeln('y Вас всего ', SumYour,' очков.'); {вывод суммы очков}

if SumYour >= MaxSum then Вгеаk{прекращение игры при переборе} end;

{метание кости для компьютера — он играет,

если сумма очков меньше 18}

if SumComp < 18 then {если компьютер продолжает игру}

begin Count := Random(6) + 1; {число очков компьютера} WriteLn('мнe выпало ', count,' очков.'); {вывод количества очков} SumComp := SumComp + count; {подсчет суммы очков компьютера} Writeln('y меня всего ', SumComp,' очков.'); {вывод суммы очков}

if SumYour >= MaxSum then Break {прекращение игры при переборе} end

else begin {если компьютер пасует}

write(‘ пас. Будете продолжать? (у/п)’); {запрос о продолжении игры}

repeat

read(reply) until (reply = 'у') or (reply = 'Y') or (reply = 'n') or (reply = 'N');

if (reply = 'n') or (reply = 'N') then Break {прекращение игры

по взаимному согласию}

end

until false;{замыкание цикла метания костей} {подведение итогов}

if SumYour > MaxSum then writeln('Bы проиграли!')

{перебор игрока}

else if SumComp > MaxSum then writeln(‘Я проиграл!')

{перебор у компьютера}

else if SumYour < SumComp then writeln('Я выиграл!')

{сравнение очков}

else if SumYour = SumComp then writeln ('Ничья!')

{равенство очков}

else writeln('Вы выиграли!');

ReadLn

end.

Программа разбита на две основные части: метание костей и подведе­ние итогов.

Первая часть реализует бесконечный цикл метания костей, ограничен­ный оператором repeat ... until false. Выбор оператора repeat мотивирован тем, что должен быть сделан, по крайней мере, один ход игры. Цикл может быть прерван оператором Break при переборе очков любым из игроков и при отказе обоих партнеров от продолжения игры. Объединение трех усло­вий в одно и использование его как завершающего условия цикла re­peat... until усложнит алгоритм, а применение для прекращения игры опера­тора Break алгоритм упрощает.