#10.1 Цикл For в Паскаль. Цикл с известным числом повторений (цикл с параметром). Тело цикла.
Primary tabs
В Паскале можно использовать три конструкции для организации циклов, они известны по именами:
- For
- While
- Repeat
В этом уроке -- мы познакомимся с первый из них -- циклом For.
Цикл For -- схема работы
Цикл For также называют циклом с известным числом повторений.
Он обладает следующей структурой (изобразим её на блок-схеме):
Как видим на схеме, в цикле for имеются:
- Заголовок цикла (шестиугольный блок на схеме выше) -- а котором описывается как именно будет изменяться счётчик цикла (на схеме выше это переменная $i$).
Счетчик цикла -- это специальная переменная (типа integer), для которой на основании правой и левой границы цикл for определяет ряд значений, которые она "проходит" при выполнении цикла.
В примере на схеме в качестве левой и правой границы указаны числа $1$ и $10$, то есть переменная $i$ должна будет "пробежать" по ряду значений:1, 2, 3, 4, 5, 6, 7, 8, 9, 10
-- для каждого из этих значений тело цикла будет повторяться (в данном случае 10 раз). Правая и левая границы всегда должны обладать типом integer.
- Тело цикла -- набор программных действий для, которых заголовок цикла определяет число повторений.
Сразу же приведём пример кода программы, цикл в которой соответствует блок схеме на рисунке выше:
var i, a:integer; begin for i:=1 to 10 do begin // начало тела цикла (у нас в нём будет 3 операции, как на блок-схеме выше) a := i; // получаем очередное значение счётчика (первый раз оно будет равно 1, а последний раз = 10) a := a + 2; // прибавляем к значению 2 write(a, ' '); // выводим с пробелом после значения end; // конец тела цикла readln(); end.
-- здесь в теле программы тоже три операции (но уже конкретные) и тот же диапазон значений счетчика, что и на блок-схеме. Запустите программу и посмотрите на результат.
Далее рассмотрим примеры решения задач, чтобы лучше понять как работает цикл for.
Если правая граница счётчика меньше левой -- downto
Если правая граница для счётчика цикла меньше чем левая то необходимо использовать вместо конструкции:
for i:=<леваяГраница> to <праваяГраница> do
конструкцию:
for i:=<леваяГраница> downto <праваяГраница> do
Разбор практических примеров
Пример №1 - использование значений счетчика
Задача:
Вывести на экран все числа от 1 до 125.
Решение:
var i:integer; begin for i:=1 to 125 do write(i, ' '); // выводим значения счетчика через пробел readln(); end.
-- так как нам нужно было повторять только действие вывода, то в теле цикла мы разместили одну операцию, а потому операторные скобки для тела цикла не нужны.
Пример №2 -- условный оператор внутри цикла
Вывести на экран все нечетные числа от 37 до 1025.
Здесь для решения в сравнении с решением предыдущей задачи просто изменим диапазон значений счетчика и добавим в тело цикла условный оператор с проверкой остатка от деления на $2$:
var i:integer; begin for i:=37 to 1025 do // i пройдёт значения от 37 до 1025 if ((i mod 2) = 1) then // если очередное значение счётчика делится на 2 с остатком write(i, ' '); readln(); end.
-- обратите внимание, что здесь тоже не используются операторные скобки для окружения тела цикла. Дело в том, что вложенным в непосредственно в блок цикл for является только один условный оператор if, а вызов стандартной процедуры write() вложен уже в if, а не непосредственно в for, а потому в данном случае считается, что в теле цикла for находится только одна операция (for) и, следовательно, операторные скобки не обязательны.
Пример №3 -- downto
Задача:
Выведите на экран все число от 133 до 57.
Решение (тут всё просто):
var i: integer; begin for i:=133 downto 57 do write(i, ' '); readln(); end.
Пример №4 -- downto и цикл в одной из веток условного оператора
Задача:
Пользователь вводит целое число, если оно больше $8$ выведите на экран все числа от этого числа до $5$ (в обратном порядке), иначе сообщите об ошибке.
Решение:
var i, a: integer; begin writeln('vvedite celoe chislo'); readln(a); if (a > 8) then for i:=a downto 5 do // цикл вложен в ветку then условного оператора. write(i, ' ') // перед else ';' не ставится else writeln('oshibka! vashe chislo ne > 8.'); readln(); end.
Пример №5 -- условный оператор с составным условием внутри цикла
Задача:
Выведите на экран, все четные числа, делящиеся на 7 нацело, лежащие в диапазоне от 28 до 117.
Решение:
В этой задаче нам необходимо перебрать все числа от 28 до 117 (будем делать это циклом), проверяя каждое число, на соответствие сразу двум условиям:
- является четным -- т.е. по сути делится на 2 нацело;
- делится нацело на 7;
Так оба условия для выводимого числа нужно проверять одновременно (они должны выполняться одновременно-- только тогда его можно выводить), то будем использовать логическое И.
Третье же условие принадлежности диапазону будет гарантировать сам цикл for -- так как мы будем перебирать только числа из этого диапазона, а потом в услвоном операторе проверять его не нужно, в качестве очередного числа используем счетчик цикла:
var i:integer; begin for i:=28 to 117 do // цикл по диапазону [28..117] if ((i mod 2) = 0) AND ((i mod 7) = 0) then write(i, ' '); readln(); end.
Пример №6 -- логические выражения, условия внутри цикла + анализ условия
Задача:
Выведите на экран, все четные числа от 35 до 117 и все числа, делящиеся на $5$ нацело, лежащие в диапазоне от 45 до 178.
Указание: сначала можно решить задачу двумя циклами, но потом перепишите с использованием одного цикла, в теле которого составьте логическое выражение, описывающее подходящие числа (используйте логические операции).
Решение двумя циклами:
Решить двумя циклами проще -- достаточно пройтись по двум числовым "отрезкам" (диапазонам) сначала циклом по диапазону [35..117], а потом по диапазону [45..178]. Внутри тел циклов надо проверять условия, которые написаны в задаче с помощью условного оператора.
Приведём решение:
var i:integer; begin for i:=35 to 117 do // цикл по [35..117] if ((i mod 2) = 0) then // если четное write(i, ' '); writeln(); // перенос строки, чтобы было понятно где начался новый цикл for i:=45 to 178 do // цикл по [45..178] if ((i mod 5) = 0) then // если делится на 5 write(i, ' '); readln(); end.
-- заметьте, что в этом решении числа выводится не по порядку, что не очень хорошо. В следующем решении мы это исправим.
Решение одним циклом:
Чтобы решить задачу одним циклом (используя единственную конструкцию for), нам стоит заметить, что отрезки [35..117], а потом по диапазону [45..178] пересекаются -- так как:
$35 \lt 45 \lt 117 \lt 178$
-- это значит, что мы можем просто перебрать все числа от 35 до 178, и:
- сначала проверяя какому отрезку они принадлежат,
- а потом какое условие требуется для вывода чисел из этого отрезка,
-- вывести только то, что нам нужно.
Приведём код, решающий задачу одним циклом:
var i:integer; begin for i:=35 to 178 do // цикл по диапазону [35..178] begin if ((i >= 35) AND (i <= 117) // если принадлежит отрезку [35..117] AND ((i mod 2) = 0)) then // и если четное write(i, ' '); if ((i >= 45) // если принадлжит отрезку [45..178] AND ((i mod 5) = 0)) then // если делится на 5 write(i, ' '); end; readln(); end.
-- здесь внутри тела цикла стоит два независимых условных оператора, числа при выводе упорядочены, но есть дублирование, так как например 50 и четное и делится на 5 и находится на пересечении диапазонов.
Чтобы избежать дублирование надо сделать так, чтобы для каждого очередного числа из значений $i$ положительно выполнялось максимум одно условие -- тогда очередное значение $i$ либо будет выведено один раз либо не будет выведено вообще.
Поэтому сделаем проверку второго условия, альтернативой на случай неуспеха первого -- для чего введём ветку ложности в первый условный оператор и вложим в неё второй (это потребует совсем незначительных правок):
var i:integer; begin for i:=35 to 178 do // цикл по диапазону [35..178] begin if ((i >= 35) AND (i <= 117) // если принадлежит отрезку [35..117] AND ((i mod 2) = 0)) then // и если четное write(i, ' ') else // если не из [35..117] или не четно if ((i >= 45) // если принадлежит отрезку [45..178] AND ((i mod 5) = 0)) then // и если делится на 5 write(i, ' '); end; readln(); end.
-- заметьте, что во вложенном в else условии проверяется только левая граница диапазона [45..178] -- это связано с тем, что значения $i$ в заголовке цикла итак ограничены сверху числом 178.
Пример №7 -- Цикл внутри веток условного оператора
Задача:
Если переменная a больше 5, то выведите на экран все числа от 1 до 10,
иначе все числа от 12 до 7 в обратном порядке
Возможное решение:
var i, a: integer; begin writeln('Введите значение переменной:'); readln(a); if (a>5) then for i:=1 to 10 do write(i, ' ') else for i:=12 downto 7 do write(i, ' '); readln(); end.
-- для лучшего понимания можно посмотреть видео-разбор этого решения.
Видео-пояснения
Для этого урока есть следующие видео:
- Цикл For, Разбор: заголовок и тело, Примеры - Часть 1
- Разбор для детей и не только: Цикл FOR в Паскале -- Часть 1
Самостоятельная работа
Вопросы
- Зачем нужен цикл for?
- Что такое заголовок цикла?
- Что такое счетчик цикла?
- Что такое тело цикла?
- Переменной $i$ в цикле for левую границу установили в $5$, а правую в $12$ -- сколько раз выполнится цикл?
Задачи
- Выведите на экран, все числа N единиц (число задает пользователь), например, для N=2, должно быть выведено::
11
для N=9, должно быть выведено:
111111111
- Выведите на экран, все числа от 35 до 64.
- Пользователь вводит два целых числа, выведите на экран все числа между ними, причем:
- Если первое меньше второго, то в порядке возрастания, пример консоли:
1 5 ответ: 1 2 3 4 5
- Иначе в порядке убывания, пример консоли:
5 3 ответ: 5 4 3
Проверить решение для пар значений:
10 20
-- должны увидеть все числа от 10 до 20, и для:
20 10
-- все числа от 20 до 10 в обратном порядке
- Если первое меньше второго, то в порядке возрастания, пример консоли:
- Выведите на экран, все четные числа от 35 до 64.
- Пользователь вводит целое число, если оно больше единицы, то выведите на экран все целые числа от этого числа до единицы (в обратном порядке), которые делятся на 5 без остатка. Иначе (если введённое пользователем число не больше единицы) сообщите об ошибке.
- Пользователь вводит целое число, если оно больше 100, то выведите на экран все числа от этого числа до $1$, иначе же все числа от $1$ до этого числа.
Подсказка: в каждой ветке условного оператора тут должно быть по одному циклу.
- Выведите на экран, все нечетные числа, делящиеся на 3 нацело, лежащие в диапазоне от 35 до 117.
- Выведите на экран, все четные числа от 35 до 117 и нечетные числа, лежащие в диапазоне от 45 до 99.
Указание: сначала можно решить задачу двумя циклами, но потом перепишите с использованием одного цикла, в теле которого составьте логическое выражение, описывающее подходящие числа (используйте логические операции). - Выведите на экран, все числа делящиеся на 3 из дипазона от 35 до 117 и нечетные числа, лежащие в диапазоне от 45 до 99.
- Переберите в цикле все числа от 1 до 100, выведите на экран каждое 7-е число.
-
Есть код:
var i, a: integer; begin readln(a); for i:=1 to 10 do if (a>2) then write('*') else write('#'); readln(); end.
-- перепишите его так, чтобы логика программы не изменилась, но количество проверок в теле цикла стало меньше.
Если не получается решить, или для лучшего понимания см. видео-разбор.
- Log in to post comments
- 71540 reads