Перейти к основному содержимому

5.16. Управляющие конструкции и операторы

Разработчику Архитектору

Управляющие конструкции и операторы

Fortran — один из старейших языков программирования, созданный для научных и инженерных вычислений. Несмотря на возраст, он продолжает развиваться, сохраняя при этом чёткую структуру и предсказуемое поведение. Современные версии Fortran, начиная с Fortran 90, предоставляют разработчику мощные средства управления потоком выполнения программы. Эти средства выражаются через управляющие конструкции: условные ветвления и циклы. Они позволяют программе принимать решения на основе данных и многократно выполнять одни и те же действия, что составляет основу любого алгоритма.

Условные конструкции: IF-THEN-ELSE

В Fortran условное выполнение кода реализуется с помощью конструкции IF. Эта конструкция позволяет программе выбирать, какие действия выполнять, в зависимости от истинности логического выражения. Логическое выражение — это утверждение, которое может быть либо истинным, либо ложным. В Fortran такие выражения строятся с использованием операторов сравнения и логических операторов.

Современный синтаксис условной конструкции в Fortran 90 и последующих стандартах использует явные завершающие операторы END IF. Это делает структуру кода прозрачной и легко читаемой. Конструкция IF-THEN-ELSE состоит из трёх частей:

  • блока IF, в котором проверяется условие;
  • необязательного блока THEN, который выполняется, если условие истинно;
  • необязательного блока ELSE, который выполняется, если условие ложно;
  • завершающего оператора END IF.

Простейшая форма выглядит так:

IF (логическое_выражение) THEN
! действия, если условие истинно
END IF

Если требуется предусмотреть альтернативное поведение при ложном условии, используется полная форма:

IF (логическое_выражение) THEN
! действия, если условие истинно
ELSE
! действия, если условие ложно
END IF

Fortran также поддерживает многоуровневые ветвления с помощью конструкции ELSE IF. Это позволяет проверять несколько условий последовательно:

IF (условие1) THEN
! действия при условии1
ELSE IF (условие2) THEN
! действия при условии2
ELSE IF (условие3) THEN
! действия при условии3
ELSE
! действия, если ни одно условие не выполнено
END IF

Каждый блок ELSE IF проверяется только в том случае, если все предыдущие условия оказались ложными. Такой подход обеспечивает чёткую иерархию проверок и исключает неоднозначность.

Важно отметить, что логическое выражение в скобках после IF обязано возвращать значение типа LOGICAL. Это достигается с помощью операторов сравнения (==, /=, <, <=, >, >=) и логических операторов (.AND., .OR., .NOT.). Например, выражение (x > 0 .AND. y < 10) будет истинным только тогда, когда оба подусловия выполняются одновременно.

Циклы: DO и DO WHILE

Циклы в Fortran позволяют повторять выполнение блока кода заданное количество раз или до тех пор, пока выполняется определённое условие. Fortran предоставляет два основных типа циклов: цикл с счётчиком (DO) и цикл с предусловием (DO WHILE).

Цикл с счётчиком: DO

Цикл DO используется, когда известно точное количество повторений. Он управляет выполнением с помощью переменной-счётчика, которая автоматически изменяется на каждом шаге. Синтаксис цикла с счётчиком в современном Fortran выглядит следующим образом:

DO переменная = начальное_значение, конечное_значение [, шаг]
! тело цикла
END DO

Здесь:

  • переменная — целочисленная переменная, которая служит счётчиком;
  • начальное_значение — значение, с которого начинается счёт;
  • конечное_значение — значение, до которого продолжается счёт;
  • шаг — необязательный параметр, указывающий, на сколько увеличивается счётчик на каждой итерации. Если шаг не указан, он по умолчанию равен единице.

Пример:

DO i = 1, 10
PRINT *, 'Итерация номер', i
END DO

Этот цикл выполнится десять раз, выводя на экран номер каждой итерации. Переменная i принимает значения от 1 до 10 включительно.

Цикл DO гарантирует, что тело цикла выполнится хотя бы один раз, если начальное значение не превышает конечное (при положительном шаге). Если начальное значение больше конечного, а шаг положителен, цикл не выполнится ни разу. Аналогично, при отрицательном шаге цикл выполняется, только если начальное значение больше или равно конечному.

Fortran запрещает изменение переменной-счётчика внутри тела цикла. Это правило обеспечивает предсказуемость и безопасность выполнения. Любая попытка присвоить новое значение счётчику приведёт к ошибке компиляции или неопределённому поведению.

Цикл с предусловием: DO WHILE

Цикл DO WHILE используется, когда количество повторений заранее неизвестно, но известно условие, при котором цикл должен продолжаться. Этот цикл проверяет логическое выражение перед каждой итерацией. Если выражение истинно, тело цикла выполняется. Если ложно — выполнение цикла прекращается, и программа переходит к следующему оператору после END DO.

Синтаксис:

DO WHILE (логическое_выражение)
! тело цикла
END DO

Пример:

count = 0
value = 1.0
DO WHILE (value > 0.001)
value = value / 2.0
count = count + 1
END DO
PRINT *, 'Потребовалось', count, 'делений'

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

Цикл DO WHILE требует особой внимательности при проектировании. Если условие никогда не станет ложным, программа зациклится. Чтобы избежать бесконечного выполнения, необходимо гарантировать, что переменные, участвующие в условии, изменяются внутри тела цикла таким образом, чтобы условие рано или поздно стало ложным.

Завершение и переход внутри циклов

Fortran предоставляет два оператора для управления выполнением циклов: EXIT и CYCLE.

Оператор EXIT немедленно прекращает выполнение текущего цикла и передаёт управление первому оператору после END DO. Он часто используется внутри условного блока, когда дальнейшие итерации становятся бессмысленными.

Оператор CYCLE прерывает текущую итерацию и немедленно переходит к проверке условия (в случае DO WHILE) или к следующему значению счётчика (в случае DO). Это позволяет пропустить часть тела цикла при определённых условиях, не прерывая сам цикл.

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


Операторы в Fortran

Операторы — это символы или ключевые слова, которые указывают компилятору выполнить определённое действие над данными. Fortran предоставляет богатый набор операторов, разделённых на категории: арифметические, логические, операторы сравнения и специализированные операторы для работы с массивами. Эти операторы составляют основу вычислений и логики любой программы.

Арифметические операторы

Fortran поддерживает стандартный набор арифметических операций, ориентированных на численные расчёты. Эти операции применяются к числовым типам данных: целым (INTEGER) и вещественным (REAL, DOUBLE PRECISION).

Основные арифметические операторы:

  • + — сложение;
  • - — вычитание;
  • * — умножение;
  • / — деление;
  • ** — возведение в степень.

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

Особое внимание в Fortran уделяется типу результата операции. Если оба операнда целочисленные, результат деления будет также целочисленным, и дробная часть отбрасывается. Например, выражение 7 / 2 даёт результат 3, а не 3.5. Чтобы получить вещественный результат, хотя бы один из операндов должен быть вещественного типа: 7.0 / 2 или REAL(7) / 2.

Оператор возведения в степень ** допускает как целые, так и вещественные показатели. Он особенно полезен в научных вычислениях, где часто встречаются степенные зависимости и экспоненциальные функции.

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

Операторы сравнения используются для построения логических выражений. Они сравнивают два значения одного типа и возвращают результат типа LOGICAL — либо .TRUE., либо .FALSE..

Fortran предоставляет следующие операторы сравнения:

  • == — равно;
  • /= — не равно;
  • < — меньше;
  • <= — меньше или равно;
  • > — больше;
  • >= — больше или равно.

Эти операторы применимы к числовым типам и к строкам. При сравнении строк используется лексикографический порядок, основанный на кодах символов (обычно ASCII). Сравнение строк происходит посимвольно слева направо до первого различия.

Операторы сравнения являются основой условных конструкций и циклов с предусловием. Без них невозможно реализовать принятие решений на основе данных.

Логические операторы

Логические операторы позволяют комбинировать несколько логических выражений в одно сложное. Они работают исключительно с данными типа LOGICAL.

Основные логические операторы в Fortran:

  • .AND. — логическое И: результат истинен, только если оба операнда истинны;
  • .OR. — логическое ИЛИ: результат истинен, если хотя бы один из операндов истинен;
  • .NOT. — логическое НЕ: инвертирует значение операнда;
  • .EQV. — эквивалентность: результат истинен, если оба операнда имеют одинаковое логическое значение;
  • .NEQV. — неэквивалентность: результат истинен, если операнды имеют разные логические значения.

Операторы .AND. и .OR. оцениваются слева направо. Fortran не гарантирует «ленивую» оценку (short-circuit evaluation), то есть оба операнда всегда вычисляются, даже если результат уже определён первым. Это важно учитывать при написании выражений, где второе условие может вызвать ошибку (например, деление на ноль или выход за границы массива).

Оператор .NOT. имеет самый высокий приоритет среди логических операторов, затем следуют .AND., .OR., и, наконец, .EQV. и .NEQV.. При необходимости порядок можно контролировать с помощью скобок.

Операции с массивами

Одна из сильнейших сторон Fortran — встроенная поддержка многомерных массивов и операций над ними. Массивы могут быть одномерными, двумерными и выше, с произвольными границами индексов. Fortran позволяет выполнять арифметические и логические операции над целыми массивами или их сечениями без явного использования циклов.

Например, если объявлены два массива A и B одинакового размера, выражение:

C = A + B

автоматически выполняет поэлементное сложение всех соответствующих элементов массивов A и B, сохраняя результат в массив C. То же самое применимо к другим арифметическим операторам: *, -, /, **.

Аналогично, логические операторы и операторы сравнения могут применяться к массивам. Результатом будет массив логических значений. Например:

mask = (A > 0.0)

создаст логический массив mask, в котором каждый элемент будет .TRUE., если соответствующий элемент A положителен, и .FALSE. в противном случае.

Fortran также предоставляет встроенные функции для работы с массивами, такие как SUM, PRODUCT, MAXVAL, MINVAL, ANY, ALL. Эти функции позволяют получать сводную информацию о массиве без написания явных циклов. Например, SUM(A) возвращает сумму всех элементов массива A, а ANY(A > 0.0) возвращает .TRUE., если хотя бы один элемент массива A положителен.

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

Сечения массивов (array sections) — ещё один мощный инструмент. Они позволяют обращаться к части массива, указывая диапазон индексов. Например, A(2:5) означает подмассив из элементов с индексами от 2 до 5 включительно. Сечения можно использовать в левой и правой части присваивания, в вызовах функций, в логических выражениях. Это делает манипуляции с данными гибкими и выразительными.