Оператор цикла

При составлении алгоритмов решения разных задач часто возникает необходимость выполнения итераций – повторного выполнения некоторых действий (операторов) до достижения некоторого условия. Примеры таких задач:

Рассмотрим алгоритм решения первой задачи: Суть решения сводится к повторению группы операторов (3-6) несколько раз. Это называется циклом. Циклом называется непрерывная группа последовательных операторов, заканчивающаяся командой перехода (передачи управления) на начало этой части. То есть, основным свойством цикла является многократное выполнение некоторой группы операторов. При этом компьютер должен выполнить одни и те же действия над разными данными. Очевидно, что цикл можно осуществлять с помощью оператора go to, но это некрасиво.


	implicit none
	real a,b,x,y,h
	integer n
 
	 print *,'enter a,b,n'
	 read *,a,b,n
	 h=(b-a)/(n+1)
	 x=a
1    y=sin(x) 
     print *,'x=',x,'y=',y                 
     x=x+h                                   
     if (x<=b) goto 1                   
end






ц
и
к
л

Для выполнения итераций в языке FORTRAN введена специальная конструкция – цикл.

Существует несколько различных форм циклов.

1) Делать n раз     do со счетчиком
{
  действия
}
2) Делать пока (условие)       do while(условие)
{
  действия
}
В разных языках программирования можно встретить разные модификации цикла.

С использованием оператора цикла предыдущий пример можно записать следующим образом:

implicit  none
real a,b,x,y,h
integer  n
print*,'enter a,b,n'
read*,a,b,n
 h=(b-a)/(n+1)
 x=a
 do while(x<=b)                       | начало цикла
   y=sin(x)                                 |
   print *,'x=',x,'y=',y                               |
   x=x+h                                   |
 end do                                     | конец цикла
end
 
Рассмотрим другую задачу: надо 10 раз прибавить к переменной a число 1.
 Вариант программы без оператора цикла:
integer :: a=0
1 a=a+1
  print *,a
  if (a<10) goto 1
end

В этом примере 10 раз повторяются следующие операторы:

Вариант с использованием оператора цикла:

 
integer :: a=0
do a=1,10  повторять до end do c одновременным изменением a от 1 до 10
      print *,a
end do

Часть программы (группа последовательных операторов), заканчивающаяся командой перехода (передачи управления) на начало этой части, называется циклом.

DO

Конструкция DO управляет повторяющимся выполнением блока операторов или конструкций. (This repeated execution is called a loop.)
Существует 3 формы конструкции do:

1.      Бесконечный цикл

do

[операторы]

end do

2.      Со счетчиком

do v=exp1,exp2[,exp3]

[операторы]

end do

3.      C предусловием

do while (logical_expr)

[операторы]

end do


Формально эти формы описываются так:

Блочная форма:

[name:] DO [label[, ] ] [loop-control]
     block
[label] term-stmt

Пример:

 a=-10

 do i=1,10

 a=a+2

print *,i,a

 end do

Цикл состоит в выполнении 2-ух операторов до оператора end do (оператора присваивания и печати). На экране появятся числа

 1 -8.000000

 2 -6.000000

 3 -4.000000

 4 -2.000000

 5 0.0000000E+00

 6 2.000000

 7 4.000000

 8 6.000000

 9 8.000000

 10 10.00000

 

Не_блочная форма: (не рекомендуется)

 DO label[,] [loop-control]

Пример, эквивалентный предыдущему:

 a=-10

 do 5, i=1,10

 a=a+2

5 print *,i,a

цикл состоит в выполнении 2-ух операторов до помеченного меткой 5 (оператора присваивания и печати).

 

name
(Optional) Is the name of the DO construct.

label - (Optional) метка для обозначения последнего оператора цикла

loop-control – управление итерациями

block – последовательность из 0 или более операторов или конструкций

term-stmt – последний оператор конструкции

 

loop-controlили

do-var = expr1, expr2 [, expr3]

или WHILE(expr)

Обратите внимание, что контроль цикла может отсутствовать, тогда цикл бесконечный!

 Далее рассмотрим особенности цикла со счетчиком.

do-var - имя скалярной переменной типа integer. НЕ МОЖЕТ быть элементом массива или членом структуры. Называется переменной цикла. (В старом стандарте допускались переменные вещественного типа)

expr – скалярное выражение типа integer. Если тип не совпадает с do-var, оно преобразуется к нужному типу.

 

expr1 – начальное значение переменной

 expr2 - конечное

 expr3 - шаг

 

Последовательность выполнения цикла:

Инициализация цикла (или выполнение оператора DO)

Вычисляются значения выражений expr1, expr2, and expr3.

Шаг expr3 не обязателен и НЕ МОЖЕТ быть равен 0. Если не задан, принимается  равным 1.

Переменная цикла (do-var) становится равной нач. значению (expr1).

кол-во итераций подсчитывается по сл. формуле

      MAX(INT((expr2 - expr1 + expr3)/expr3), 0)
   

Кол-во итераций ==0, если:

      expr1 > expr2 and expr3 > 0
      expr1 < expr2 and expr3 < 0
   

Проверка количества повторений цикла. Если кол-во повторений равно 0, то выполнение прекращается.

Выполняется block - блок операций внутри цикла.

Выполнение оператора END DO приводит к следующим операциям:

Кол-во повторений уменьшается на 1, а переменная цикла изменяется на величину шага.

Переход к пункту 4.

 

После выполнения цикла переменная цикла сохраняет свое последнее значение. Обратите внимание, что оно обычно, больше expr2. НЕЛЬЗЯ явно менять значения переменной цикла внутри цикла, но можно ее использовать в любых выражениях. Изменение переменных, стоящих в expr1,expr2, expr3 в процессе выполнения цикла не влияют на контроль кол-ва итераций – оно уже определено!

n=5

do i=1,n

 read (*,*) i !!! syntax error !!!

 i=i+1 !!! syntax error !!!

 a=i/2 !!! warning !!!возможна потеря точности, если i – integer

 n=10 количество повторений цикла остается = 5 !

end do

 

Цикл с конструкцией WHILE

Сразу отмечу, что эта форма цикла всегда может быть заменена на бесконечную и, поэтому, считается устаревшей.

Если контроль цикла имеет форму [ , ] WHILE (scalar_logical_expr), это равнозначно бесконечному циклу, если первым оператором внутри цикла стоит:

IF (.NOT. (scalar_logical_expr )) EXIT

Пример

Условие: Складывать числа, пока их сумма не достигнет 100. Числа задает пользователь.

Задача напоминает сбор яблок в корзину. Пока вес корзины не превысит заданного (100) складывать яблоки в корзину. Поэтому введем переменную – корзину, для суммы чисел - s. Вводимые числа –яблоки – переменная x. Алгоритм – пока (сумма яблок <100) брать очередное яблоко; добавлять яблоко в корзину.

 

integer a

s=0

do while(s<100) ! пока (сумма яблок <100)

 print *,'enter number' !

 read *,a ! брать очередное яблоко

 s=s+a ! добавлять яблоко в корзину

end do

 

 

Конструкция DO заканчивается или END DO или оператором с той меткой, которая стоит после DO. Если метки нет, то цикл закрывается только оператором END DO.

Не блочный (с меткой) DO не может заканчиваться одним из сл. операторов:

Arithmetic IF

.NOTE. Не_блочный (с меткой) DO признан устаревшим.

 

 

Вложенные циклы.

Do

 

 Do

 

 End do

 

do

…. 

End do

….

End do

Недопускается пересечение границ вложенных циклов.

Не блочные циклы могут заканчиваться на одном и том же операторе с общей меткой, а вот end do для каждого должен быть свой.

 

Do 5 ….

 Do 5….

 ….

5 continue

 

Пример:

do i=1,3

 do j=1,5

 print *,i,j

 end do

end do

end

В результате на экране:

 1 1

 1 2

 1 3

 1 4

 1 5

 2 1

 2 2

 2 3

 2 4

 2 5

 3 1

 3 2

 3 3

 3  4

 3 5

 

примечание

Пара слов по поводу кол-ва повторений цикла.

do i=0,10,2 сколько раз будет выполняться?

Ответ: 6 раз, т.к. интервалов 5, а концов у интервалов – 6! Не путайте!

 

Examples

 

Бесконечный цикл:

Character n

  DO
    READ *, N
    IF (N == ‘e’) STOP
    Print *,N
  END DO

Выполняется, пока не введен символ «е».

 

 

Не блочный с общим оператором конца

     DO 20 I = 1, N
     DO 20 J = 1 + I, N
  20 RESULT(I,J) = 1.0 / REAL(I + J)
 
 

The following two program fragments are also examples of DO statements:

  C   Инициализация массива четными числами
  C
      DIMENSION array(20)
      DO j = 2, 20, 2
        array(j) = 12.0
      END DO
  C
 
Выполнение функции 11 раз
      DO k = -30, -60, -3
        int = j / 3
        print *, sin (int)
      END DO
 

Последнее значение переменной цикла - ?

    DO j = 1, 10
      WRITE (*, '(I5)') j
    END DO
    WRITE (*, '(I5)') j
(ответ - 11)
НА ГЛАВНУЮ ДАЛЕЕ
Hosted by uCoz