В первых двух частях я рассказал, зачем нужны массивы и циклы. Но я описал цикл, из которого нет выхода, и значит он бесполезен. Должно быть что-то ещё, чтобы заставить цикл остановиться в нужный момент.
Представим, что каждый раз, когда цикл должен повториться, мы задаём вопрос – надо его повторять или нет? Если бы у нас была такая возможность, то мы могли бы закончить цикл тогда, когда захотим.
К счаcтью, такая возможность есть. Это ещё одна машинная инструкция, которая может сравнить одно значение с другим и получить результат: больше, меньше, равно. Поэтому мы можем просто считать, сколько раз выполнился цикл. Для этого можно завести переменную-счетчик, и при каждом повторении цикла увеличивать её на 1.
Сейчас я составлю простой цикл, в котором переменная будет увеличиваться на 1. Примечание: я делаю цикл с помощью метки и перехода goto на метку. Это очень примитивная и вредная с точки зрения языков программирования конструкция, настолько вредная, что некоторые языки даже полностью запрещают goto. Как в языках программирования делают нормальные циклы, и почему goto считается вредным, я объясню ниже. Но усвойте навсегда, что можно написать самый красивый цикл на самом красивом языке, а после трансляции в машинный код всё равно получится метка и goto. Просто вы этого не увидите. Сейчас я просто хочу нагляднее показать, как это работает. Поэтому буду использовать пример на языке C.
- Сначала я заведу целочисленную переменную-счетчик, назову её "a" и присвою ей 0. Это будет означать, что цикл пока что повторился 0 раз, то есть ни разу:
int a = 0; - Теперь я поставлю метку, с которой должен повторяться цикл. Это любое имя с двоеточием. Назову её label ("метка").
label: - Затем я напишу тело цикла – то, что должно повторяться. Сейчас в теле цикла я буду просто увеличивать счетчик на 1. Для этого служит операция ++.
a++; - И наконец, я напишу возврат на метку label, чтобы цикл замкнулся.
goto label;
Всё вместе:
Я добился того, чтобы значение a увеличивалось на 1 в цикле. Теперь, если я хочу повторить цикл только 5 раз, мне нужно написать условие. Это условие будет сравнивать a с 5.
if (a < 5) goto label;
"if" значит "если". Такая инструкция используется почти во всех языках программирования. Видели одну – видели все. Написав такую инструкцию, мы получаем следующий результат человеческим языком:
если a < 5, перейди на метку label.
А если a = 5 или а > 5? Тогда условие не выполняется, перехода на метку не происходит, и программа работает дальше. Ура, мы вышли из цикла!
Мы только что ознакомились с понятием безусловного перехода (goto) и условного перехода (if ... goto). Условный переход выполняется только тогда, когда выполняется заданное условие.
Поздравляю!
Освоив условные и безусловные переходы, вы освоили буквально всё программирование. Хотя в языках программирования есть много модных фишек и плюшек, непосредственно в машинном коде всего этого нет. Есть только условия и переходы. С помощью только условий и переходов вы можете написать ВООБЩЕ ЛЮБУЮ программу.
Однако, посмотрим, как языки организуют циклы без goto. Напишу сразу код, а затем разберу его. Этот код также одинаков для очень большого количества языков, поэтому видели один – видели все.
Здесь появляется инструкция while, которая означает "пока". То есть,
пока a < 5, надо...
Надо что? Надо выполнять то, что написано между фигурными скобками "{ }". Такие скобки служат для объединения нескольких инструкций в один смысловой блок, который или выполняется, или не выполняется целиком. В данном случае в блоке есть только одна инструкция, но это неважно.
Таким образом, весь блок со всем своим содержимым связан с инструкцией while, и целиком зависит от нее.
Нетрудно заметить, что while одновременно заменяет if (так как проверяет условие) и goto (так как сама организует цикл). В данном случае невидимый goto как бы стоит там, где стоит закрывающая скобка "}", и перенаправляет выполнение программы снова на строку с while.
Для сравнения, то же самое можно записать с помощью метки и goto:
Если выполняется условие if, то, как и в предыдущем варианте, выполняется всё, что записано между скобками "{ }". Блок инструкций на этот раз связан с if. Как видим, он будет выполняться, только пока a < 5.
Также замечу на будущее, что расположение скобок не играет роли. Можно написать так:
или так:
Всё это одно и то же.
Кроме цикла while, есть еще циклы for, do, а также т.н. итераторы типа foreach для перебора т.н. коллекций. Все они ничем не отличаются от обычных циклов и служат только для облегчения написания и понимания кода. Поэтому я не буду здесь на них заостряться. Когда понадобятся – тогда и расскажу. Если вы нормально усвоили, что такое цикл, остальные варианты это уже пустяки.
Но почему в языках программирования не приветствуется или вовсе запрещается использовать переходы goto? Просто потому, что такие переходы, если их использовать в большом количестве и как попало, сильно замусоривают код и затрудняют его понимание. То есть путем запрета goto вас заставляют писать понятные и легко отлаживаемые программы. Других причин нет. Однако если вам доведётся писать на языке ассемблера, то у вас там не будет ничего кроме goto, или, по-тамошнему, jmp (jump – прыжок). И там вы сможете оторваться по полной.
Ну, а дальше мы наконец возьмем всех монстров и в цикле обработаем их, как положено. И кроме того, обсудим другие возможности программ.
Читайте дальше: