TW-CAD
    Что такое TestWard
    Технология
    Заказать тест
    Регистрация
    FAQ
    Статьи
  Проектирование
    Информация
    Вирт. лаборатория
  Учебный процесс
    1-й курс
      Лекции
      Ликбез
      Сессия
    5-й курс
      Литература
      Практикум
      Сессия
    Консультации
  Информация
    Как с нами связатся
    О нас

 

 

 

Массивы

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

  • в C как массив указателей
  • в Паскале как массив массивов
  • в Фортране как прямоугольная таблица

Многомерные массивы с dim>1, тем более с dim>2, а особенно с переменными размерностями, и в C и Паскале непременно вызовут затруднения, тогда как в Фортране все массивы описываются и обрабатываются единообразно.

Более точно, в Фортране
массив - это прямоугольная таблица с числом измерений от dim=0 до dim=7, таблица состоит из однотипных элементов, объединенных общим именем.

Важнейшие частные случаи:

  • dim=0 – скаляр - переменная, мы ее уже использовали, объявляя ее тип в списке integer real complex logical character , можно type (имя_рек_типа) список
  • dim=1 – вектор или одномерный массив
  • 7³dim>1 - многомерный массив
  • dim=2 – матрица, таблица или двумерный массив
  • dim=3 – система таблиц или трехмерный массив

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

Пример 1. Подсчитать для 60 вводимых чисел s-среднее и среднеквадратическое отклонение

GIFJPG/ar23.gif (1197 bytes)       GIFJPG/ar24.gif (1408 bytes)
Попробуем разобраться, сравнив 3 варианта решения задачи, см. колонки 1..3 в таблице.

до Fortran-90

в стиле Fortran-90

1 - простая переменная x

2 - массив X покомпонентно

3 -   X - вектор

Скаляр обозначили  маленькой букой x, вектор X - большой буквой, но Фортран различает их не по этому признаку

Program x_scalar
Real sum,s,Sigma,
Integer k

Sum = 0 ! среднее
do k = 1,60
Read(1,*) x ! x
забываем
Write(*,*) ‘x=’, x
Sum = sum +x
End do ! ..k = 1,60 !
s = sum / 60.
Write(*,*) '
среднее =', s

! среднеквадр. отклонение
Rewind ( 1 ) !
к началу файла
Do k = 1,60 ! x
не хранятся
Read
(1,*) x ! вводят снова
Sum = sum +(s-x)**2
End do
Sigma = sqrt( sum ) / 60.
Write(*,*) 'ско =', sigma

End

Program X_component
Real sum,s,Sigma, X (60)
Integer :: k

Read(1,*) x ! читаем все
Write
(*, "(10f5.2)" ) X

Sum = 0 ! среднее
do k = 1,60
Sum = sum +X(k)
end do !
хранят все Xk
s = sum / 60
Write(*,*) '
среднее =', s

! среднеквадр. отклонение
do k = 1,60 !
все X хранятся
sum = sum +(s-X(k))**2
end do ! ..k = 1,60
Sigma = sqrt( sum ) / 60
write(*,*) '
ско =', sigma

End

Program X_vector
Integer,parameter :: N=60
Real, dimension(1: N) :: X
Real
s

!
читаем и печатаем вектор X
Read
(1,*) X ; Write(*, "(10f5.2)" ) X

S = sum(X)/N; write(*,*) 'среднее =', s

Write
(*,*) '
ско =', sqrt(sum((X-s)**2))/ N

End

Пример того, как не имеет смысла писать.

Проще - нет повторного чтения. В циклах компоненты вектора вместо простой переменной.

Радикальное упрощение, в параметрах функции суммирования векторы вместо компонент.

До появления Fortran-90 у программиста была возможность манипулировать с простыми переменными, см. колонку 1, а также с переменными с индексами, см. колонку 2 в таблице. В Fortran-90 появилась возможность манипулировать с векторами и матрицами, см. колонку 3 в таблице. Обратите внимание, насколько лаконична и понятна программа в стиле Fortran-90: прочитать - вычислить - напечатать. В ней просматривается общая тенденция - перенести центр тяжести на раздел описаний и формулы, избавив программу от технических деталей, - в данном примере стали ненужными циклы.

Для того, чтобы это обеспечить в Fortran-90 появились

  • Емкие лаконичные средства описания атрибутов (свойств) объектов
  • Мощные и компактные средства конструирования массивов и сечений массивов (нечто похожее на минор матрицы)
  • Множество стандартных элементных функций, одинаково применимых и к переменным, и к векторам, и к матрицам
  • Пакет функций для измерения и препарирования массивов
  • Ряд новых функций для работы с векторами и матрицами

Новый принцип описания объектов в Фортране-90

Новый принцип описания объектов совмещает полное объявление типа и размерности, а также всех прочих атрибутов массива. Важно, что все собрано в одном описании. Если несколько массивов имеют одинаковый набор свойств, то они идут одним списком. Именно такой способ рекомендован как основной в обновленном языке Фортран-90, изобилующем многими уточняющими атрибутами. Например, вполне понятно описание в стиле Фортран-90
Integer*1, dimension (1:5), parameter :: CHET=(/ 0,2,4,6,8 /), NECHET=(/ 1,3,5,7,9 /)
в  этом описании имеется

  • знак двойного двоеточия "::" в середине строки говорит о том, что по определению набор атрибутов (свойств), перечисленных слева от "::", относится ко всем объектам, указанным справа от "::"
  • в примере справа от "::" два вектора CHET, NECHET, что свидетельствует о совпадении их свойств, при разных значениях  
  • атрибут integer*1, нужен, чтобы указать целый тип элементов, компактно упакованных, каждый в 1 байт
  • атрибут dimension, чтобы отличить массив от простой переменной и дать размерностные характеристики массива
  • атрибут parameter, чтобы указать, что всё это константы
  • составной знак (/  .. ..  /) - это конструктор массива, в данном примере целые числа из диапазона 0:9 подразделены на четные CHET и нечетные NECHET

В Фортране-90 атрибут dimension может иметь не только массив, но и функция.

В Фортране-77 Real и dimension являются не атрибутами, а операторами, допускается совмещать описания dimension X(60) и Real X, опуская dimension. Такой “экономный” способ описания не вполне согласуется с требованием явного полного перечисления свойств объектов, он не стал основным в Фортране-90

В Фортране-77 допускается писать одно описание

Вместо двух описаний

Real X(60)

Real X
dimension X(60)

MS в опережение стандарта также разрешила применение некоторых атрибутов, которые по их предложению в MS Ф5.1 записывались в квадратных скобках после имени объекта, например, Real Matrix [allocatable](:,:)  Написание атрибутов в квадратных скобках не принято в Фортране-90.

Характеристики массива

Одномерный, двумерный, трехмерный, любой многомерный массив описываются единообразно

  • одномерный массив real X(60) - это вектор из 60 однотипных элементов
  • двумерный массив real T(3,5) - это матрица однотипных элементов из 3 строк и 5 столбцов
  • трехмерный массив real Edr(4,3,2) - это система из 2 матриц, каждая по 4 строки и 3 столбца

В качестве индексов для выбора  элементов массива вместо безликих математических обозначений i,j,k лучше использовать "говорящие" имена вроде str, stl, tbl

·        integer str  !  номер строки

·         integer stl  !  номер столбца

·         integer tbl  !  номер таблицы

"Говорящие" имена str, stl, tbl сложнее перепутать местами между собой, зная, что именно в этом порядке должны перечисляться индексы трехмерного массива Radius( str, stl, tbl ) или Radius(3,2,3) – элемент 3-ей строки, 2-ого столбца, 3-ей таблицы. Элемент двумерного массива можно выбрать, задавая 2 индекса Dlina(2,5) или Dlina(str,stl).

Иллюстрируем характеристики массива на примере трех массивов
real*8,allocatable,dimension(-2:2,:) :: Dlina
integer*2, save, dimension(1:5,3,1:3) :: Radius
real
*4, dimension(1:5,2:4,11:13) :: Ploschad

Характеристики, объявляемые в описании массива

  1. имя массива пишется по обычным правилам, лучше по смыслу задачи – обязательная характеристика
    в нашем примере имена массивов Dlina, Radius, Ploschad
  2. тип массиважелательная характеристика, (implicit None отменит необязательность в описании типа)
    тип массива (как и для простой переменной) определяет как каждый элемент массива хранится в памяти ПК, сколько байтов занимает, какие к нему применимы операции; имеется 5 базовых типов (integer real complex logical character ) плюс любое количество производных типов данных, описываемых в составных операторах
    type Имя_типа .. .. end Type Имя_типа
    в нашем примере тип real для массива Dlina и integer*2 для массива Radius
  3. ранг массива или число измерений – обязательная, неявная характеристика
    допускается ранг от 1 до 7
    в нашем примере для массива Dlina ранг, то есть число измерений 2, так как после dimension в скобках в списке через запятую перечислены описания двух размерностей; диапазон по второму измерению не известен и отмечен лишь двоеточием, но для правильного подсчета опускать его нельзя
    в нашем примере для массива Radius ранг, то есть число измерений 3, так как после dimension в скобках в списке через запятую перечислены описания трех размерностей
  4. размерность – либо указана явно, либо строится по диапазону
    по каждому измерению обязательно указание либо размерности, либо диапазона
    размерность
    или протяженность по выбранному измерению - это неотрицательное число, указывающее на количество возможных значений индекса по этому измерению
    в нашем примере для массива Dlina число строк равно 5 (размерность по первому измерению), а число столбцов неизвестно (размерность по второму измерению)
    в нашем примере для массива
    Radius число строк, равное 5,  подсчитывается по диапазону -2:2; число столбцов, равно 3; число таблиц тоже 3 и совладает с верхней границе диапазона 1:3
  5. диапазон – либо указан явно, либо строится по размерности
    по каждому измерению обязательно указание либо размерности, либо диапазона, последнего даже в виде одного лишь двоеточия
    диапазон
    возможных значений индекса задается указанием нижней : верхней границ индекса;
    в том случае, когда нижняя граница опущена, элементы нумеруются с 1 и верхняя граница совпадает с размерностью; границы - целые числа, индекс изменяется через 1
    в нашем примере и для массива Radius и для массива Dlina размерность по первому измерению одинакова, то есть число строк равно 5, но диапазон разный - строки в массиве Radius нумеруются с 1 до 5, а в массиве Dlina от -2 до 2
    в нашем примере для массива
    Radius нижняя граница диапазона номеров таблиц опущена вместе с двоеточием, по умолчанию она; принимается; равной 1; поэтому и число строк и число таблиц изменяются в одном и том же диапазоне от 1 до 3
    в нашем примере диапазон по второму измерению для массива
    Dlina не известен и отмечен лишь двоеточием, опустить которое нельзя
  6. форма массива – это перечисление или вектор всех размерностей массива,
    форма важнейшая характеристика, которая определяет порядок размещения элементов в памяти - 1-й индекс самый быстрый, 2-й - медленнее .. самый медленный – последний
    в частности, двумерный массив располагается в памяти ПК по столбцам
          в нашем примере массив Radius имеет форму (5,3,3), а форма массива Dlina известна не до конца (5,?)
          в нашем примере массив
    Radius и Ploschad имеет одну и ту же форму (5,3,3), не смотря на то, что имеют разный тип и разный диапазон; индексов, поэтому Ploschad=2*3.14*Radius**2 вполне допустимая формула, опирающаяся на один и тот же порядок размещения элементов массивов Radius и Ploschad в памяти ПК
         
    в нашем примере массив Radius и Dlina имеет разный ранг, а значит и разную несовместимую форму, поэтому формула Dlina =2*3.14*Radius недопустима
  7. число элементов массива равно произведению всех размерностей массива, перечисленных в форме массива
        в нашем примере массив Radius имеет форму (5,3,3), число элементов=5*3*3=45
         в нашем примере форма массива
    Dlina известна не до конца (5,?) и число элементов не подсчитать
  8. объем памяти, занимаемой массивом, равен памяти, приходящейся на один элемент, помноженной на число элементов, ограничивается лишь объемом доступной памяти компьютера
       в нашем примере для массива Radius объем памяти=2*45=90 (байтов), поскольку integer*2 - это 2 байта на элемент, а число элементов=45
        в нашем примере для массива
    Dlina объем памяти не подсчитать, так как неизвестно число элементов, вследствие того, что неизвестно число столбцов (5,?)
  9. когда выделяется память под массив

·         под статический массив – при запуске программы резервируется объем памяти, подсчитанный при компиляции
        массив с фиксированной размерностью,
        массив с переменной размерностью- память резервируется в вызывающей программе, а перераспределяется в вызываемой ПП
в нашем примере массив Radius - статический, все его размерности фиксированы, потребуется неизменный объем памяти в 90 байтов

·         под динамический массив – в процессе выполнения программы, при компиляции объем памяти не известен
         массив с атрибутом allocatable - наделяемый памятью в операторе allocate,
         автоматический массив, память под который выделяется в момент вызова подпрограммы
в нашем примере массив Dlina динамический, так как его форма неизвестна (5,?), массив необходимо описывать с атрибутом allocatable, чтобы вернуться к вопросу о наделении его памятью позже при выполнении программы, когда станет известно число столбцов

  1. прочие атрибуты
    в нашем примере атрибут Save для массива Radius исключает попадание массива в стековую память ПК

Описание размерностных характеристик массива

DIMENSION - оператор или атрибут для описания размерностей,  диапазонов изменения индексов, ранга, и формы массива.

Атрибут dimension в Ф-90 (оператор в Ф-77) описывает все размерностные характеристики массива. Оператор описания с этим атрибутом  должен располагаться в программе до первого выполняемого оператора

Оператор описания, характерный для программ в стиле Фортран-77 пишется, как в прмерах

·          dimension X(60) ! одномерный массив из 60 элементов

·          dimension g(10,20) ! матрица или двумерный массив формы (/ 10,20 /) , 10 строк, 20 столбцов

В Фортране-77 Real и dimension являются не атрибутами, а операторами, допускается совмещать описание Real X и dimension X(60), опуская dimension. В этом случае то, что X-массив не явно описано dimension, а лишь косвенно видно из X(60).

В Фортране-77 допускается писать одно описание

Вместо двух описаний

Real X(60)

Real X
dimension X(60)

В скобках после атрибута dimension (после имени объекта в операторе dimension) перечисляются описания всех измерений массива.  Число описанных измерений определяет ранг массива. Любое измерение массива можно описать тремя способами:

  • неявно путем задания диапазона индексов cнач:cкон , где cнач £ cкон
    для любого значения индекса i в программе должно выполняться соотношение cнач£ i £cкон ,
    cнач ,cкон -целые - могут быть константами, константными выражениями, параметрами ПП или выражениями, куда входят параметры ПП
    например dimension L(10:100)
  • явным заданием размерности в виде cкон, подразумевая cнач=1, для любого значения индекса i в программе должно выполняться соотношение 1£ i £cкон, 
    например, dimension z(1000)
  • указанием  неизвестной размерности в виде двоеточия – подразумевается, что определение размерности отложено до выполнения программы используется для динамических массивов, объявляемых с атрибутом allocatable, что переводится как массив, наделяемый памятью в операторе allocate и освобождающий память в deallocate

Для того чтобы программу сделать более гибкой

  • вместо констант используют константные выражения из явных и именованных констант, чтобы легко изменять размерности многих массивов, изменяя централизованно лишь один параметр, например
    integer, parameter :: p=20
       integer, dimension(1:p+1, 1:p+1) :: M
       integer, dimension( 0 : 2*p-1 ) :: L , Q
  • вместо констант используют переменные целого типа, которые являются параметрами ПП для массивов с переменной размерностью и автоматических массивов
  • в MS-Fortran 5.1 используют метакоманду $debug, чтобы обеспечить контроль соотношения cнач£ i £cкон (с некоторым замедлением программы), с выдачей сообщения о его нарушении в виде "subsript out of range"
  • в FPS 4.0 для слежения за индексами используют режим отладки (проект вида debug)

Только говоря о явно описанной форме массива, как, например, в операторе dimension M(2,3), в скобках указывают количество строк и столбцов, в остальных случаях упоминаются значения индексов, так, например

Real M;   dimension M(2,3) ! в скобках указано 2-количество строк, 3-количество столбцов
read
(*,*)
M(2,3) ! в скобках указана позиция одного единственного читаемого элемента массива внутри массива
Позиция задается указанием 2-ой строки 3-его столбца в виде переменной с индексами M(2,3). В примере велено читать не всю матрицу, а один единственный элемент из 2-й строки, 3-его столбца.
read(*,*)  M   !   сравни - читать весь массив по столбцам

Предупреждение: элемент неописанного массива воспринимается компилятором как функция с параметрами - при компиляции нет аварийной ситуации и нет сообщений, но при компоновке получим сообщение "имя_массива - Undefined reference" – неопределенная ссылка, из-за неудачной попытки найти среди стандартных программ "псевдофункцию с именем массива".

Массивы и элементы массивов в формулах

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

В фортране-90 (частично и в MS Фортране 5.1) сделано важное обобщение: практически везде, где используется простая переменная, может быть использован массив

real X(11), Y(11), Z(-5:5); Z = sin(X/Y+0.5)/4 + 2.1

Непременное условие: все операнды, упомянутые в формуле с массивами – это либо массивы одной и той же формы, либо скаляры (переменные и константы), совместимые по форме с массивами любой формы.

Важная особенность – порядок обработки элементов массива стандартом не оговаривается, например, можно считать, что последовательно или параллельно. Последнее обстоятельство важно для отладки программы на любом компьютере – хоть на ПК с единственным процессором, хоть на суперкомпьютере со многими процессорами, где вычисления могут быть распараллелены. Связь с конкретными возможностями “железа” отнесена к компетенции компилятора.

Атрибуты и операторы в Фортране-77 и в Фортране –90

В Фортране-77 атрибутов нет, есть только операторы.
В MS-Фортране 5.1 в опережение стандарта Фортран–90 появились атрибуты, которые писали в квадратных скобках после имени объекта,
например, real*8 Dlina [ allocatable ] ( -2:2, : )
Основу описаний в Фортране-90 составляют атрибуты, но для преемственности сохраняется форма оператора.

Атрибут

Назначение

Фортран-77

Фортран –90

DATA

Начальные значения объектов

Оператор

Как атрибут не пишется,  однако инициализация всегда возможна.
 Как оператор сохранен.

PARAMETER

Именованная константа

Оператор

Атрибут/оператор

ALLOCATABLE

Динамический объект

В MS-Фортране 5.1 [Атрибут] в квадратных скобках после имени

Атрибут

SAVE

Сохраняемый объект
(вне стека)

В MS-Фортране 5.1 [Атрибут] в квадратных скобках после имени

Атрибут

INTENT

Тип связи параметра:
(IN)-входной,
(OUT)- выходной,
(INOUT) – вход-выходной

Нет

Атрибут

OPTIONAL

Необязательный параметр процедуры

Нет

Атрибут

PUBLIC

Общедоступный объект модуля

Нет

Атрибут

PRIAVITE

Локальный объект модуля

Нет

Атрибут

POINTER

Указатель

Нет

Атрибут

TARGET

Объект ссылки

Нет

Атрибут/оператор

В Фортран –90 лучше писать атрибуты, а не операторы, потому что:

  • все свойства объекта собраны в одном определении
  • переменные с одними и тем же набором свойств (атрибутов) идут общим списком

Статическое и динамическое распределение памяти

Объем памяти, занимаемой массивом, подсчитывается как число элементов, помноженное на число байтов в расчете на один элемент. Число элементов равно произведению всех размерностей массива, входящих в форму массива. Например, для двумерного массива число элементов - это произведение числа строк на число столбцов. В зависимости от того, когда делается подсчет числа элементов, различают два способа наделения массива памятью: статический - при компиляции, динамический - при выполнении программы. Описание массива должно быть видимо в каждой программной единице (ПЕ), где он используется; это может быть главная программа, подпрограмма (ПП) или модуль. В зависимости от того, где массив наделяется памятью, в каждом из способов предусмотрено две схемы наделения массива памятью

Где описана форма массива

Когда массив наделяется памятью

Статически –
при запуске программы

Динамически
при выполнении программы

Форма описана в той же ПЕ,  где массив наделяется памятью

Массив с фиксированными размерностями

allocatable - массив неизвестной формы
allocate - наделить памятью
 
deallocate – освободить память  

Форма описана через переменные, полученные из параметров ПП

Массив с переменной размерностью среди параметров: память распределена в вызывающей ПЕ, в ПП только перераспределяется

Автоматический массив не числится среди параметров – он локализован в ПП: наделяется памятью при входе, освобождается при выходе

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

Для динамического массива при компиляции известны не все характеристики, часто известен лишь ранг (его обязательно надо указывать). Объем памяти под динамический массив при компиляции не может быть подсчитан и при запуске программы память под него не может быть зарезервирована. В случае, когда Вы хотите добиться максимальной гибкости в использовании памяти, используйте принцип динамического распределения памяти, согласно которому именно во время выполнения программы подсчитывается необходимый объем памяти под массив, запрашивается и после использования освобождается! Там, где обозначен только ранг, а одна или несколько размерностей массива не известны, используется принцип динамического распределения памяти. В Фортран–90 помимо динамических массивов с атрибутом в allocatable в подпрограммах допускаются беззаботные автоматические массивы, которые и обсуждается позже.

Динамический (не автоматический) массив надо описать с атрибутом allocatable. Это означает, что при компиляции точно известен только ранг а форма известна не до конца (для неизвестной размерности пишут “:” вместо диапазона индексов). При запуске программы массив памятью не наделяется. Когда будут известны все размерности, будет подсчитан и выделен необходимый объем памяти при исполнении специального оператора allocate. Программист сам вручную выделяет память в операторе allocate и освобождает память в операторе deallocate. В MS-Фортране в расширение стандарта Фортран-77 также имеется атрибут allocatable, который пишется в квадратных скобках после имени массива. Переход на такое ручное управление требует большего опыта и ответственности. Кроме того, на все это требуется дополнительное время!

Размещение массивов в памяти компьютера

Размещение массивов в памяти компьютера определяется формой массива:

·        массивы одной формы имеют равное количество элементов, которые хранятся в памяти в одном и том же порядке

·        для массивов разной формы порядок следования элементов разнится, даже если они имеют равное количество элементов

Примеры на сравнение формы массивов:

real, dimension(4:5,-1:1,0:9) :: c,d ! форма (2,3,10) рассчитывается по описаниям размерностей
real, dimension(2,3,10) :: b ! b и c,d – одной формы, хранятся в памяти в одном и том же порядке
real, dimension(2,3) :: D ;   real, dimension(3,2) :: M  ! D и M – разной формы, хотя оба содержат по 6 элементов
real, dimension(2,0) :: E ;   real, dimension(0,2) :: S  ! S и E – разной формы, хотя оба не содержат элементов

Понятие формы важно, так как именно она характеризует порядок размещения элементов в памяти. Например, можно написать b=c ; d=2*a + sin(b), не заботясь о порядке обработки элементов массива.. В большинстве случаев так оно и есть, и программисту вовсе и не надо знать, как элементы массива располагаются в памяти компьютера друг относительно друга, Это правильно, так как позволяет распараллеливать вычисления в многопроцессорных системах!

Однако когда в/из массива передаются значения, то подразумевается порядок следования, соответствующий размещению элементов в памяти компьютера. Этот порядок стандартизован в Фортране:

·        для одномерного массива - по возрастанию индекса, например
dimension X(10) ! эквивалентны по действию 3 варианта
read(1,*) X
read(1,*) X(1), X(2), X(3), X(4), X(5), X(6), X(7), X(8), X(9), X(10)
read(1,*) X(1:10)

·        для двумерного массива - по столбцам, например,
dimension N(2,3) ! читать весь массив - понимают как
read(1,*) N   ! чтение по столбцам, как хранится в памяти
read(1,*) N(1,1), N(2,1),   N(1,2), N(2,2),   N(1,3), N(2,3)
read(1,*)   N(1:2,1),    N(1:2,2),     N(1:2,3)

·        вообще для многомерного массива - самый быстрый - 1-ый индекс, медленнее - 2-ой, ... наконец, самый медленный - последний, каждый из индексов пробегает все возможные значения по возрастанию, например,
dimension P(2,2,2)
read(1,*) P ! читать весь массив - понимают как
read(1,*) P(1,1,1), P(2,1,1), P(1,2,1), P(2,2,1), P(1,1,2), P(2,1,2), P(1,2,2), P(2,2,2)
read(1,*) P(1:2,1,1),    P(1:2,2,1),    P(1:2,1,2),    P(1:2,2,2)

Перечислим случаи, когда подразумевается порядок следования, соответствующий размещению элементов массива в памяти компьютера:

  • при подготовке данных для ввода и просмотре результатов вывода
  • при написании форматов вывода
  • при задании начальных значений для элементов массива
  • при передаче массива с переменными размерностями в подпрограмму, на чем основан механизм перераспределения памяти

Не следует путать вопрос о порядке ввода с вопросом о подготовке данных.

Например, вводя матрицу оператором read(*,*) N, соблюдая один и тот же порядок следования элементов
N(1,1), N(2,1), N(1,2), N(2,2), N(1,3), N(2,3) можно расположить по-разному:

1) все числа в одной строке 11,21,12,22,13,23

2) по одному числу в строке
11
21
12
22
13
23

3) по два числа в строке
11,21
12,22
13,23

4) по 3 числа в строке
11,21,12
22,13,23

В то же время при форматном вводе

dimension N(2,3)
read(1, '( 2i3)' ) N ! числа можно расположить только по два числа в строке, как указано в 2i3
11 21
12 22
13 23

Пример 2 "Ловушка" для начинающих. Для матрицы сумма элементов 1ой строки Sum=11+12+13=36.

Программа расчета Sum у начинающего может выглядеть так:
integer m1Sum, M(3,3)
data M/ 11,12,13, 21,22,23, 31,32,33 /
do k = 1,3
  m1Sum = m1Sum + M(1,k)
 
write(*,*) M(1, k) ! вставим просто для контроля
end do
write(*,'(3i3)' ) M
write(*,* ) 'Sum of M =', m1Sum
end

При выполнении этой программы получим на первый взгляд неожиданный результат Sum=11+21+31=63. Причина - перепутаны строки и столбцы в data, что часто делают начинающие. Но больше всего их запутывает печать "правильной" матрицы в write(*,'(3i3)' ) M - на самом деле при печати еще раз перепутаны строки и столбцы. Исправим программу, изменив в ней
data M / 11,21,31, 12,22,32, 13,23,33 / и печать матрицы по строкам, как будет показано ниже.

Hosted by uCoz
.

 

 Web-design Звягин В.Ф. со товарищи: Аминев Р.Ш..
197101, Россия, Санкт-Петербург, ул.Саблинская, 14
ИТМО
Hosted by uCoz