Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Fortran 90. ANSI Standard.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
861.18 Кб
Скачать

Повторная нумерация

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

INTEGER :: nums(10), i

nums = (/ 1,3,5,7,9,2,4,6,8,0 /)

...

i = MAXLOC( nums ) ! i=5, элемент 9 есть maximum

i = MAXLOC( nums(1:5) ) ! i=5, последний элемент в вырезке =9

i = MAXLOC( nums(3:8) ) ! i=3, третий элемент в вырезке =9

i = MAXLOC( nums(::2) ) ! i=3, третий элемент в вырезке =9

 

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

Основные встроенные процедуры

Основные встроенные процедуры специфицировны для скалярных аргументов, но могут брать аргументы-масивы:

REAL :: num, root

REAL, DIMENSION(3,3) :: a

INTEGER ::length(5)

CHARACTER(LEN=7) :: c(5)

...

root = SQRT(num)

a = SQRT(a)

length = LEN( TRIM(c) ) ! length=6

Функция SQRT() возвращает квадратный корень ее аргумента. Если аргумент - скалярная переменная, возвращается оно значение. Если аргумент массив, возвращается массив корней. Каждый элемент заменяется корнем существующего значения.

Третье присваивание находит длину строки для каждого элемента массива с и отбрасывает завершающие пробелы. Следовательно, если c(1) есть 'Alexis ' функция TRIM() возвратит 'Alexis' (то есть удалит завершающий пробел), получит длину length 6.

 

Многие встроенные функции (включая математические функции) могут брать массивы и их вырезки или отдельные скалярные переменные в качестве аргументов.

Массивы нулевого размера

Массив в Fortran 90 может иметь размер 0. Это случается, когда нижняя граница больше верхней. Такой массив полезен, потому что не имеет значений элемента, не имеет данных, но правилен и определен. Пустой массив позволяет управлять известными ситуациями без требуемых экстра-кодов. Рассмотрим пример:

INTEGER :: a(5)=(/1,2,1,1,3/)

...

a(1:COUNT(a==1))=0 ! a=(/ 0,0,0,1,3 /)

a(1:COUNT(a==4))=1 ! a не изменилось

Первый оператор инициализирует a, используя конструктор массива.. Функция COUNT() возвращает число элементов, значения которых равно 1 и 4 соответственно. Первый оператор устанавливает a(1:3) в 0, но второй ничего (потому что нет элементов a, равных 4, и вырезка массива a(1:0) - массив размера 0).

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

Массивы и производные типы

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

TYPE(circle)

INTEGER :: radius

REAL :: area

END TYPE circle

Где-нибудь в другом месте второй встроенный тип, называемый position , использован для запоминания координат центра окружности типа real; position имела два числа типа real в качестве компонент. Возможно заменить использование производного типа position массивом типа real :

TYPE(circle)

REAL, DIMENSION(2) :: pos

INTEGER :: radius

REAL :: area

END TYPE circle

Здесь pos(1) есть x координата, соответственно pos(2) есть y координата. Массив можно использовать, когда число компонент довольно велико. На компоненты массива ссылаются точно так же, как на другие компоненты:

TYPE(circle) :: first

...

first%pos(1) ! элемент 1 из pos

first%pos(1:) ! весь массив (сечение)

 

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

TYPE(circle), DIMENSION(100) :: all_circles

...

all_circles(1)%radius ! радиус окружности 1

all_circles(51:100)%radius ! радиус последней половины окружностей

all_circles(1:100:2)%area ! область каждой другой окружности

all_circles(:)%pos(1) ! x - координаты каждой окружности

all_circles%pos ! все координаты всех окружностей

all_circles(10)%pos(:) ! обе координаты 10-й окружности

 

Массив производного типа данных и/или компоненты массива имеют те же требования (то есть те же правила в выражениях и др.) и ограничения как другие массивы в Fortran 90. Например:

TYPE(circle), DIMENSION(100) :: cir

...

cir(1:10) = cir(91:100) ! соответствие сегментов производных типов

cir(i)%pos = cir(i-1)%pos(:) ! соответствие массивов типа real

cir%pos(1:2) = cir(1:2)%pos ! ошибка, cir=cir(1:2) не соответствуют

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