Циклы

Неотъемлемой частью любой "взрослой" программы являются циклы. В жизненных примерах, вы их найдете в бесчисленных кол-вах.  Вращения земли вокруг своей оси, вращение планет вокруг солнца, смена времен года, и прочее... Как вы наверное поняли циклы - это нечто повторяющееся несколько (много) раз. Вы когда копируете много файлов с одного места на другое, думаю делаете это сразу вместе, а не по одному. Так вот копирование происходит в цикле: сначала копируется первый файл, потом второй , третий и т. д. Представьте себе, что вам надо вывести на экран цифры от 0 до 9  без циклов. Тогда наверно это бы выглядело примерно так:


Dim As Integer A
Print A
A+=1
Print A
A+=1
Print A
A+=1
Print A
A+=1
Print A
A+=1
Print A
A+=1
Print A
A+=1
Print A
A+=1
Print A
A+=1
Print A
Sleep


Не так уж и страшно скажете вы. А что делать, если нужно вывести от 1 до 1000000 ? Писать 2000000 строчек? Конечно же есть более красивое решение-это использовать циклы или подобие их. Когда то на древних бейсиках был способ записи цикла и сейчас я вам его покажу для общего развития:

 Не запускайте!


LABEL:
 '  зима
 '  весна
 '  лето
 '  осень
Goto LABEL


В этом примере для вас новая команда GOTO ( GO TO перейти на с анл.) . Она по сути и делает то, что я написал в скобках: переходит на нужный адрес или метку. Метка (или адрес) в FreeBasic, как вы успели заметить, пишется из имени и завершающего двоеточия. Имя может быть любым, используя правила переменных.  И так пример выше - есть не что иное, как бесконечный цикл - вполне работающая программа, но не надо ее запускать, если не знаете как потом выключить. В данном цикле вся работа происходит между двумя строчками. То есть дойдя до строки  GOTO LABEL , программа перемещает  свое выполнение на строчку LABEL: (метка) и опять выполняются команды, написанные между этими строчками (у нас нет команд, но вместо комментариев можно вписать любые). Циклы хороши только тогда, когда они управляемы! Пример ниже как раз показывает подобное:

Dim As Integer A
LABEL:
    'начало тела цикла
    If  A=100  Then 
        Sleep
        End
    Else 
        Print A
    Endif
    A+=1
    'конец тела цикла
Goto LABEL


В этом примере выводятся на экран цифры от 0 до 99.
 Если вы замените в переменной A значение на 10000 , то уже выведутся цифры от 0 до 9999 . Как видите, чтобы поменять кол-во выведенных надписей, нам достаточно в одном месте поменять цифру. Удобно ? Мне кажется да. Хотя это не самый красивый пример, но мы его разберем. В первой строке мы объявили переменную А . Вторая строка это метка, на которую переносит выполнение программы оператор GOTO. Внутри цикла вы можете увидеть, рассматриваемые в прошлых статьях логические команды, с помощью которых как раз и управляется цикл. Изначально переменная A равна 0 , но в теле цикла, она каждый раз за прохождение цикла(итерацию) , увеличивается на единицу. В условной команде IF постоянно идет проверка на равенство переменной значению 100. Если не достигнуто равенство, тогда печатается значение переменной. Как только равенство будет достигнуто, программа засыпает с помощью команды Sleep и после нажатия вами любой клавиши завершает свою работу.
 Время не стоит на месте и времена GOTO постепенно проходят. Этим оператором пользуются очень редко. Но то что я привел выше, есть примитивная структура любого цикла, на любом языке программирования. А теперь давайте рассмотрим настоящие и реально используемые циклы языка FreeBasic. Начнем с Do - Loop

Do
 '  зима
 '  весна
 '  лето
 '  осень
Loop


Как видите мало чем отличается такая конструкция от  конструкции с оператором GOTO.  Но все же она во много удобна и гибка!  Во первых из нее возможен выход с помощью команды Exit Do. Во вторых  с добавлением дополнительных ключевых команд Until ,  While ,  удобство наглядно видно. Все это мы рассмотрим. Давайте перепишем прошлый пример с помощью этого цикла:

Dim As Integer A
Do
    Print A
    A+=1
Loop Until A=100
Sleep
End


Пример становится более читаем для программиста. В теле цикла выполняются только те команды, которые действительно там необходимы, остальные вынесены за него. Проверка в данном случае идет в конце цикла с помощью ключевой команды UNTIL (буквально означающее ПОКА или ДО). То есть выполнять цикл, пока A не будет равно 100. Но оказывается пример выше можно переписать несколькими способами:

Dim As Integer A
Do Until A=100
    Print A
    A+=1
Loop 
Sleep
End


Программа выведет на экран тоже самое. Разница у этих способов в том, что в первом примере заход в цикл происходит по любому и прохождение по циклу будет хотя бы один раз. А в последнем примере сравнение идет в начале. И если команда Until найдет результат истинным,то не будет ни одного прохождения по телу цикла:

Пример1:

Dim As Integer A
Do
    Print A
    A+=1
Loop Until A>=0
Sleep
End 


пример2:

Dim As Integer A
Do Until A>=0
    Print A
    A+=1
Loop 
Sleep
End


Теперь можно рассмотреть ключевую команду While.  Эта команда противоположна Until.
 Команда Until  дает работать циклу до тех пор пока условие не достигнуто. Команда же While дает работать циклу, при условии что условие истинно.

 Пример1:

Dim As Integer A
Do While A = 0
    Print A
    A+=1
Loop
Sleep
End 


Пример2:

Dim As Integer A
Do While A = 10
    Print A
    A+=1
Loop
Sleep
End 


Как вы могли заметить в первом случае команда While возвратила истину, поскольку A=0, но после первого прохождения цикла, A стало равно 1 и цикл прервался. Что касается второго примера, то результат сразу неверный и  команда While даже не дала войти в цикл. Команду While как и команду Until можно записать в конец цикла "в помошь" к команде Loop:

Dim As Integer A
Do 
    Print A
    A+=1
Loop While A <>100
Sleep
End


Но можно записать команду While и без Do-Loop. Есть такая конструкция While - Wend , которая встречается на многих диалектах бейсика, и даже есть подобный макрос на ассемблере.  Пример переписанный с помощью этой конструкции:

Dim As Integer A
While A <>100
    Print A
    A+=1
Wend 
Sleep
End


Все тоже самое ,  выполняется цикл пока A не равно 100.
Есть еще одна очень полезная и мощная конструкция цикла FOR-NEXT. Этот цикл имеет свой определяемый счетчик и конечно выполняется ровно столько, на сколько заведен этот счетчик:

For A As Integer=0 To 99
    Print A
Next A
Sleep
End 


Здесь мы опять встретили нашу знакомую команду TO,  которая говорит нам о диапазоне значений.   Команда FOR  начинает цикл . Но ей для счетчика нужна переменная, которую она будет проверять на достижение конца диапазона, установленного нами. Команда NEXT увеличивает счетчик(переменную А) на единицу. Вообще говоря, увеличение на единицу происходит только по умолчанию. Но мы можем увеличивать на любую величину наш счетчик с помощью команды STEP (шаг):

For A As Integer=0 To 99 Step 5
    Print A
Next A
Sleep
End 


Собственно говоря, записывать имя переменной после команды NEXT не обязательно и я так не делаю в своих программах, хотя кому то так понятнее.
Существуют еще так называемые вложенные циклы. Вы будете их применять частенько. Принцип у них не сложный. Самое главное понять , что внутренний цикл  вращается во внешнем. Так если внутренний должен выполняться 5 раз , а внешний 10, то общее прохождение внутреннего увеличивается в 10 раз .

Пример:

For A As Integer =1 To 10
    For B As Integer=1 To 5
        Print  "B"
    Next B
    Print  "AAAAAAAAAA"
Next A
Sleep
End 


В этом примере программа заходит во внешний цикл A и сразу же попадает во внутренний цикл B.  Пока цикл B не отработает, программа не выйдет во внешний цикл. К примеру отработал внутренний цикл В и вывел в окно консоли надпись "B" пять раз ,  программа попадает во внешний цикл A который должен выполнится  10 раз.  Поэтому внутренний запускается 10 раз и выводит свою надпись 10*5=50  раз. А мы видим в окне консоли кучу надписей, специально мной разделенных надписью "AAAAAAAAAA", при каждом прохождении внешнего цикла.
 Я уже упоминал о возможном преждевременном выходе из цикла с помощью команды EXIT . Принцип синтаксиса этой команды для всех циклических команд один: сначала идет завершающая команда Exit, а потом имя цикла. Пример:

For A As Integer =0 To 99
    Print A
    If  A=10 Then
        Exit  For
    Endif
Next A
Sleep
End 


Как видите, мы здесь вывели только 10 чисел и преждевременно завершили цикл. Конечно этот пример в полной мере не может показать полезность команды Exit , но вы должны понимать, что любая программа, будь то PhotoShop или NotePad,  для того чтобы работать, ее выполнение зацикливается с множеством встроенных реализационных команд в этом цикле, и как только пользователь нажмет на выход, как раз срабатывает подобный преждевременный выход из цикла(ов).  Пример выхода из вложенных циклов :

Var a=0 , b=0
While a <>1
    While b<>10000
        If b>=20 Then
            Exit While , While 
        Endif
        b+=1
        Print b
    Wend
    A+=1
Wend
Sleep


Пример выше показывает как можно выходить из двух вложенных циклов сразу. Единственно, что тут: имена циклов должны быть одинаковы. То есть если у вас первый цикл For-Next , а второй Do-Loop , то данным способом воспользоваться нельзя (по крайней мере, пока разработчики это не реализовали). А одноименные пожалуйста

 EXIT For, For, For  - для трех циклов

 EXIT Do, Do, Do, Do, Do    -  для пяти циклов


Иногда может потребоваться не выход из цикла а пропуск одной из его итераций (прохождения) . Для этого в FreeBasic существует команда  Continue

Var b=0
While b<>10
    b+=1
    If b=5 Then
        Continue While
    Endif 
    Print b
Wend
Sleep 


Как и в случае с командой Exit , синтаксис команды Continue такой же:  пишется сама команда, затем имя цикла. В примере видно, что цикл не работал один раз (пропускал) и в итоге в окне консоли мы не увидели цифру 5 среди других цифр от 1 до 10 . 

Вот собственно то, что я хотел рассказать в этой статье. Всего доброго!

содержание | назад | вперед