Цикл — это многократно повторяющаяся последовательность действий. Первый цикл, с которым мы познакомимся в этом уроке называется While…Do (делай пока верно условие).
Синтаксис:
While условие Do begin //тело цикла end;
Сейчас нам нужно открыть Delphi и создать новый проект. Кидаем на форму компоненты Button и Label:
Создаем на кнопке процедуру OnClick и первое, что нам надо сделать — это ввести переменную A типа Integer:
procedure TForm1.Button1Click(Sender: TObject); var A:integer; begin ...
Теперь между ключевыми словами begin и end установим значение переменной A равное 1:
A:=1;
И сейчас мы напишем сам цикл, с условием A<>100, то есть пока A не равно 100 будет выполняться цикл.
Если же А = 100 — цикл остановится:
While A<>100 do begin //Тело цикла end;
Далее, нам нужно что-то сделать в теле цикла. Давайте будем увеличивать значение переменной A на единицу и выводить значение переменной в Label.
Вместо комментария (//Тело цикла) мы напишем:
A:=A+1; Label1.Caption:=IntToStr(A);
Общий вид кода:
procedure TForm1.Button1Click(Sender: TObject); var A:integer; begin A:=1; //Присваеваем единицу While A <> 100 do //Пока А не равно 100 - делаем begin A:=a+1; //прибавляяем единицу Label1.Caption:=IntToStr(a); //Выводим значение А end; end;
Компилируем программу, нажимаем на кнопку и видим, что лабел показывает нам сотню. Но почему сразу сотню? Почему не 1,2,3,4 и так до ста.
Дело в том, что цикл выполняется на столько быстро, что мы не замечаем как лабел выводит нам сначала 1 потом 2 и потом 3.
По этому мы видим только сотню — конечный результат. Кто-то может подумать, что так не интересно :).
Хорошо, сейчас сделаем так, чтобы видеть как Delphi выполняет цикл.
Дописываем после строки
Label1.Caption:=IntToStr(a);
Вот эти две строчки
Application.ProcessMessages; sleep(100);
Они делают следующие:
- Application.HandleMessage — это метод, позволяющий выводить значения переменных во время работы цикла.
Не смотря на то, что мы и так выводим переменную в лабел, этот метод необходим. - sleep(100); — функция Sleep() говорит программе, что нужно поспать, как бы заморозиться на какое-то количество миллисекунд. Миллисекунды указываются в скобках. В секунде 1000 миллисекунд.
Общий вид кода:
procedure TForm1.Button1Click(Sender: TObject); var A:integer; begin A:=1; //Присваеваем единицу While A <> 100 do //Пока А не равно 100 - делаем begin A:=a+1; //прибавляяем единицу Label1.Caption:=IntToStr(a); //Выводим значение А Application.ProcessMessages; sleep(100); end; end;
Компилируйте и проверяйте.
С циклом While мы закончили, теперь разберем цикл со счетчиком или другое его название For…To…Do.
Данный цикл удобно применять, когда нам точно известно кол-во повторений.
Синтаксис:
For переменная счетчик:=Выражение №1 To выражение №2 Do begin //тело цикла end;
Этот цикл называется со счетчиком, потому что он сам увеличивает переменную счетчик на единицу.
Первым делом нам нужно добавить переменную S типа Integer.
procedure TForm1.Button1Click(Sender: TObject); var A, S:integer; begin ...
Далее, пишем программу, которая будет считать сумму чисел от 1 до 100.
То есть имеется ряд чисел 1 2 3 4 5 6 7 … 100.
Программа будет складывать эти числа между собой, то есть 1+2+3+4+5+6+7+…+100.
Стираем цикл While и пишем цикл For, но перед ним присвойте переменной S ноль:
For A:=1 to 100 do begin //Тело цикла end;
Этот цикл повторит действия в теле 100 раз.
В тело цикла мы запишем:
S:=s+a;
Программа будет считать сумму чисел от 1 до 100, прибавляя к переменной S переменную счетчик A.
И после цикла выводим результат в лабел.
Label1.Caption:=IntToStr(S);
Общий вид:
procedure TForm1.Button1Click(Sender: TObject); var A, S:integer; begin S:=0; //Присваеваем ноль For A:=1 to 100 do begin S:=s+a; //Вычисления end; Label1.Caption:=IntToStr(S); end;
У цикла For есть цикл двойник, он может считать в обратном порядке. Для этого нужно изменить ключевое слово To на DownTo
Пример той же самой программы, но с обратным счетчиком:
procedure TForm1.Button1Click(Sender: TObject); var A, S:integer; begin S:=0; //Присваеваем ноль For A:=100 downto 1 do begin S:=s+a; //Вычисления end; Label1.Caption:=IntToStr(S); end;
Далее. Знакомимся с циклом Repeat.
Синтаксис:
Repeat //Тело цикла Until условие;
Этот цикл сначала выполняет действие, а потом проверяет условие. Цикл выполниться в любом случае хотя бы один раз.
Стираем цикл For в нашей программе и пишем цикл Repeat:
procedure TForm1.Button1Click(Sender: TObject); var A, S:integer; begin S:=0; //Присваеваем ноль a:=0; Repeat a:=a+1; S:=s+a; //Вычисления Until a=100; //цикл будет выполняться пока a не достигнет 100 Label1.Caption:=IntToStr(S); end;
Эта программа выполнит тоже самое что и предыдущая.
Ну вот мы и закончили обучение циклам! Сейчас выучим 2 команды для управления ими.
Сразу приведу пример программы, а потом прокомментирую что и как в ней работает:
procedure TForm1.Button1Click(Sender: TObject); var A, S:integer; begin S:=0; //Присваеваем ноль For A:=1 to 1000 do begin S:=s+a; //Вычисления if S>100 then break else continue; end; Label1.Caption:=IntToStr(S); end;
В теле цикла присутствует условие, которое проверяет переменную S. Если S больше 100, то мы экстренно выходим из цикла при помощи команды break,
иначе продолжаем цикл командой continue. Пример программы не очень удачный, так как цикл будет работать даже если мы стерем команду continue, но я надеюсь, что суть вы уловили.
Экспериментируйте и всё получится. Жду комментов 
Задание на закрепление: напишите программу, которая вычислит сумму двухзначных чисел и выведет ее в Label.
Ну вот и всё! Удачи!
Встретимся в следующем уроке!
Эх, раз, ещё раз, Ещё много-много раз!
Цыганская песня о циклах
Терпенье и труд всё перетрут.
Пословица
Очень часто в программах встречаются ситуации, когда одни и те же действия нужно повторить многократно. Для таких случаев в языке Delphiприпасены аж три оператора циклов — for, whileи repeat.
Примеры циклов мы можем найти и в повседневной жизни: времена года (циклически сменяют друг друга весна — лето — осень — зима), время суток (утро — день — вечер — ночь), фазы Луны, вращение планет вокруг Солнца и Солнечной системы вокруг центра Галактики, спортивные состязания, учебный год, режим дня, дыхание и кровообращение, часы, биоритмы активности человека — можно даже утверждать, что уникальны именно неповторяющиеся события, а не циклические.
Оператор FOR
Цикл forвстречается в программах чаще других. Его используют, когда число повторений оператора заранее известно.
Цикл forзаписывается в одной из форм:
forпеременная:= начальное значение to конечное значение doоператор;
forпеременная:= начальное значение downtoконечное значение doоператор;
Оператор (или составной оператор) называется телом цикла. Число повторений (они также называются итерациями) определяется переменной (управляющей переменной, счётчиком цикла, параметром цикла), которая автоматически увеличивается или уменьшается при каждом выполнении тела цикла.
Переменная цикла — это локальная переменная порядкового типа (обычно целого). Она не должна изменяться в теле цикла (да вы и не сможете этого сделать — Delphiне позволит!), но её значение может использоваться в выражениях внутри цикла.
Первая форма действует так:
1.Переменной цикла присваивается начальное значение.
2.Текущее значение переменной цикла сравнивается с её конечным значением. Если оно меньше или равно конечному значению, то выполняется тело цикла — оператор(ы). Если больше, то выполнение цикла заканчивается и управление переходит к следующему за структурой forоператору.
3.Если цикл не завершён в п.2, то значение переменной цикла увеличивается на 1 и цикл возвращается к п.2.
Понятно, что выполнение цикла forрано или поздно закончится. Более того, он может вообще не выполняться ни разу, если начальное значение сразу больше конечного, либо будет выполнен только 1 раз, если начальное значение равно конечному.
Важно помнить, что после завершения цикла значение переменной цикла не определено, то есть её нельзя использовать в выражениях!
Вторая форма действует аналогично, за исключением того, что в п.3 значение переменной цикла уменьшается на 1. Оператор forс downtoне будет выполнен ни разу, если начальное значение переменной цикла меньше конечного.
Рассмотрим простой цикл, считающий до пяти:
procedure 5;
var i: integer;
begin
for i:= 1 to 5 do
//^ Заголовок цикла
print(inttostr(i)
); //^ Тело цикла
end;
Здесь i- переменная цикла (их обычно именуют буквами i, j, к, l, m, n).
Начальное значение переменной цикла равно 1, конечное 5.
Таким образом, цикл будет выполнен 5 раз, при этом на экране будут напечатаны числа 1 2 3 4 5
Оператор FOR… IN
В последних версиях Delphiпоявилась новая разновидность оператора цикла For. Оператор For… inперебирает все элементы коллекции — это могут быть символы строки, элементы массивов и записей.
for переменная in коллекция do оператор;
В языке C# подобный оператор называется foreach.
Переменная цикла должна быть объявлена в том же блоке, что и оператор цикла, а её тип должен быть совместим с типом элементов в коллекции.
Изменять значение переменной цикла внутри цикла нельзя!
Установите на форме текстовое поле Edit1, щёлкните по кнопке Button1 и напишите код в методе Button1Click:
procedure TForm2.Button1Click(Sender: TObject); var
s: string; ch: char; begin
s:= Edit1.Text; for ch in s do
ListBox1.Items.Add(ch);
end;
Здесь мы считываем строку, которую ввёл пользователь в текстовое поле, в цикле for .inперебираем все символы этой строки и добавляем их в список
И для этого нам даже не нужно знать длину строки — оператор for…inумеет работать самостоятельно!
Очень часто в программах приходится перебирать и элементы массива. Дополним нашу программу целочисленным массивом arr, в который поместим восемь первых простых чисел:
var
Form2: TForm2;
arr: array[1..8] of integer = (2,3, 5, 7, 11, 13, 17, 19);
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender:
TObject);
var
s: string;
ch: char;
i: integer;
begin
s:= Editl.Text;
if s <> 'Editl' then
for ch in s do
ListBoxl.Items.Add(ch)
else
for i in arr do
end;
В метод Button1Clickдобавим проверку строки в текстовом поле. Если пользователь не ввёл строку, то мы печатаем элементы массива (Рис. У8.3), в противном случае — строку.
Оператор WHILE
Любовь — кольцо, а у кольца Начала нет и нет конца
Песня о зацикливании
Цикл while называется также циклом с предусловием и имеет следующий вид:
while выражение do оператор;
Выражение должно быть логического типа (boolean) и называется также условием выполнения цикла.
Работает он так:
1. Вычисляется логическое выражение.
2. Если оно ложно (значение равно FALSE), то выполнение цикла заканчивается.
3. Если оно истинно (значение равно TRUE), то выполняется оператор и управление передаётся в п.1.
Поскольку условие проверяется до выполнения тела цикла, то операторы могут быть вообще не выполнены ни одного раза — если выражение с самого начала ложно.
Как мы видим, цикл заканчивается, когда условие станет ложным. А почему изменяется значение выражения? — Да потому, что изменились значения переменных, входящих в это условие. И это может произойти только в теле цикла. Отсюда грустный вывод: цикл whileможет вообще никогда не закончиться, и программа зациклится навечно, что очень часто и бывает!
Пример 1. Найдём все числа Фибоначчи, которые не больше некоторого заданного числа n.
Результаты вычислений мы будем выводить в список lstProtocol задавать нужное нам число от 2 до 99999 в компоненте speNUM а понуждать программу к этому — с помощью кнопки sbtGo:
Вводим в однострочныйй редактор число и попадаем в процедуру обработки:
procedure TfrmMain.sbtGoClick(Sender: TObject);
var n: integer;
begin
n:= speNum.Value; fibo(n); end;
Здесь вызывается процедура, которая и проводит нужные нам расчёты:
//РЕШИТЬ ЗАДАЧУ procedure fibo(n: integer);
var f,f1,f2: integer; begin f:=0; f1:=1; f2:=1;
frmMain.lstProtokol.Clear; while f2 <= n do begin
frmMain.lstProtokol.Items.add(inttostr(f2)); f2:= f1 + f; f:=f1; f1:=f2;
end;
end;
Чтобы понять, как действует в этом примере оператор while, уделим немного времени числам Фибоначчи (а эти числа очень интересны!). Нетрудно догадаться, что их открыл Фибоначчи (он же Леонардо Пизанский), средневековый математик, внимательно наблюдавший за размножением кроликов.
Первые два числа равняются 1:
f1:=1;
f2:=1;
а все последующие равны сумме двух предыдущих, то есть третье число 1 + 1 = 2, четвёртое 1 + 2= 3, пятое 2 + 3 = 5 и так далее, до бесконечности:
f2:= f1+f;
f:=f1;
f1:=f2;
А цикл while f2 <= n do только проверяет, не достигло ли очередное число Фибоначчи заданного нами предела.
Исходный код программы находится в папке fibonacci.
Оператор REPEAT
Цикл repeatназывается также циклом с постусловием и имеет следующий вид:
repeat
оператор untilвыражение;
Выражение (условие выполнения цикла) должно быть логического типа.
Оператор repeatдействует почти так же, как while, но с одним важным отличием: условие продолжение цикла проверяется после выполнения оператора. Это значит, что цикл обязательно будет исполнен по крайней мере 1 раз, даже если логическое выражение истинно с самого начала.
По записи цикла видно, что зарезервированные слова repeatи untilиграют роль операторных скобок, поэтому в теле цикла можно просто перечислять операторы — использовать составной оператор нет необходимости (но это и не запрещено). По этой же причине перед untilточку с запятой разрешается не ставить.
Работает оператор repeat так:
- Выполняется оператор в теле цикла.
- Вычисляется логическое выражение. Если оно ложно (значение равно FALSE), то управление передаётся в п.1. Если оно истинно (значение равно TRUE), то выполнение цикла заканчивается.
Теперь мы можем найти и второе различие циклов whileи repeat: первый заканчивается, когда условие не выполняется (значение выражения становится равным FALSE), второй — когда условие выполняется (значение выражения становится равным TRUE).
Пример 2. Найдём все числа Фибоначчи, которые не больше некоторого заданного числа n.
Внешне («интерфейсно») программа ничем не отличается от первого примера, но теперь мы найдём числа Фибоначчи с помощью оператора repeat:
//РЕШИТЬ ЗАДАЧУ
procedure fibo(n: integer); var f,f1,f2: integer; begin f:=0; f1:=1; f2:=1;
frmMain.lstProtokol.Clear;
repeat
frmMain.lstProtokol.Items.add(inttostr(f2)); f2:= f1 + f; f:=f1; f1:=f2; until f2 >= n;
end;
Легко заметить, что нам пришлось изменить только небольшую часть кода: заменить один оператор цикла другим и «инвертировать» условие продолжения цикла. Как говорится, лёгким движением руки whileпревращается в элегантный repeat!
Исходный код программы находится в папке fibonacci2.
Вложенные циклы
Довольно часто внутри одного цикла нужно выполнить другой цикл, например, при поиске нужного элемента в двумерном массиве. Хорошим примером вложенных циклов может быть русская матрёшка: каждая меньшая по размерам кукла целиком посещается внутри большей. При известном мастерстве удаётся создать глубоко вложенные матрёшки:
for . . . //начало первого цикла
begin
for . . . //начало второго цикла begin
for . . . //начало третьего цикла
begin
end; //конец третьего цикла
end; //конец второго цикла
Как и всегда, отступами выделяйте отдельные циклы! Вложенных циклов может быть любое количество и это могут быть не только циклы for, но и whileи repeatв любых сочетаниях.
Пример. В своё время мне пришлось на городской олимпиаде по математике решать такую задачу: Подсчитать, сколько раз пятёрка входит в представление чисел от 1 до 1000 в виде произведения простых чисел: 2, 3, 5, 7, 11,. (например, 24 = 2 * 2 * 2 * 3; 25 = 5 * 5). Мы не на олимпиаде, поэтому пусть задачу решает компьютер, а мы составим для него простенькую программу:
//РЕШИТЬ ЗАДАЧУ
procedure TfrmMain.sbtGoClick(Sender: TObject);
var i, n, n5: integer; begin n5:=0;
for i:= 1 to 1000 do begin //проверяем все заданные числа n:= i;
while TRUE do begin
if n mod 5 = 0 then begin n:= n div 5; inc(n5); end
else break; end; end;
frmMain.lstProtokol.Items.add(inttostr(n5));
end;
Здесь мы легко найдём цикл for, в котором перебираются все заданные числа, и вложенный в него бесконечный цикл while, который и подсчитывает их делители. Если число делится нацело на 5, то увеличиваем счётчик на 1, иначе переходим к проверке следующего числа. Олимпиадный «подвох» этой задачи заключается в том, что полученное после деления на 5 число опять может быть кратно 5, то есть его опять нужно проверить. Если это обстоятельство не учесть, то число пятёрок можно было бы подсчитать мгновенно: 1000 : 5 = 200. Таким образом, в первой тысяче чисел ровно 200 делятся на 5. Ещё 40 делятся на 25 (5*5), 8 — на 125 (5*5*5) и одно — на 625 (5*5*5*5). Зная ответ, и задачу легко решить, а я на олимпиаде намаялся
Помоги проекту! Расскажи друзьям об этом сайте:
Материал из Викиверситета
Символьный тип данных
Символьный тип данных на языке Delphi — char. Его размер 1 или 2 байта(в версиях ранее Delphi 2009 тип char был размерностью 1 байт, далее 2 байта. В современных версиях однобайтовым является тип AnsiChar ). Для кодировки используется код ASCII. В поздних версиях Delphi для кодировки используется Unicode, поэтому размер символьного типа увеличен до 2 байт. Значения переменных и литералов(констант) должны быть заключены в апострофы.
var c:char; begin c:='a';//латинская строчная a c:=#$61;// то же, так как код этой буквы в шестнадцатеричной системе равен 61 c:=#97; //то же, так как код этой буквы в десятичной системе равен 97 c:='ф'; //кириллическая буква ф c:=#$444;// то же, так как код этой буквы в шестнадцатеричной системе равен U+444 c:=#1092;// то же, так как код этой буквы в десятичной системе равен U+1092 //функция ord(c) или прямое преобразование типов word(c) вернет целочисленное значение, равное 1092 writeln(c,'=', ord(c));//вернет "ф=1092" end.
Операторы цикла
В языке Delphi для создания циклов используются операторы while,repeat..until,for.
Операторы while
Оператор while(навываемый также оператором с предусловием) имеет следующую структуру:
while <логическое условие> do <тело цикла>
Под телом цикла подразумевается либо одиночная, либо составная инструкция( то есть набор инструкций, вложенный в скобки begin/end)
Тело цикла повторяется до тех пор, пока логическое условие(то есть выражение булева типа) истино. Когда оно становится ложным, управление передается следующему после while оператору.
{$APPTYPE CONSOLE} var a:integer; begin readln(a); while(a>10) do begin //Если а меньше либо равно десяти, то цикл не будет выполняться a:=a-1; writeln('a= ',a); end; end.
В зависимости от логического условия, цикл может ни разу не выполниться. Если в цикле требуется использование более одного оператора, то необходимо использовать begin..end;
Оператор repeat
Оператор цикла repeat(называемый оператором цикла с постусловием) аналогичен оператору while, но отличается от него, во-первых, тем, что условие проверяется после очередного выполнения операторов тела цикла и таким образом гарантируется хотя бы однократное выполнение тем цикла, а во-вторых, тем, что критерием прекращения цикла является истинность булева выражения (постусловия).
Оператор repeat имеет следующую структуру:
repeat <тело цикла> until <логическое условие выхода из цикла>
Также, для тела цикла не нужно использовать begin и end, так как в данном случае скобками тела цикла являются сами ключевые слова repeat/until.
{$APPTYPE CONSOLE} var a:integer; begin a:=10; repeat writeln(a); a:=a-1; until a<5 ; readln; end.
Оператор for
Оператор for имеет следующую структуру:
for <счетчик цикла> := <нижняя граница> to/downto <верхняя граница> do <тело цикла>
В отличие от операторов while и repeat, при использовании оператора for мы (явно или неявно) задаем количество повторений тела цикла. Счетчик цикла — любая переменная порядкового типа.
Для правильно работы цикла, равно как и в целях быстродействия, рекомедуется, чтобы счетчик цикла был локальной переменной(то есть эта переменная должна быть определена в той же функции, что и сам цикл).
Нижняя граница - выражение(константа либо вычисляемое), к которому будет приравнен счетчик цила, при первом выполнении тела цикла. Когда счетчик выйдет за пределы верхней границы(которая также может быть константой либо вычисляемым выражением), цикл прекратится. Если нижняя граница больше верхней, и используется прямой цикл( то есть выбрана конструкция to, а не downto ), то цикл не будет выполнен ни разу (подобно этому,если нижняя граница равна верхней, то цикл выполнится ровно один раз). После выполнения тела цикла, параметр цикла увеличивается на единицу(или уменьшается, если вместо to мы используем downto).
Не следует использовать значение счетчика цикла, после выхода цикла.
{$APPTYPE CONSOLE} var i,x,y:integer; begin readln(i); //Неважно какое значение у i, при входе в цикл, ее значение приравнивается к 10 for i:=10 downto 2 do //После выполнения тела цикла, значение i уменьшается на единицу writeln(i); for i:=2 to 1 do //тело цикла не выполнится ни разу writeln(i); for i:=1 to 1 do //тело цикла выполнится ровно один раз writeln(i); x:=-1;y:=2; for i:=x to y do begin //границы цикла могут быть неизвестны на этапе компиляции. В данном случае тело цикла выполнится 4 раза writeln(i); end; for i:=x downto y do //поскольку x<y, а цикл обратный(используется downto), то тело цикла выполнено не будет writeln(i); readln; end.
Не допускается присвоение внутри тела цикла значений переменной-счетчику цикла.
Обратный цикл (с использованием downto, когда счетчик цикла уменьшается от первого граничного значения ко второму) может быть слегка эффективнее(быстрее) прямого. Это имеет значение, если нужна максимальная производительность, а тело цикла маленькое и простое.
Продвинутые техники оператора for в поздних версиях Delphi
Цикл for может быть применен для для всех элементов значения перечисляемого типа в формате
for <итератор> in <значение_перечисляемого_типа> do <простая_или_составная_инструкция>;
В каждой итерации, переменная-итератор принимает значение текущего элемента значения перечисляемого типа.
procedure test3(x,y:integer); var c:char; i:integer; s:string; sl: TStringList; d:array of integer; begin writeln('Диапазон A..Z'); for c in ['A'..'Z'] do write(c); //вернет ABCDEFGHIJKLMNOPQRSTUVWXYZ x:=1; y:=3; writeln(''); writeln('Диапазон 1..3'); for i in [x..y] do begin write(i,','); end; //вернет 1,2,3, writeln(''); sl:=TStringList.Create(); sl.Add('Строка1'); sl.Add('Строка2'); writeln(''); writeln('Перечислимое выражение типа TStringList'); for s in sl do write(s,','); //вернет "Строка1,Строка2," writeln(''); if CompilerVersion>=28 then// Delphi XE7 d:=[1,2,3]//в Delphi XE7 допускается такая инициализация динамического массива else begin Setlength(d,3); d[0]:=1;d[1]:=2;d[2]:=3; end; writeln(''); writeln('Перечислимое выражение типа динамический массив целых( array of integer)'); for i in d do begin write(i,','); end; // вернет 1,2,3, writeln(''); writeln('Перечислимое выражение пользовательского типа -- числа фибоначчи'); for i in TFibonacci.GetNumbers(20) do write(i,','); //вернет 0,1,2,3,5,8,13, writeln(''); end;
для полноты приведем реализацию записи(record ) TFibonacci
TFibonacci=record private pp,p, max:integer; function GetCurrent:integer; inline; public function GetEnumerator():TFibonacci; function MoveNext():boolean; property Current:integer read GetCurrent; class function GetNumbers(max:integer):TFibonacci;static; end; { TFibonacci } function TFibonacci.GetCurrent: integer; //процедура -- "геттер" для свойства Current //всякий перечислитель изначально не инициализирован: перед первым вызовом Current, //необходимо вызвать MoveNext, и убедится, что эта функция вернула true begin result:=pp+p; end; function TFibonacci.GetEnumerator: TFibonacci;// всякий перечислимое значение структурного типа(класс или запись) //должен иметь публичную функцию GetEnumerator, возвращающюю структурный тип, // использующийся как перечислитель(Enumerator), реализующий MoveNext():boolean // и свойство Current. В данном случае экземпляр возвращает самого себя begin result:=self; end; class function TFibonacci.GetNumbers(max: integer): TFibonacci;//своего рода конструктор var fb:TFibonacci; begin result.max:=max; result.pp:=-1; result.p:=0; end; function TFibonacci.MoveNext: boolean; // передвигает указатель перечислителя на следующую позицию, или в случае неинициализированного // перечислителя -- на первую позицию перечисляемого значения,либо возвращает false, означающее // конец перечисления var prev:integer; begin prev:=GetCurrent(); case prev of -1: pp:=0; 0: p:=1; else begin pp:=p; p:= prev; end; end; result:= GetCurrent()<max ; end;
Операторы досрочного завершения цикла
Бывают ситуации, когда надо досрочно завершить цикл, либо пропустить остаток тела цикла, и начать новую итерацию цикла.
В первом случае используется оператор break. Во втором continue.
Данные операторы доступны для всех типов цикла: while, repeat и for.
Рассмотрим программу:
{$APPTYPE CONSOLE} var i:integer; begin I:=-10; while i<5 do begin writeln(10/i); i:=i+1; if (i=0) break;//досрочное завершение цикла end; readln; end.
Эта программа выводит результат деления 10 на i. Но как мы видим, i может принять значение равное 0, и тогда деление на 0 приведет к аварийному завершению программы. Чтобы это предотвратить, мы можем прервать цикл, если значение i становится равным 0.
Оператор continue передает управление оператору, стоящему в начале тела цикла. Попробуем исправить программу, используя оператор continue.
{$APPTYPE CONSOLE} var i:integer; begin I:=-10; while i<5 do begin i:=i+1;//модификация переменной, входящей в условие цикла if i=0 then continue;//мы пропускаем дальнейшее тело цикла, и начинаем новую итерацию. Помните, что это может //привести к бесконечному циклу, если модификация переменных, входящих в условие цикла, происходит // в пропущенной(следующей ниже) части цикла writeln(10/i); end; readln; end.
Как мы видим, когда i становится равно 0, то управление передается началу цикла, в результате чего значение i становится равно единице. Благодаря оператору continue, цикл не прервется, и, когда значение i станет равно 5, цикл нормально завершится.
Следует добавить, что одним из немногих случаев, когда использование безусловного перехода (goto) оправдано, является выход из нескольких вложенных циклов.
The loop is a common element in all programming languages. Delphi has three control structures that execute blocks of code repeatedly: for, repeat … until and while … do.
The FOR loop
Suppose we need to repeat an operation a fixed number of times.
// show 1,2,3,4,5 message boxes
var j: integer;
begin
for j := 1 to 5 do
begin
ShowMessage(‘Box: ‘+IntToStr(j)) ;
end;
end;
The value of a control variable (j), which is really just a counter, determines how many times a for statement runs. The keyword for sets up a counter. In the preceding example, the starting value for the counter is set to 1. The ending value is set to 5.
When the for statement begins running the counter variable is set to the starting value. Delphi than checks whether the value for the counter is less than the ending value. If the value is greater, nothing is done (program execution jumps to the line of code immediately following the for loop code block). If the starting value is less than the ending value, the body of the loop is executed (here: the message box is displayed). Finally, Delphi adds 1 to the counter and starts the process again.
Sometimes it is necessary to count backward. The downto keyword specifies that the value of a counter should be decremented by one each time the loop executes (it is not possible to specify an increment / decrement other than one). An example of a for loop that counts backward.
var j: integer;
begin
for j := 5 downto 1 do
begin
ShowMessage(‘T minus ‘ + IntToStr(j) + ‘seconds’) ;
end;
ShowMessage(‘For sequence executed!’) ;
end;
Note: it’s important that you never change the value of the control variable in the middle of the loop. Doing so will cause errors.
Nested FOR loops
Writing a for loop within another for loop (nesting loops) is very useful when you want to fill / display data in a table or a grid.
var k,j: integer;
begin
//this double loop is executed 4×4=16 times
for k:= 1 to 4 do
for j:= 4 downto 1 do
ShowMessage(‘Box: ‘+ IntToStr(k)+ ‘,’ + IntToStr(j)) ;
end;
The rule for nesting for-next loops is simple: the inner loop (j counter) must be completed before the next statement for the outer loop is encountered (k counter). We can have triply or quadruply nested loops, or even more.
Note: Generally, the begin and end keywords are not strictly required, as you can see. If begin and end are not used, the statement immediately following the for statement is considered the body of the loop.
The FOR-IN loop
If you have Delphi 2005 or any newer version, you can use the «new» for-element-in-collection style iteration over containers. The following example demonstrates iteration over string expressions: for each char in string check if the character is either ‘a’ or ‘e’ or ‘i’.
const
s = ‘About Delphi Programming’;
var
c : char;
begin
for c in s do
begin
if c in [‘a’,’e’,’i’] then
begin
// do something
end;
end;
end;
The WHILE and REPEAT loops
Sometimes we won’t know exactly how many times a loop should cycle. What if we want to repeat an operation until we reach a specific goal?
The most important difference between the while-do loop and the repeat-until loop is that the code of the repeat statement is always executed at least once.
The general pattern when we write a repeat (and while) type of loop in Delphi is as follows:
repeat
begin
statements;
end;
until condition = true
while condition = true do
begin
statements;
end;
Here is the code to show 5 successive message boxes using repeat-until:
var
j: integer;
begin
j:=0;
repeat
begin
j := j + 1;
ShowMessage(‘Box:’+IntToStr(j)) ;
end;
until j > 5;
end;
As you can see, the repeat statement evaluates a condition at the end of the loop (therefore repeat loop is executed for sure at least once).
The while statement, on the other hand, evaluates a condition at the beginning of the loop. Since the test is being done at the top, we will usually need to make sure that the condition makes sense before the loop is processed, if this is not true the compiler may decide to remove the loop from the code.
var j: integer;
begin
j:=0;
while j < 5 do
begin
j:=j+1;
ShowMessage(‘Box:’+IntToStr(j)) ;
end;
end;
Break and Continue
The Break and Continue procedures can be used to control the flow of repetitive statements: The Break procedure causes the flow of control to exit a for, while, or repeat statement and continue at the next statement following the loop statement. Continue allows the flow of control to proceed to the next iteration of repeating operation.
Циклы – это одна из важнейших конструкций в программировании. Они позволяют выполнять однотипные действия несколько раз, пока выполняется определенное условие. В Delphi для создания циклов существует несколько конструкций.
For цикл
Один из самых распространенных циклов в Delphi – это For-цикл. Он позволяет выполнять определенный набор действий заданное число раз.
for i := 1 to 10 do
begin
// Действия, которые нужно выполнить
end;
В приведенном примере цикл выполняется 10 раз, начиная с i = 1 и заканчивая i = 10. Действия, которые нужно выполнить внутри цикла, записываются между ключевыми словами begin и end.
While цикл
Еще одним типом цикла в Delphi является While-цикл. Он выполняет действия до тех пор, пока определенное условие истинно.
while условие do
begin
// Действия, которые нужно выполнить
end;
В условии указывается логическое выражение, которое проверяется на каждой итерации цикла. Если оно истинно, то выполняются действия внутри цикла. Когда условие становится ложным, цикл прекращается.
Repeat-Until цикл
Еще одна разновидность цикла в Delphi – это Repeat-Until-цикл. Он выполняет действия, пока определенное условие ложно.
repeat
begin
// Действия, которые нужно выполнить
end;
until условие;
Цикл выполняет действия внутри блока begin и end до тех пор, пока условие ложно. Когда условие становится истинным, цикл прекращается.
Примеры кода
Пример 1: For цикл для вывода чисел от 1 до 10
var
i: Integer;
begin
for i := 1 to 10 do
begin
WriteLn(i);
end;
end.
Пример 2: While цикл для проверки условия
var
x: Integer;
begin
x := 0;
while x < 10 do
begin
WriteLn(x);
x := x + 1;
end;
end.
Пример 3: Repeat-Until цикл для ввода числа больше 10
var
x: Integer;
begin
repeat
begin
Write('Введите число больше 10: ');
ReadLn(x);
end;
until x > 10;
WriteLn('Введено число больше 10.');
end.
Заключение
Циклы – важная часть программирования на Delphi. Они позволяют выполнять повторяющиеся действия и упрощают написание кода. Зная различные типы циклов и примеры их использования, вы сможете эффективно решать задачи в своих программах.
Похожие статьи
Циклы в Delphi — это структуры программирования, которые позволяют выполнять повторяющиеся действия в вашем коде.
Существует несколько типов циклов в Delphi:
- Цикл for — это наиболее распространенный тип цикла в Delphi. Он позволяет вам выполнять повторяющиеся действия заданное количество раз. Пример использования цикла for:
1 2 3 4 |
for i := 1 to 10 do begin // Ваш код end; |
- Цикл while — этот тип цикла позволяет вам выполнять повторяющиеся действия, пока выполняется некоторое условие. Пример использования цикла while:
1 2 3 4 5 |
while i < 10 do begin // Ваш код i := i + 1; end; |
- Цикл repeat-until — этот тип цикла позволяет вам выполнять повторяющиеся действия, пока выполняется некоторое условие в конце цикла. Пример использования цикла repeat-until:
1 2 3 4 |
repeat // Ваш код i := i + 1; until i >= 10; |
В циклах Delphi вы можете использовать различные операторы управления циклом, такие как break, continue и exit, чтобы изменить поток выполнения цикла в зависимости от условий, определенных в вашем коде.
Какой цикл в Delphi лучше использовать?
Выбор того, какой тип цикла использовать в Delphi, зависит от конкретной задачи, которую вы решаете. Каждый тип цикла имеет свои преимущества и недостатки в зависимости от условий выполнения.
- Цикл for: используется, когда вы знаете точное количество итераций, которые должен выполнить цикл. Это самый быстрый и наиболее эффективный тип цикла в Delphi.
- Цикл while: используется, когда вы не знаете заранее, сколько раз должен выполниться цикл. Этот тип цикла будет выполняться до тех пор, пока заданное условие остается истинным.
- Цикл repeat-until: также используется, когда вы не знаете заранее, сколько раз должен выполниться цикл, но в отличие от цикла while, он гарантирует, что цикл выполнится хотя бы один раз, даже если условие не будет выполнено с самого начала.
Если вы сомневаетесь, какой тип цикла лучше использовать в вашей конкретной задаче, лучше начать с цикла for. Если вам нужно бесконечно повторять какие-то действия, используйте цикл while или repeat-until. Однако, не забывайте, что для каждого типа цикла необходимо оценить производительность и затраты на ресурсы, такие как память и время выполнения, чтобы выбрать наиболее подходящий тип цикла.






