07 [FreeBASIC] - циклы

F
freebs
Давайте рассмотрим такую задачку - вывести на экран числа от 1 до 10. Скажете нет ничего проще - `print 1;2;3;4;5;6;7;8;9;10` А если от 1 до 100, а до 1000? В предыдущем уроке вы увидели, что программа может некоторые действия выполнять, а некоторые нет, в зависимости от условий(оператор **IF**). А бывает так, что некоторые действия порой приходится выполнять многократно. http://ipic.su/img/img7/fs/freebas556.1529100937.jpg Есть один оператор, который присутствует во многих языках программирования, но которым категорически не советуют пользоваться - это **GOTO**. Я также воспользуюсь им лишь здесь. В старых версиях бейсика, где строки нумеровались - 10, 20, 30, 40... оператор `GOTO 20` говорил программе что нужно изменить последовательный ход выполнения программы и перейти на команду что записана в строке 20 и далее исполнять все последующие команды. В последующих версиях, когда строки перестали нумеровать, чтобы воспользоваться оператором GOTO следует в начале строки, куда должен быть осуществлён переход, написать метку и завершить метку двоеточием(`:`). Метки присутствуют и в других языках - Pascal, C/C++... но их использование считается дурным тоном(ведь за ними последует **goto**), и их стараются избегать. Давайте посмотрим как быдет выглядеть решение печати чисел от 1 до 100 ![](https://i.imgur.com/k8byDHx.png) **m1** это метка, куда условный оператор будет перенаправлять ход выполнения программы при выполнении условия что k<=100 ## Такая конструкция называется **цикл** Циклы используются очень часто в программах и для них придумали специальные операторы. Посмотрим как запишется пердыдущий пример с помощью оператора **цикла FOR...** `Dim as integer k` `FOR K=1 TO 100` `PRINT k;` `NEXT K` `SLEEP` ![](https://i.imgur.com/2xEwhBq.png) ## оператор FOR - это цикл со счётчиком в `K=1` задаётся начальное значение и цикл крутится до 100 ('TO 100') Цикл прекратится если K>100, но как же оно станет больше ста, если оно, K, нигде не увеличивается? А увеличивет его NEXT. NEXT служит как бы концом оператора цикла, а всё что между FOR и NEXT называется телом цикла. В бейсике можно задать шаг изменения переменной цикла, в нашем случае K. Строка инициализации цикла тогда запишется так: `FOR K=1 TO 100 STEP 2` Здесь мы задали шаг приращения переменой цикла равный двум. `Оператор NEXT K` неявно выглядит так `K=K+2` Шаг может быть и не целым, и даже отрицательным. Например FOR K=100 TO 1 STEP -1 PRINT k; NEXT K SLEEP напечатает числа от 100 до 1 *Изменять переменную цикла внутри цикла нельзя!!! Считается дурным тоном, как и использование GOTO.* Но не всегда заранее известно сколько раз будет выполняться цикл - здесь вместо цикла со счётчиком есть цикл с условием. Есть **цикл с предусловием** - условие стоит в начале цикла, далее идёт тело цикла. Такой цикл может и не выполнится ни разу, если условие сразу будет ложным. **Do While** *условие* *тело цикла* **Loop** Есть **цикл с постусловием** - условие стоит в конце цикла, после тела цикла. Такой цикл выполнится как минимум один раз. **Do** *тело цикла* **Loop While** *условие* один проход(шаг) цикла называется итерацией. ## Есть ещё два оператора для управления циклами. **Exit** прерывает цикл и передаёт управление на команду что идёт за циклом(досрочный выход из цикла) **Continue** прерывает текущую итерацию и передаёт управление на начало цикла(переход к следующей итерации) ## Рассмотрим несколько примеров - задач на циклы ### Найти сумму первых N чисел ![](https://i.imgur.com/2y1XnjW.png) Нам понадобятся три переменные: k-переменная цикла, N-количество чисел суммы которых мы будем искать, s-для вычисления суммы - *строка 4* справиваем количество чисел которые нужно просуммировать и заносим это число в переменую N - *строка 5* подготоваливаем переменную для накопления суммы - обнуляем. В данном случае в переменой s и так будет 0, но в других языках, в другом месте, в другое время это может быть и не так. Поэтому переменные нужно обнулять перед использованием - *строка 6* начинаем цикл с 1 до N - *строка 7* к имеющемуся значению переменной s добавляем очередное число k. На первой итерации у нас s=0, k=1 получим s=0+1. На втором проходе цикла у нас s=1, k=2 получим s=1+2. На третьем - s=3, k=3 получим s=3+3, и т.д. - *строка 8* Конец тела цикла - оператор NEXT - *строка 9* здесь при каждой итерации переменная цикла (k) уеличивается на шаг цикла (сейчас 1) и проверяется условие для изменившегося k... и при k=101 условие *строки 7* не выполняется - текущее значение k(101) больше конечного значения(100). Цикл прекращается и программа переходит к исполнению *строки 10* *строка 10* выводит на экран вычисленную сумму ## Напечатать чётные числа от 1 до 100 решение можно записать одной строкой `FOR i=2 to 100 step 2:PRINT i;:NEXT i` но я хочу продемонстрировать работу **continue** Dim as integer i For i=1 to 100 if (i mod 2)<>0 then continue for print i; next i sleep ![](https://i.imgur.com/BrmmKih.png) как видите для **continue** (и **EXIT**) нужно указывать какой цикл прервать - **continue for** А если циклы вложенные и нужно прервать оба - **continue for, for** переменнная **i** пробегает в цикле все значения от 1 до 100, но условием *если остаток от деления числа* **i** *на 2 не равен нолю* то мы это значение пропускаем и переходим к следующему значению переменной цикла, к следующей итерации. Обратите внимание как записывется "не равно" - `<>` или так `><` ## Напечатать таблицу умножения 10х10 dim as integer i,j for i=1 to 10 for j=1 to 10 locate j,i*3 print i*j next j next i ![](https://i.imgur.com/r7UUwW7.png) Во первых вспомните оператор **locate** он принудительно задаёт позицию для последующего вывода симола на экран. Вначале указываем строку, а затем отступ от левого края. Так как числа в таблице одно-двухциферные плюс ещё один символ на отступ то для вычисления отступа слева мы i*3. Цикл с переменной j - внутренний, а с i - внешний. Два

Comments