Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
современный фортран , Бортеньев.pdf
Скачиваний:
242
Добавлен:
26.03.2015
Размер:
2.34 Mб
Скачать

5. Выражения, операции и присваивание

5.4. Приоритет выполнения операций

Когда арифметические, символьные, логические операции и операции отношения присутствуют в одном выражении (такая смесь может быть, например, в логическом выражении), приоритет выполнения операций таков (дан в порядке убывания):

1)любая заданная или перегруженная одноместная операция;

2)арифметические операции;

3)символьная операция конкатенации;

4)операции отношения;

5)логические операции;

6)любая заданная или перегруженная двуместная операция.

Втабл. 5.2 встроенные операции Фортрана расположены в порядке убывания приоритета.

Таблица 5.2. Приоритет выполнения встроенных операций

 

**

*

+

//

.EQ., ==

.NOT.

.AND.

.OR.

.XOR.

 

 

 

/

-

 

.NE., /=

 

 

 

.EQV.

 

 

 

 

 

 

.LT., <

 

 

 

.NEQV.

 

 

 

 

 

 

.LE., <=

 

 

 

 

 

 

 

 

 

 

.GT., >

 

 

 

 

 

 

 

 

 

 

.GE., >=

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Замечание. Каждая ячейка таблицы содержит операции с равным приоритетом.

5.5. Константные выражения

В операторах объявления Фортрана могут появляться выражения (например, при задании значений именованных констант), но такие выражения должны быть инициализирующими и константными, например:

integer, parameter :: n = 10, m = n / 2

real a(m, n), b(2 * n) ! n / 2 и 2 * n - примеры константных выражений

В общем случае константное выражение - это выражение, в котором все операции встроенные, а каждый простой элемент - это:

константное выражение, заключенное в скобки;

константа или подобъект константы, в котором каждый индекс сечения или граница подстроки является константным выражением;

конструктор массива, в выражениях которого (включая границы и шаги) каждый простой член является константным выражением или переменной неявного цикла;

167

О. В. Бартеньев. Современный ФОРТРАН

конструктор структуры, компоненты которого являются константными выражениями;

обращение к встроенной элементной или преобразовывающей функции, все параметры в котором являются константными выражениями;

обращение к встроенной справочной функции (кроме функций PRESENT, ASSOCIATED или ALLOCATED), в котором каждый параметр -

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

Именованным константам (объектам с атрибутом PARAMETER) могут быть присвоены значения только инициализирующих константных выражений. Значения таких выражений вычисляются при компиляции, и поэтому на них накладываются дополнительные ограничения:

допускается возведение в степень лишь с целым показателем;

аргументы и результаты встроенных элементных функций должны быть целого или текстового типа;

из преобразовывающих функций допускаются только REPEAT, RESHAPE, SELECTED_INT_KIND, SELECTED_REAL_KIND, TRANSFER и TRIM.

Каждый элемент инициализирующего выражения должен быть определен в предшествующем операторе объявления или левее в том же самом операторе объявления.

Пример:

character(*), parameter :: st(3) = (/ 'Январь', 'Февраль', 'Март' /) integer, parameter :: n = len_trim(st(2))

5.6. Описательные выражения

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

они могут зависеть только от тех значений, которые определены при входе в процедуру;

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

168

5. Выражения, операции и присваивание

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

элементными функциями с параметрами и результатом целого или текстового типа;

функциями REPEAT, RESHAPE, TRANSFER и TRIM с параметрами целого или текстового типа;

справочными функциями, кроме функций PRESENT, ASSOCIATED и ALLOCATED, при условии, что величина, информация о которой выдается, не зависит от выделения памяти и прикрепления ссылки.

В обращении к справочной функции исследуемый объект может быть доступен посредством use-ассоциирования или ассоциирования через носитель или может быть объявлен в том же программном компоненте, но обязательно до его использования в справочной функции. На элемент массива, объявляемого в программном компоненте, можно ссылаться только после описания его границ.

Пример:

function fun(x, y, lob)

! Прежде объявляем x

real x

real(kind(x)) y, fun

! Теперь можно употребить x в описательном

integer lob(2)

! выражении

real, dimension( lob(1) : max(lob(2), 10) ) :: z real wz(lob(2) : size(z))

!Параметр разновидности типа переменной y и результирующей переменной

!fun, границы массивов z и wz задаются описательными выражениями.

5.7. Присваивание

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

Синтаксис оператора: var = expr

где var - имя переменной; expr - выражение.

В соответствии со стандартом в случае встроенного присваивания типы переменной var и выражения expr должны соответствовать друг другу:

результат арифметического выражения может быть присвоен числовой переменной. Если переменная и выражение имеют разные числовые

169

О. В. Бартеньев. Современный ФОРТРАН

типы, то тип результата выражения приводится к типу переменной, которой присваивается результат, например:

complex :: z = (-2.0, 3.0)

 

 

integer k

 

 

k = z * z

 

 

print *, k

!

-5

результат логического выражения может быть присвоен логической переменной;

результат символьного выражения может быть присвоен только символьной переменной;

переменной производного типа можно присвоить значение выражения данного типа, например:

type pair real x, y end type pair

type(pair) :: p1, p2 = pair(1.0, 2.0) p1 = p2

p2 = pair(-2.0, -5.0)

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

Можно, однако, выполнить перегрузку присваивания. Например, можно задать оператор присваивания, в котором var имеет числовой, а expr - символьный тип. Или задать присваивание, при котором переменной производного типа присваивается результат выражения иного типа. Перегрузка присваивания выполняется так:

составить подпрограмму sub с двумя обязательными параметрами x и y, причем параметр x должен иметь вид связи OUT, параметр y - IN. В результате работы подпрограммы определяется значение x;

используя оператор INTERFACE ASSIGNMENT(=), связать подпрограмму sub с оператором присваивания. Тогда подпрограмма будет вызываться каждый раз, когда var имеет такой же тип, как и x, а тип expr совпадает с типом параметра y, т. е. присваивание x = y эквивалентно вызову call sub(x, y).

Пример. Присвоить целочисленной переменной сумму кодов символов строки.

interface assignment(=) subroutine charti(n, ch) integer, intent(out) :: n character(*), intent(in) :: ch

170

 

 

 

5. Выражения, операции и присваивание

end subroutine charti

 

 

 

end interface

 

 

 

integer k, m

 

 

 

character(80) :: st = 'String to count'

 

 

k = st(:10)

! Выполняется заданное присваивание

call charti(m, st(:10))

! Этот вызов эквивалентен оператору m = st(:10)

print *, k, m

!

890

890

end

subroutine charti(n, ch) integer, intent (out) :: n character(*), intent (in) :: ch integer i

n = 0

do i = 1, len_trim(ch) n = n + ichar(ch(i:i)) end do

end subroutine charti

Замечание. Реализующая присваивание подпрограмма может быть модульной процедурой (разд. 8.7).

Более подробно вопросы перегрузки присваивания рассмотрены в разд. 8.12.2.

171