07 [FreeBASIC] - циклы
Давайте рассмотрим такую задачку - вывести на экран числа от 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

**m1** это метка, куда условный оператор будет перенаправлять ход выполнения программы при выполнении условия что k<=100
## Такая конструкция называется **цикл**
Циклы используются очень часто в программах и для них придумали специальные операторы.
Посмотрим как запишется пердыдущий пример с помощью оператора **цикла FOR...**
`Dim as integer k`
`FOR K=1 TO 100`
`PRINT k;`
`NEXT K`
`SLEEP`

## оператор 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 чисел

Нам понадобятся три переменные: 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

как видите для **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

Во первых вспомните оператор **locate** он принудительно задаёт позицию для последующего вывода симола на экран.
Вначале указываем строку, а затем отступ от левого края. Так как числа в таблице одно-двухциферные плюс ещё один символ на отступ то для вычисления отступа слева мы i*3.
Цикл с переменной j - внутренний, а с i - внешний.
Два

