next up previous contents
След.: Упражнение Выше: Выражения и присваивания Пред.: Упражнение   Содержание


Оператор и конструкция FORALL

Осуществляет множественные присваивания. В чем-то она аналогична циклу, но действует иначе: сначала производятся все вычисления в правой части и затем осуществляются присваивания в неопределенном порядке (возможно, параллельно). Так, если один и тот же массив присутствует и в левой, и в правой части присваивания, то в цикле изменения, вносимые на первой итерации могут менять результат второй, а FORALL это исключает. Синтаксис оператора:

FORALL(I = I0:I1[:dI] [, логическая маска]) присваивание.

Синтаксис конструкции:

[имя:]FORALL([тип::]I = I0:I1[:dI] [, логическая маска])

операторы присваивания

END FORALL [имя]

Идентификатор счетчика, разумеется, может быть любой, переменная целочисленного типа. Их может быть больше одного. Счетчики локальны для конструкции -- не влияют на одноименные переменные вне ее. Диапазон задается индексным триплетом. Возможно задание маски логическим выражением (его результат должен быть логическим массивом той же конфигурации, что и массив в левой части присваивания). Операторы присваивания могут быть =, =>, FORALL, WHERE. Возможность указать тип предусмотрена для выбора разновидности (тип целый).

Примеры [14,2]

REAL, DIMENSION(10,10) :: A, B = 1.0

...

FORALL (I = 1:10, J = 1:10, B(I, J) /= 0.0)

A(I, J) = REAL (I + J - 2)

B(I, J) = A(I, J) + B(I, J) * REAL (I * J)

END FORALL

REAL, DIMENSION(10,10) :: A

REAL, DIMENSION(10) :: B

...

FORALL (I = 1:10)

B(I) = A(I,I) !диагональ матрицы;

END FORALL

Отметим, что секции массива могут выделять только прямоугольные подмассивы.

INTEGER, DIMENSION(5):: A = [(I,I=1,5)]

!первые 5 натуральных чисел: [1, 2, 3, 4, 5]

FORALL(I=1,4) A(I+1) = A(I) !Массив A содержит [1, 1, 2, 3, 4]

DO I=1,4

A(I+1) = A(I)

END DO !Массив A содержит теперь только единицы.

В следующей конструкции[14] два оператора присваивания. Присваивание B использует значения A, вычисленные предыдущим оператором, но не те, что были в A ранее:

FORALL (I = 2:N-1, J = 2:N-1, A(I,J) /= 0.0 )

A(I,J) = A(I,J-1) + A(I,J+1) + A(I-1,J) + A(I+1,J)

B(I,J) = 1.0 / A(I,J)

END FORALL

Маска помогает избежать ситуации деления на ноль.

Не допускается многократное присваивание одному и тому же элементу массива. Вложенные конструкции должны иметь различные идентификаторы счетчиков. Много примеров есть в Стандарте [14], приложения C.4.5, C.4.6.



Подсекции

Ilya A. Chernov 2012-12-19
X