Rambler's Top100


Сегодня мы поговорим о циклах. Что это такое? Давайте представим, что вам необходимо вывести на экран слово ПРИВЕТ! двадцать раз. Писать: writeLn ('ПРИВЕТ'); 20 раз !!! А если нужно сто раз? А если заранее неизвестное число раз?? Как быть? Вот тут и нужны циклы.
Цикл - кусок кода, который повторяется определённое число раз (бесконость - это тоже определённое число раз!).

Цикл FOR

Этот цикл наиболее часто используется в программах ввиду его чрезвычайной удобности. Итак знакомтесь, цикл for!
Давайте рассмотрим его использованние на примере с выводом слова привет на экран. Да давайте оговоримся, что будем опускать стандартные куски программы типа Program, var, begin, end. И ещё одно соглашение об именах переменных: обычно именами i и j дают переменным целого типа и их объявление мы тоже будем опускать. Итак пример:

for i := 1 to 20 do
     writeLn ('Привет!');

Цикл записывается так for переменная_цикла := начальное_значение to конечное_значение do операторы; В нашем примере мы взяли в качестве переменной цикла взята переменная i, начальное значение 1, конечное - 20. Что это значит? А это значит, что цикл будет выполняться для i = 1, 2, 3, 4, 5 ... 19, 20. Т.е. 20 раз. Каждый раз мы прибавляем к i еденицу. При этом начальное и конечное значение переменной цикла может задаваться численным выражением (например for i := 1 to 3*65 do ....) или выражением с переменной (например for i := X + Y to X * Y / Z + 45 *j do ....). При этом эти значения вычисляются компилятором один раз перед выполнением цикла. Например, результат такой программы:

Program   Test;

var  
   i : integer;
   x : integer;
begin  
     x := 10;
     for i := 0 to х do  
     begin  
       writeLn (i, ' ', x);
       x := x + 2
     end  
end.
Будет таким :
0 10
1 12
2 14
3 16
4 18
5 20
6 22
7 24
8 26
9 28
10 30

Как видите предел i не поменялся, хотя х мы меняем! Использую цикл for нужно соблюдать следующее правило: не нужно менять переменную цикла (т.е. ту переменную, по которой идёт цикл, у нас это была i) внутри него.
Есть ещё один альтернативный вариант цикла for, который используется, когда считать нужно не "снизу вверх" а "сверху вниз". Например мы хотим изменять i не от 1 до 20, а наоборот от 20 до 1. Тогда наш цикл примет вид:

for i := 20 downto 1 do
     writeLn ('Привет!');
Теперь i = 20, 19, ... 2, 1. А так всё аннологично. Основное неудобство состоит в том, что мы не можем задавать закон изменения переменной цикла. Однако и это не так страшно, как кажется на первый взгляд.

Цикл WHILE

Цикл номер два: while! Этот цикл называется циклом с предусловием. Записывается он так:
while условие do оператор;
Такой цикл выполняется пока условие истинно. И прекращается в противном случае. Например такой цикл:
while 1 do
	writeLn ('Привет!');
Приведёт к "зависанию" компьютера, т.к. выражение 1 всегда истинно (не могут же быть числа ложными). выйдти из этого цикла можно нажатием клавиши Ctrl+Break (Ctrl+C) - стандартный выход из ДОС программ. Проверка истистинности условия проводится как и в операторе if.
Давайте покажем, как оператором While можно заменить for:
i := 1;
x := 10;
while i  <=  x do
begin
   writeLn (i, ' ', x);
   x := x + 1;
   i := i + 1
end;

Попробуйте этот код... ну как эффект не тот? :) Давайте разберёмся в чём дело. А вся проблемма в том, что условие (максимальное значение) для цикла for считается зарание один раз заранее! А у нас оно всё время меняется. Ок. Теперь посмотрите результат программы: она останавливается при i = 32 757. Давайте посмотрим ещё один вариант:

i := 1;
x := 10;
while i  <>  x do
begin
   writeLn (i, ' ', x);
   x := x + 1;
   i := i + 1
end;

Запустите и подождите немного.... СТОП! А откуда там отрицательные числа?? Ведь мы прибавляем каждый раз по 1 и 1, т.е. i и х растут ??? Давайте разберёмся по подробнее. Что из себя представляет числовая прямая? Это окружность максимального радиуса, т.е. радиуса бесконечность. Такая окружность вырождается в прямую. Однако для целых чисел (типа integer) эта "бесконечность" известна - 32767 (помните выпуск Типы данных?). Счечик i можно представить, как точку, которая движется по этой окружности. Когда i доходит до максимума, то она становится отрицательной, т.е. -32767!! А помните предыдущий пример, где всё останавливалось при x = 32 767. Почему так вышло? Прибавляя к х = 32767 один что мы получаем: x + 1 = -32767 !!!! А условие цикла у нас стоит i <= x т.е. когда х = 32 767 i = 32 757, далее х + 1 = -32 767 i + 1 = 32 758 т.е. условие i <= x не выполняется! И поэтому мы выходим из цикла!
Поэтому аккуратнее с максимальным значение integer, оно не такое большое, как может показаться! Теперь напишем нормальный вариант цикла for через цикл while:

i := 1;
x := 10;
Temp := x;
while i  <= Temp do
begin
   writeLn (i, ' ', x);
   x := x + 1;
   i := i + 1
end;

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

Ну и напоследок...

Ну вот мы подошли к последнему циклу. Он называется цикл с постусловием, цикл: repeat-until ! Этот цикл в общем и целом анологичен while, но есть два отличия. Вот как он записывается: repeat оператор until условие;

Итак его отличия от while:
  1. самое важное: проверка условия совершается после выполнения оператора. Таким образом этот цикл обязательно выполнится хотя бы один раз. В то время как while, может и не выполняться ни разу.
  2. не самое важное, но очень нужно запомнить, что критерием прекращения цикла является тот случай, когда условие истинно, а если оно ложно, то цикл продолжится! В то время как в while абсолютно противоположная ситуация.
Давайте же рассмотрим какой-нить пример:
i := 10;
repeat
     writeLn (i);
	 i := i - 1
until i = 0;

Этот цикл выполняется пока i не равно нулю. Т.е. для значений i = 10, 9, 8 ..... 2, 1. Обратите внимание, что мы не используем операторы begin-end т.к. этот цикл доспукает использовать в своём теле сколько хочешь операторов в отличие от while и for. Вот написал и вспомнил о том, что не сказал, что такое тело цикла :( Вот дырявая башка! Итак тело цикла - это та последовательность операторов, которая выполниется. Т.е. например все операторы между repeat и until - это и есть тело цикла.

Программа

Итак сегодня мы продолжим изучать Отладчик и напишем ещё одну программу.
Наша новая программа - факториал! Что такое факториал? По определению факториал числа n (обозначается n! ) n! = 1 * 2 * 3 *....* (n-1) * n - т.е. перемножение чисел от 1 до n. Итак вот программа:

Program Factorial;

uses CRT;

var
   n, i : integer;
   Result : longint;
begin
     ClrScr;

     Write ('Какое значение? ');
     ReadLn (n);

     Result := n;

     for i := 0 to n do
     begin
         Result := Result * i
     end;	

     writeLn ('Результат: ', Result);
	 ReadLn
end.

Давайте же помотрим результат!!!! Запускаем вводим число... ЧТО ЭТО ЗА НАФИГ??? Почему 0? ... запускаем вновь ... опять 0! Досада. Видимо в программу залезла логическая ошибка! Ну вот теперь мы познаем всю мощь отладчика!
Итак строки:

begin
     ClrScr;

     Write ('Какое значение? ');
     ReadLn (n);

Выглядят довольно понятно и ошибка явно не в них. Так зачем же нам тратить наше драгоценное время на их пошаговое исполнение? Давайте сразу же перейдем к следующей строке. Наведите на неё курсор и нажмите Ctrl+F8 (меню Debug - > Add breakpoint) Она подсветится красным цветом. Что же такого чудесного мы сделали? А вот что: мы добавили breakpoint (по-русски: брякпоинт, бряк:) - точку остановки. Когда исполнение программы дойдёт до этой строчки, то мы сразуже перейдём в режим по-шагового исполнения. Увидите список бряков можно Debug -> Breakpoints.
Итак бряк есть, теперь нам нужно всё время смотреть, что же у нас в переменной Result. Этого можно добится двумя путями.

  1. Добавить внутрь цикла строчку типа: writeLn (Result);
  2. Использовать отладчик.

Второе на мой взгляд несколько предпочтительнее :) Давайте сделаем вот что: выберем Debug -> Add Watch или Ctrl+F7 - в появившемся диалоге укажем имя нашей переменной: Result (в поле Watch expression) Появится окно watches (если не появилось, то Debug -> Watch). В нём вы увидите значение переменной Result. Так же можно для практики добавить туда и переменные i и n. Так тепрь мы можем наблюдать, что же там внутри и как меняются переменные. Ну вот, теперь запускаем программу (Ctrl+F9), вводим для примера 5 и сразу же оказываемся внутри программы.
Заметьте, что у нас такие значения: Result = 0, i = 0, n = 5. Давим на F8 (не забыли что это такое:) Result изменился с 0 на 5 (делаем вывод: оператор := работает правильно, ошибка не в нём :)))) Входим в цикл (давим F8)... Заметьте, что я специально добавил в цикл конструкцию begin-end (в неё нет надобности). Я это сделал, что бы при отладке внутри цикла у нас подсветка двигалась :) а иначе она просто будет висеть на строчке: Result := Result * i; и создаётся впечатление остановки программы. Итак проходим первый этап цикла (i = 0) опа!! Вот оно! Result сразу же изменился на 0 ! Давайте посмотрим, что же будет дальше... а дальше он так и останется 0. Можно заметить, что мы умножаем Result на i, но ведь в начале цикла i = 0 т.е. мы умножаем на 0 и поэтому Result всегда 0! УРА! Нашли ошибку! Прервём исполнение программы (Ctrl+F2). Для устранения ошибки мы сделаем следующее: в цикле i должно изменяться от 1 до n. Я надеюсь, что переписать программу для вас не составит труда. Итак исправим, уберём бряк (на той строчке Ctrl+F8) Запустим программу... ВОТ ЧЁРТ! Теперь Result не 0 но очень уж большой!!!! В чём же дело?? Давайте повторим всё заново: поставим бряк и запустим её снова... введём 5... Постойте ка а почему это у нас Result в начале равен 5?? Ведь факториал это произведение от 1 до n ??? Да вот же в чём дело! Мы вначале присваиваем Result := n; А надо так: Result := 1; Теперь всё нормально!
Давайте удалим всю отладочную информацию: Очистим все бряки (Debug -> Breakpoints . кнопка Clear All) Удалим все просмоторщики (в окне watches правая кнопка мыши из меню Clear All) и выполним программу заново. Ещё одна мелочь, которая не сразу бросается в глаза: переменная Result у нас типа longint, однако и этого не достаточно, что бы вместить факториалы чисел больше 31! Как подсчитать факториал для любых чисел мы поговорим попозже. Обязательно поговорим!




программирование на Паскале, Pascal, BP, TP, BorlandPascal, TurboPascal turbo pascal 7.0, borland pascal 7.0, языки программирования, pascal учебник
Рад приветствовать! =) Начнем мы с истории данного сайта. Изначально он разрабатывался как типично авторский проект, не неся в себе особых целей. Я лишь хотел освоить азы html верстки и опробывать свои силы в разработке web-сайтов. Тематика "программирование на Паскале" была выбрана не случайно, до этого я долго изучал этот ЯП и всё это вылилось в написание собственного самоучителя по Паскалю. Сейчас это всё вспоминается с некоторой долей иронии и улыбкой на лице. В нынешнее время я полностью занимаюсь web-разработками и отошел от прикладного программирования, но данный проект решил всё же не забрасывать и вдохнуть в него новую жизнь, освежив дизайн и контент.

С уважением, Евгений Злобин
турбо-паскаль скачать, файлы паскаль, бесплтано скачать pascal