Как в паскале начать цикл заново

Как в паскале начать цикл заново thumbnail

Оператор безусловного перехода goto

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

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

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

Оператор goto осуществляет переход к оператору, помеченному специальной меткой, которая отделяется от самого оператора двоеточием. В качестве метки может быть использовано любое целое число без знака, содержащее более четырех цифр, или любое имя. Чтобы можно было использовать метку, она должна быть в обязательном порядке объявлена в разделе меток в описательной части программы. Этот раздел начинается служебным словом label, после которого через запятую перечисляются метки.

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

goto метка;

label goback;
var num: real;
 
begin
goback:
write (‘Введите число: ‘);
readln (num);
 
if num < 0 then
goto goback;
 
num := sqrt (num);
 
write (‘Квадратный корень: ‘, num:5:2);
 
readln
end.

Операторы break и continue

Бывает, что цель выполнения цикла достигается раньше, чем он будет прекращен по условию выхода. Так, например, в программе для определения простоты числа цикл будет выполняться n div 2-1 раз, хотя то, что число не является простым, может быть обнаружено на первых шагах цикла. Чтобы уменьшить количество шагов цикла, можно воспользоваться оператором goto, либо сформировать сложное условие выполнения (прекращения) цикла.

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

Операторы break и continue выполняются в любом из видов циклов (repeat, while, for) и действительны только для внутреннего цикла. Например, если нужно обеспечить принудительный выход из двойного цикла, оператор break должен быть расположен как во внутреннем, так и во внешнем цикле. Операторы break и continue по сути являются видоизмененными операторами goto с известной точкой, в которую осуществляется переход.

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

var
num: real;
i: integer;
 
begin
for i := 1 to 5 do begin
write (‘Введите число: ‘);
readln (num);
if num = 0 then
break;
writeln (num)
end;
 
readln
end.

В примере запрашиваются пять чисел и суммируются только положительные из них.

var
num, sum: real;
i: integer;
 
begin
sum := 0;
 
for i := 1 to 5 do begin
write (‘Введите число: ‘);
readln (num);
if num < 0 then
continue;
sum := sum + num
end;
 
write (sum:10:2);
 
readln
end.

Принудительное прекращение программы

Обычно программа завершает свою работу по достижении последнего оператора (т.е. при выходе на оператор end с точкой). Если возникает необходимость прекратить выполнение программы где-либо внутри нее, то можно воспользоваться процедурой halt, которая вызывается как отдельный оператор. Эту процедуру можно вызвать, задав в круглых скобках параметр в виде целого неотрицательного числа от 0 до 255. Это значение возвращается в операционную систему в виде кода ошибки (ERRORLEVEL) и может быть проанализирована DOS в случае запуска данной программы из командного файла. Отсутствие параметра в процедуре halt соответствует значению параметра 0 (нормальное завершение программы).

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

Источник

Добрый день! ☺ Если вы используете в своей программе циклы, то время от времени вам понадобится или досрочно выйти из цикла, или пропустить несколько последних операторов в цикле. В таком случае без операторов break и continue вам не обойтись. Плюс к этому, иногда есть необходимость досрочно выйти из процедуры или функции, или вообще завершить программу – тогда используется оператор exit. Но нужно ещё запомнить, что операторы BREAK и CONTINUE применяются только внутри циклов.

Сначала дадим определение оператору break, а continue и exit ниже.

✎ break — это оператор, предназначенный для досрочного выхода из цикла.

По английски break означает “перерыв”, “прервать”, и это слово хорошо знакомо боксерам. При его использовании программа немедленно выходит из цикла, продолжая выполнять последующие за циклом операторы. Так, если вы выполняете в цикле некоторую работу (вычисления), но при определенных условиях все дальнейшие вычисления бессмысленны, то смело задействуйте оператор break – он мгновенно выведет вас из цикла. Это как обеденный перерыв или дешевый хостинг для сайта, от которых трудно отказаться. Так и оператор break или exit, МГНОВЕННО завершающие работу в нужный момент. Но следует помнить, что оператор break прерывает только тот цикл, в котором он вызван, и это надо учитывать при использовании вложенных циклов. Приведем примеры.

Напечатаем все символы английского алфавита от “a” до “m”.

Причем, будем перебирать все буквы подряд, а после попадания буквы “m” выйдем из цикла.

Код Pascal

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
var
ch: char; { <– переменная ch символьного типа }

begin
{ Перебираем все символы английского алфавита }
for ch := ‘a’ to ‘z’ do
begin
write(ch:2); //выводим символ
{ Когда встречаем символ ‘m’, выходим из цикла: }
if ch = ‘m’ then break
end;
readln
end.

В строке 8 кода выводим букву ch (параметр цикла), а ниже проверяем равенство её букве “m”. Если равенство выполняется, то выходим из цикла. Поскольку после цикла в коде программы есть только оператор readln – ожидание нажатия клавиши Enter, – то после её нажатия программа на этом завершается.

“УГАДАЙКА ДЕЛИТЕЛЬ”. Программа “задумывает” число от 1000 до 1999, а вам нужно угадать делитель этого числа, то есть целое число, делящее нацело “задуманное” машиной.

Сначала в строках 5, 6 задаем границы a и b интервала случайных чисел (вместо указанных 1000 и 1999 можете взять свои параметры). В 9 строке находим случайное число n с диапазона [1000, 1999], а в 11 строке после запроса вводим делитель d по своему желанию. Если этот делитель не равен 0 и делит нацело число n (строчка 12 кода), то выводим соответствующее сообщение; в противном случае выходим из цикла (строка 14) и сообщаем о неудаче (строка 17).

Код Pascal

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
var
a, b, n, d: integer;

begin
a := 1000;
b := 1999;
randomize;
repeat
n := a + random(b – a + 1); { число 1000..1999 }
write(‘Введите целое число –> ‘);
readln(d);
if (d <> 0) and (n mod d = 0) then
writeln(‘ ‘, n, ‘ делится на ‘, d)
else break
until false;
writeln;
writeln(n, ‘ НЕ ДЕЛИТСЯ НА ‘, d, ‘!’);
readln
end.

Одно из моих испытаний выглядит таким образом:

Введите целое число –> 1
1590 делится на 1
Введите целое число –> 2
1616 делится на 2
Введите целое число –> 3
1080 делится на 3
Введите целое число –> 5

1584 НЕ ДЕЛИТСЯ НА 5!

Задача. Выводить случайные целые числа с диапазона 0..99 до тех пор, пока не встретится число, большее 90. И так 10 раз с новой строчки.

Для генерации случайных чисел задействуем датчик псевдослучайных чисел (5 строка), а потом процедуру random(100) для вывода целых случайных чисел с диапазона 0..99 (строка 10 кода). Поскольку вывод чисел до первого большего 90 надо повторять 10 раз, то внешний цикл берем с параметром от 1 до 10 (строка 6). Тогда внутренний цикл мы не можем брать с параметром, поскольку не известно заранее количество повторений. Здесь воспользуемся циклом с предусловием while (условие) do, причем само условие вхождения в цикл будет всегда истинно, то есть True (строка 8). А выйдем из цикла с помощью оператора break при первом же попавшемся числе, большим 90 (строка 12). После выхода из цикла переходим на следующую строку оператором writeln (15 строка кода), и повторим все сначала в общем количестве 10 раз.

Код Pascal

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
var
i, n: integer;

begin
randomize;
for i := 1 to 10 do { <– повторяем 10 раз }
begin
while true do
begin
n := random(100); { <– случайное число 0..99 }
write(n:3); { <– выводим число }
if n > 90 then break { <– если число
большее 90 – выходим из цикла }
end;
writeln { <– переходим на следующую строку }
end;
readln
end.

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

70 69 91
94
23 62 72 94
75 41 29 5 60 34 87 22 71 4 86 20 39 94
49 47 92
82 9 44 43 23 43 16 91
97
25 55 10 72 94
42 95
30 52 18 18 51 11 25 20 0 96

Другие примеры использования оператора досрочного выхода из цикла break посмотрите в задачах Array43 (второй вариант решения) и задание Array44 там же; в другом разделе Proc28 и Proc31 решебника Абрамяна. Возможно, где-то ещё найдете, я уже не помню. ☻

Далее рассмотрим оператор continue.

✎ continue — этот оператор предназначенный для завершения текущей итерации цикла и переходу к концу тела цикла.

На английском continue означает “продолжать”. Исходя из определения, если в цикле прогаммы встречается оператор continue, то все последующие за ним операторы пропускаются, осуществляя переход к концу цикла. Далее все зависит от вида цикла – с параметром или с условием. Если цикл с параметром (цикл for) или цикл с предусловием (while), то сразу переходим в начало и проверяем условие входа в цикл; если цикл с послеусловием (repeat), то прорверяется условие выхода из цикла. Но продемонстрируем сказанное на примерах.

По аналогии с предыдущей задачей, будем выводить случайные числа.

Задача. Из 10 случаных чисел с диапазона [-100, 99] вывести только положительные.

Каждый раз, как мы получим отрицательное число (строки кода 8, 9), оператор continue отправит нас в самый конец цикла, пропуская вывод этого числа в строке 10.

Код Pascal

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
var
i, n: integer;

begin
randomize;
for i := 1 to 10 do { <– повторяем 10 раз }
begin
n := -100 + random(200); { диапазон чисел – [-100, 99] }
if n < 0 then continue;
write(‘ ‘, n) { <– выводим число }
end;
readln
end.

Можете запустить программу несколько раз и понаблюдать: ни в одном из случаев вы не увидите отрицательного числа – это нам гарантирует оператор continue. Вы получите приблизительно такой результат:

75 96 30 24 93 80 92

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

Задача. Для 10 случаных чисел с интервала (-10, 10) вычислить их квадратные корни.

Код Pascal

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
var
i: integer;
a: real;

begin
i := 0;
writeln(‘| число | корень |’);
writeln(‘ —————–‘);
while i < 10 do begin
inc(i);
a := -10 + 20 * random;
if a < 0 then begin
writeln(‘|’, a:5:3,’ | ‘, ‘|’:9);
continue
end;
writeln(‘| ‘, a:5:3, ‘ | ‘, sqrt(a):6:5, ‘ |’)
end;
readln
end.

Один из моих результатов выглядит следующим образом:

| число | корень |
—————–
| 0.613 | 0.78319 |
|-9.488 | |
|-9.477 | |
| 0.271 | 0.52054 |
|-1.345 | |
| 7.410 | 2.72210 |
| 6.992 | 2.64423 |
|-4.853 | |
| 3.491 | 1.86841 |
| 0.091 | 0.30220 |

Как видно, для отрицательных чисел корни квадратные отсутствуют – это нам гарантирует условный оператор в строке 12, где выводим только значение a без корня, а потом continue (продолжаем далее).

И, наконец, переходим к оператору exit.

✎ exit — это оператор, предназначенный для досрочного выхода из процедуры или функции и возвращения в основную программу. Вызов оператора exit в основной программе приводит к её завершению.

Пример использования EXIT. Вычислить квадратный корень из введенного пользователем числа.

Поскольку в области действительных чисел из отрицательного числа квадратный корень извлечь не возможно, то если введенное нами число (строка 6) окажется отрицательным, то выходим из программы с сообщением “ошибка!” (строки 7-11). Причем, сообщение нужно писать до вызова оператора exit, иначе после выхода из программы ни один оператор не выполнится.

Код Pascal

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
var
x: real;

begin
write(‘Введите число –> ‘);
readln(x);
if x < 0 then
begin
writeln(‘ERROR!’);
exit
end;
writeln(‘Корень квадратный = ‘, sqrt(x):0:5);
readln
end.

Как видим, оператор exit можно использовать и вне цикла – и в этом его отличие от операторов break и continue, которые, как отмечалось, вызываются только внутри цикла.

Вызов EXIT в цикле. Вычислять квадратные корни введенных чисел до первого отрицательного числа.

Цикл используем с предусловием, где условие true – всегда истинно. Это значит, что такой цикл будет продолжаться “вечно”, если мы не выйдем из него оператором break или exit. ☺ Мы выберем второй. Это предыдущая программа, только обрамленная циклом while. При первом же отрицательном числе мы выходим из условия if, а заодно и цикла.

Код Pascal

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
var
x: real;

begin
while true do
begin
write(‘Введите число –> ‘);
readln(x);
if x < 0 then
begin
writeln(‘ERROR!’);
exit
end;
writeln(‘ корень квадратный = ‘, sqrt(x):0:5);
writeln
end
end.

Вот, что примерно должно у вас получится:

Введите число –> 23
корень квадратный = 4.79583

Введите число –> 5
корень квадратный = 2.23607

Введите число –> 12
корень квадратный = 3.46410

Введите число –> 100
корень квадратный = 10.00000

Введите число –> 333
корень квадратный = 18.24829

Введите число –> -894
ERROR!

Теперь приведем пример, как делается вызов EXIT в подпрограмме (процедуре или функции). В данном случае воспользуемся функцией.

“СДЕЛАЙ ПОСЛЕДНИЙ ХОД и проиграй ☻”. Компьютер “загадывает” число, потом делается ход – указывается произвольное число и вычисляется общая сумма с прежними слагаемыми. Проигрывает тот, на чьем ходу сумма окажется больше “задуманного” числа. Палаллельно подсчитывается процентное соотношение суммы “правильно” введенных чисел (которые не привели к проигрышу).
Какое число “загадал” компьютер – не известно. Известны только границы “задуманного” числа и границы “вводимых” компьютером чисел, поэтому и пользователь ДОЛЖЕН вводить свои числа в таких же границах, иначе – тоже проигрыш. Первым делает ход пользователь.

Код Pascal

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
const
{ ДИАПАЗОН ЗАДУМАННОГО КОМПЬЮТЕРОМ ЧИСЛА: }
D1 = 0; { <– левая граница }
D2 = 50; { <– правая граница }
{ ГРАНИЦЫ ВВОДИМЫХ ЧИСЕЛ: }
a = 0; { <- минимальная граница }
b = 10; { <- максимальная граница }

var
counter: integer;
Q, percent: real;

procedure summ(memory: real);
var
y: real;
begin
inc(counter); { <– увеличиваем ход на 1 }
if odd(counter) then
begin
write(‘Введите число –> ‘);
readln(y);
{ Если число выходит за границы, то выходим: }
if (y < a) or (y > b) then begin
writeln;
write(‘НАРУШЕНИЕ ПРАВИЛ: число за границами диапазона [‘, a, ‘; ‘, b, ‘]!’);
exit
end
end
else begin
write(‘Ход компьютера –> ‘);
y := a + (b – a) * random; { <- число в диапазоне [a; b) }
sleep(1000);
writeln(y:0:3)
end;
Q := Q + y; { <– увеличиваем общую сумму }
if (Q > memory) then exit
else begin
percent := (Q / memory) * 100; { <- приближенность к загаданой сумме (в процентах) }
summ(memory) { <== снова вызываем процедуру }
end
end;

var
memory: integer;

begin
randomize;
Q := 0; { начальная общая сумма }
counter := 0; { начальное количество ходов }
memory := D1 + random(D2 – D1 + 1); { “задуманное” число }
writeln(‘Компьютер уже “задумал” число от ‘, D1, ‘ до ‘, D2, ‘.’);
writeln(‘Позволено вводить числа с диапазона [‘, a, ‘; ‘, b, ‘]’);
writeln;
summ(memory); { <== ВЫЗОВ ПРОЦЕДУРЫ }
writeln;
if odd(counter) then writeln(‘ВЫ ПРОИГРАЛИ!’)
else writeln(‘КОМПЬЮТЕР ПРОИГРАЛ.’);
writeln;
writeln(‘ Было задумано число ‘, memory);
writeln(‘ Последняя сумма: ‘, Q:0:3);
writeln(‘ Приближенность к выиграшу: ‘, percent:0:3, ‘%’);
readln
end.

Вот, как примерно выглядит “проигрыш” компьютера при испытаниях:

Компьютер уже “задумал” число от 0 до 50.
Позволено вводить числа с диапазона [0; 10]

Введите число –> 1
Ход компьютера –> 2.641
Введите число –> 2
Ход компьютера –> 1.221
Введите число –> 4
Ход компьютера –> 4.698
Введите число –> 2.901
Ход компьютера –> 7.407

КОМПЬЮТЕР ПРОИГРАЛ.

Было задумано число 23
Последняя сумма: 25.867
Приближенность к выиграшу: 80.262%

Здесь есть такие ключевые параметры: memory – число, “задуманное” компьютером; counter – общее количество сделанных ходов; Q – общая сумма введенных чисел (компьютером и человеком); percent – процентное отношение набранной суммы к задуманной сумме memory. А еще есть диапазоны: задуманное число – от D1 до D2, число для ввода – от a до b (строки 1 – 7 в разделе описания констант).

Но эта программа не имеет стратегии – вы просто вводите числа, которые суммируются. Если набирается сумма больше “задуманного” memory, то программа завершается. Чтобы выиграть, вы должны вводить числа поменьше. А поскольку компьютер ничем не ограничен, то рано или поздно проиграет. Ведь пользователь просто каждый раз может вводить 0: тогда на его ходе сумма увеличиваться не будет, а на ходе компьютера – да, а это уже нечестно.

Но можно доработать программу уже со стратегией таким образом: если вы начинаете вводить маленькие числа, то компьютер это “замечает” и тоже начинает генерировать слагаемые поменьше – в результате общая сумма будет медленно расти. А при таком раскладе выиграть уже сложнее. Можно указать и другие правила или ограничения, фантазия не ограничена.

На этом, наверное, все. Пишите в комментариях, что можно ещё добавить. Пока! ☺

Источник

При решении задач может возникнуть необходимость повторить одни и те же действия несколько или множество раз. В программировании блоки кода, которые требуется повторять не единожды, оборачиваются в специальные конструкции – циклы. У циклов выделяют заголовок и тело. Заголовок определяет, до каких пор или сколько раз тело цикла будет выполняться. Тело содержит выражения, которые выполняются, если в заголовке цикла выражение вернуло логическую истину (True, не ноль). После того как достигнута последняя инструкция тела, поток выполнения снова возвращается к заголовку цикла. Снова проверяется условие выполнения цикла. В зависимости от результата тело цикла либо повторяется, либо поток выполнения переходит к следующему выражению после всего цикла.

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

Блок схемы циклов

Цикл for

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

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

Цикл for существует в двух формах:

for счетчик:=значение to конечное_значение do
тело_цикла;
for счетчик:=значение downto конечное_значение do
тело_цикла;

Счетчик – это переменная любого из перечисляемых типов (целого, булевого, символьного, диапазонного, перечисления). Начальные и конечные значения могут быть представлены не только значениями, но и выражениями, возвращающими совместимые с типом счетчика типы данных. Если между начальным и конечным выражением указано служебное слово to, то на каждом шаге цикла значение параметра будет увеличиваться на единицу. Если же указано downto, то значение параметра будет уменьшаться на единицу.

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

var
i, n: integer;
 
begin
write (‘Количество знаков: ‘);
readln (n);
 
for i := 1 to n do
write (‘(*) ‘);
 
readln
end.

Цикл while

Цикл while является циклом с предусловием. В заголовке цикла находится логическое выражение. Если оно возвращает true, то тело цикла выполняется, если false – то нет.

Когда тело цикла было выполнено, то ход программы снова возвращается в заголовок цикла. Условие выполнения тела снова проверяется (находится значение логического выражения). Тело цикла выполнится столько раз, сколько раз логическое выражение вернет true. Поэтому очень важно в теле цикла предусмотреть изменение переменной, фигурирующей в заголовке цикла, таким образом, чтобы когда-нибудь обязательно наступала ситуация false. Иначе произойдет так называемое зацикливание, одна из самых неприятных ошибок в программировании.

var
i, n: integer;
 
begin
write (‘Количество знаков: ‘);
readln (n);
 
i := 1;
while i <= n do begin
write (‘(*) ‘);
i := i + 1
end;
 
readln
end.

Цикл repeat

Цикл while может не выполниться ни разу, если логическое выражение в заголовке сразу вернуло false. Однако такая ситуация не всегда может быть приемлемой. Бывает, что тело цикла должно выполниться хотя бы один раз, не зависимо оттого, что вернет логическое выражение. В таком случае используется цикл repeat – цикл с постусловием.

В цикле repeat логическое выражение стоит после тела цикла. Причем, в отличие от цикла while, здесь всё наоборот: в случае true происходит выход из цикла, в случае false – его повторение.

var
i, n: integer;
 
begin
write (‘Количество знаков: ‘);
readln (n);
 
i := 1;
repeat
write (‘(*) ‘);
i := i + 1
until i > n;
 
readln
end.

В примере, даже если n будет равно 0, одна звездочка все равно будет напечатана.

Источник

Читайте также:  Цикл крана в сутки