Материал: Аверянов Введение в оператсионные системы и основы программирования 2015

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Легко представить себе куб (рис. 3.2), состоящий из мелких кубиков, каждый из которых пронумерован тремя индексами – это модель распределения памяти для трехмерного массива (назовем его CUBE – имя не имеет значения). Элементы массива будут ну-

мероваться от CUBE(1, 1, 1) до CUBE(4, 4, 4).

Ранг массива равен трем (хотя чаще вместо термина «ранг» употребляются старые термины, как размерность или число измерений). Максимальный ранг массивов в Фортране не может быть больше семи. Размер массива, т.е. общее число элементов в массиве CUBE составляет шестьдесят четыре элемента, а экстенты, или протяженности, по каждому измерению одинаковы и равны четырем. Совокупность экстентов массива определяют его форму. Для CUBE ранг массива (равный трем) и форма: (3, 3, 3) полностью определяют его как массив в модели данных Фортрана 90/95.

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

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

Для начала рассмотрим статические массивы. Из них простейшими являются одномерные массивы (c размерностью или рангом, равным единице). Одномерный массив является аналогом такого математического объекта как последовательность. Например, последовательность цифр от 0 до 9 может представлять собой одномерный массив целых констант c именем DIGITS (как в примере 3.38). То, что описываемый объект является массивом, состоящим из десяти элементов, показывает атрибут DIMENSION с указанием в круглых скобках размерности массива. Наличие атрибута PARAMETER говорит о том, что элементы массива являются константами.

Пример 3.38. Объявление и инициализация массива констант с указанием верхней границы

program ARRINIT1

integer (kind=1), parameter, dimension(10):: DIGITS = (/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9/)

151

print*, DIGITS end

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

DIGITS (1) = 0, DIGITS (2) = 1, … , DIGITS (10) = 9

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

Можно изменить нумерацию элементов массива DIGITS, потребовав, например, чтобы они нумеровались с нуля:

DIGITS (0) = 0, DIGITS (1) = 1, … , DIGITS (9) = 9

Для этого нужно явно задать нижнюю границу массива с учетом того, что по правилам Фортрана верхняя и нижняя границы массива в атрибуте DIMENSION разделяются двоеточием (пример 3.39).

Пример 3.39. Объявление и инициализация массива констант с указанием нижней и верхней границ

program ARRINIT2

integer (kind=1), parameter, dimension(0:9):: DIGITS = (/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9/) print*, DIGITS

end

Для инициализации (присвоения значений элементам) одномерных массивов в Фортране 90/95 предусмотрен специализированный конструктор (он использован в примерах 3.38 и 3.39), который в простейшем случае представляет собой список (через запятую) буквальных констант и ограниченный лексемами «(/» и «/)».

152

Пример 3.40. Объявление и инициализация массива констант при помощи конструктора

program ARRINIT3

integer (kind=1), parameter, dimension(0:9):: DIGITS = (/ ( I, I = 0, 9) /) print*, DIGITS

end

Конструктор инициализации массивов (пример 3.40) позволяет представлять список инициализации в виде значений, зависящих от некоторой переменной, например, список: 0, 1, 2, …, 9 может быть представлен в виде неявного цикла: (I, I = 0, 9). Здесь переменная цикла I (имя не принципиально, но это должна быть целая величина) пробегает все целые значения от 0 до 9.

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

В первом случае значение переменной неявного цикла I начинается с единицы, заканчивается девяткой, при этом для отбора только нечетных значений шаг изменения I равен двум: (I, I = 1, 9, 2).

Во втором случае шаг изменения I стандартный (равен единице

ипотому не указывается), но добавляется масштабирующий множитель: 0.1, уменьшающий значения, пробегаемые переменной цикла I в десять раз: (I*0.1, I = 1, 9, 2).

Следует отметить, что неявные циклы имеют большое значение

ичасто применяются при выводе массивов на печать, в файлы и т.д. (например, в операторе PRINT, пример 3.41).

Пример 3.41. Использование неявных циклов при инициализации массива и еговыводе на печать

program ARRINIT4

integer (kind=1), parameter, dimension(0:9):: DIGITS = (/ ( I, I = 0, 9) /) print*, (DIGITS(I), I = 0, 9))

end

Для приведенных примеров важно еще раз отметить, что список значений элементов (/ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9/) и диапазон индексов (0:9) – это разные вещи, не смотря на то, что выглядят одинаково.

Широкое распространение в компьютерных вычислениях имеют

двумерные массивы (c размерностью или рангом, равным двум).

153

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

1

2

3

4

5

6

7

8

9

Элементы двумерного массива (например, матрицы; обозначим ее переменной или константой MATRIX) адресуются двумя индексами: номером строки, часто обозначаемым целой переменной I, и номером столбца, за него обычно отвечает целая переменная J.

Таким образом, любой элемент матрицы может быть обозначен как MATRIX(I, J), где I и J могут принимать целые значения в диапазоне от единицы до трех. Так, элемент «5» приведенной выше матрицы будет иметь индексацию MATRIX(2, 2).

В машинной памяти все двумерные массивы размерности (M, N) хранятся как одномерные массивы, имеющие сквозную нумерацию от 1 до (M*N) и сформированные из последовательности столбцов соответствующей матрицы.

Рассмотрим вопрос об объявлении и инициализации подобного массива MATRIX (пример 3.42). При этом будем считать, что элементы матрицы – переменные целого типа INTEGER стандартной разновидности.

Для инициализации массива воспользуемся оператором DATA, который позволяет присвоить массиву-переменной список значений: разделителями элементов списка значений являются запятые, а сам список целиком заключен в прямые слеши «/»:

Пример 3.42. Объявление и инициализация двумерного массива переменных при помощи оператора DATA и егопострочный вывод

program ARRINIT5

integer, dimension(3, 3) :: MATRIX data MATRIX /1, 2, 3, 4, 5, 6, 7, 8, 9/ I=1; print*, (MATRIX(I, J), J = 1, 3) I=2; print*, (MATRIX(I, J), J = 1, 3) I=3; print*, (MATRIX(I, J), J = 1, 3) end

Если инициализирующий список матрицы MATRIX состоит из чисел от единицы до девяти в порядке возрастания, то при выводе

154

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

1

2

3

4

5

6

7

8

9

При этом на экране видим, что первая строка стала первым столбцом, вторая – вторым столбцом, а третья – третьим:

1

4

7

2

5

8

3

6

9

Это произошло потому, что при поточном вводе данных в массив (например, оператор DATA) они записываются по столбцам, а не по строкам – это одна из особенностей Фортрана (например, в языке Си при подобном вводе данные запишутся по строкам). Если внести соответствующие изменения входных данных, то все станет на свои места (пример 3.43).

Вернемся к вопросу об индексации массивов. При объявлении двумерного массива MATRIX в атрибуте DIMENSION(3, 3) указаны только верхние границы массива по каждому измерению, это означает, что нижние границы по каждому измерению равны единице. Как было в случае с одномерным массивом или как в принципе допустимо с семимерным массивом, можно указывать диапазоны границ по каждому измерению (см. пример 3.43).

Пример 3.43. Объявление и инициализация двумерного массива переменных при помощи оператора DATA и егопострочный вывод

program ARRINIT6

integer, dimension(3, 3) :: MATRIX data MATRIX /1, 4, 7, 2, 5, 8, 3, 6, 9/ I=1; print*, (MATRIX(I, J), J = 1, 3) I=2; print*, (MATRIX(I, J), J = 1, 3) I=3; print*, (MATRIX(I, J), J = 1, 3) end

Диапазон индексов представляет собой нижнюю и верхнюю границы индекса, разделенные двоеточием (пример 3.44).

155

Источник: https://studfile.net/preview/16708824/