
- •Lesson 2 Ветвления и циклы
- •Блок-схемы алгоритмов
- •Управляющие операторы
- •Операторы перехода
- •Условный оператор If
- •Оператор If...Then
- •Оператор If...Then...Else
- •Оператор If с тремя и более блоками
- •Переключатель Select
- •Безусловный переход GoTo
- •Операторы Stop и Return
- •Операторы цикла
- •Операторы Exit и Cycle
- •Цикл по переменной
- •Количество повторений цикла по переменной
- •Подробная блок-схема цикла по переменной
- •Цикл Do while
- •Бесконечный цикл
- •Вложенные циклы
- •Неявные циклы
Подробная блок-схема цикла по переменной
Переменная цикла xизменяется по закону арифметической прогрессии. Для демонстрации этого приводится логическая блок-схема, показывающая последовательность выполнения цикла по переменной. Соответствие узлов блок-схемы строкам исходного кода на Фортране установлено с помощью цифр.
|
Do x=xn,xk,step ! (1) блок_do ! (2) Enddo ! (3) . . . ! (4) ! цикл закончен, ! продолжение программы
Пункт (3) включает в себя:
|
Внимание! Из блок-схемы видно, что в цикле по переменной не может произойти зацикливание. Запомним эту его особенность, чтобы сравнить впоследствии с другими разновидностями циклов.
При использовании в программе оператора цикла по переменной следует учитывать следующие правила:
Переменная xизменяется в цикле автоматически, поэтому изменять ее в теле циклазапрещено.
Вход в тело цикла разрешается толькочерез заголовок цикла. При несоблюдении этого правила число повторений цикла kpи переменнаяxне определены.
Не рекомендуется изменять в теле цикла переменные xn, xk,step, хотя это и не повлияет на число повторений уже запущенного цикла.
Существует только две возможности повлиять на работу цикла операторами тела цикла – это операторы ExitиСycle.
Оператор Exit, встретившийся в теле цикла,прерывает цикл, – завершает его досрочно и передает управление первому исполняемому оператору,следующемуза циклом (4).
Оператор Сycleв теле цикла (2) прерывает выполнение текущей итерации. При этом операторы, расположенные междуCycleи Enddoне выполняются. Происходит переход к изменению переменныхxиk (3) для следующей итерации;
При нормальном завершении цикла переменная xдостигает значения x = xn + step *kp, а при досрочном выходе сохраняется достигнутое значениеxиз интервала [xn,xk].
Примечание. Цикл повещественнойпеременнойxимеет неустойчивый характер. При некоторых соотношениях параметров циклаxn, xk, stepможет не выполниться итерация цикла дляx = xk (последняя итерация). Причины:
ошибка округления при вычислении количества повторений kp;
накопление погрешности округления при изменении переменной цикла (x=x+step), особенно если шагstepсравнительно мал по отношению кx.
Чтобы избежать этого, возможны варианты:
заменить цикл по вещественнойпеременной циклом поцелойпеременнойinta. Перед циклом придется добавить оператор вычисления количества повторений цикла kp, а в цикле перед каждой итерацией вычислитьxчерез inta. Значение целой переменной inta будет точным, переменнаяxне будет накапливать погрешность, хотя разовая погрешность сохранится.
Integer inta, kp; real x
kp = . . . ! формула количества повторений цикла
Do inta = 0, kp-1 ! kp – число повторений цикла
x = xn + inta * step
. . . ! содержимое прежнего блока_do
Enddo
«подправить» цикл по вещественной переменной, увеличив конечное значение на полшага:
Do x = xn, xk + step/2, step
Конечное значение изменилось и теперь равно xk+step/2.
Примеры циклов по переменной.
Пример 1
Вывести на экран все числа, кратные трем, от 30 до 3 (в обратном порядке)
|
Do k=30,3,-3 Write(*,*) k Enddo |
Пример 2 (использование оператора Exit)
Подсчитать сумму квадратных корней из 30 чисел, вводимых с клавиатуры. После ввода отрицательного числа прекратить суммирование, сообщить об ошибке и вывести количество просуммированных чисел. По окончании цикла вывести полученную сумму.
Integer:: k; Real:: x, summa=0
Do k=1,30
Read(*,*) x
If (x<0) then
Write(*,*) ‘ ошибка, k=’, k-1
Exit
Endif
summa = summa + sqrt(x)
Enddo
Write(*,*) ‘summa=’, summa
Пример 3 (использование оператора Cycle)
Последовательно ввести с клавиатуры 30 чисел. Подсчитать сумму и количество квадратных корней из неотрицательныхчисел. Отрицательные числа игнорировать, по окончании цикла вывести сумму и количество просуммированных чисел.
Integer:: k, count=0; real:: x, summa=0
Do k=1,30
Read(*,*) x
If (x<0) cycle
summa = summa + sqrt(x)
count = count+1
Enddo
Write(*,*) ‘summa=’, summa, ‘ , count=’, count