Размещение массива в памяти компьютера
Говоря о размещении массива в памяти, следует прояснить:
- какой объем памяти требуется;
- в каком порядке элементы массива хранятся в памяти;
- когда массив размещают в памяти.
Какой объем памяти требуется?
Объем памяти, занимаемый массивом, определяется просто из-за того, что все элементы однотипны и занимают одинаковый объем памяти.
<объем_памяти> = <память на один элемент>*size(array)
Размер массива ограничивает лишь объем памяти компьютера.
В каком порядке элементы массива хранятся в памяти?
В большинстве случаев программист об этом может не задумываться. Однако, в ряде случаев при передаче массива целиком подразумевается именно этот порядок:
- при подготовке данных для ввода;
- при написании форматов вывода;
- при задании начальных значений для элементов массива.
Порядок хранения стандартизован в Фортране: для одномерного массива – по возрастанию индекса, для матрицы – по столбцам, для многомерного массива – самый быстрый первый индекс, медленнее второй, наконец, последний – самый медленный, каждый из индексов пробегает все значения по возрастанию.
Пример. В каком порядке надо готовить данные?
Всего в трехмерном массиве P(1:2,1:2,1:2) 8 элементов. Его элементы располагаются в памяти, как указано выше, и порядок чтения разъясняется вторым оператором read. Именно в этом порядке и надо готовить данные. Так как read бесформатный, можно, не нарушая порядка следования, либо все числа перечислить в одной строке через пробел или запятую, либо – каждое число – в отдельной строке.
dimension P(1:2,1:2,1: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)
Предупреждение. Размещение массива в памяти стандартно и никак не зависит от порядка ввода.
Когда массив размещают в памяти?
Форма статического массива, (предыдущий пример), известна при компиляции – shape(P)=(/2,2,2/); массив размещается в памяти при запуске программы. Форма динамического массива не определена при компиляции, например,
Real,allocatable,Dimension(:,:) :: Matrix, Matr1, Matr2, X(:)
Известно лишь количество измерений массивов: два для Matrix и один для X. Запустив программу, сначала определяют протяженности, а затем динамически размещают массивы в памяти оператором
allocate( X(1:N),Matrix(1:M,1:N),&
Matr1(1:N ,1:M), Matr2(1:N,1:N) )
Освобождают память оператором
deallocate( X, Matrix, Matr1, Matr2 )
Массив как аргумент процедуры должен быть размещен в памяти до входа в процедуру; в нее передается его адрес, независимо от способа написания размерности:
Real,intent,Dimension(1:N)::Mas - в виде переменной N;
Real,intent(in),Dimension(1:10)::Mas - в виде константы 10;
Real,intent(in),Dimension(:)::Mas – без указания размерности;
Real,intent(in),Dimension(*)::Mas-массив, перенимает форму;
Dimension(1:N,1:M) – в виде массива с перераспределением памяти между строками и столбцами, например, 3*4=4*3=2*6=6*2=12.
В любом случае количество элементов можно узнать с помощью функции size(array), а для матрицы число строк – size(Matrix,dim=1), число столбцов – size(Matrix, dim=2).
Пример (массивы X, Y, P, Q конформны):
real,dimension(1:11):: X,Y ! массивы X,Y по 11 элементов
real,dimension(-5:5)::P,Q ! P,Q – по 11 элементов с номерами 5,..0,..5
Y=sin(X+0.5)/4 + 2.1; p= Y/2; Q=P-1
5.3. Секции массивов и неявный цикл в списках ввода/вывода
Требуя гибкой организации, ввод/вывод массивов часто подразумевает строчную форму написания цикла в списке ввода/вывода. Неявный Do – это конструкция вида read(..) (v, i=iн,iк,is); write (..) (v, i=iн,iк,is) , где v -список переменных, выражений, элементов массива, зависящих от i. Скобки как бы заменяют do .. enddo , ограничивая область действия цикла по переменной i. Возможно вложение циклов. Поскольку речь идет об индексах, то i, iн, iк, is– целые величины. Триплетом называют тройку целых величин iн, iк, is , записанных в отличие от цикла через двоеточие iн:iк:is. Как можно заметить из примеров, приведенных ниже в Табл.32, триплеты можно употреблять вместо индексов, как в M(i,1:3:2). Известно также, что шаг is=1, если он опущен M(i,1:3). В отличие от цикла в триплете можно опускать не только шаг, но и iн – M(i,:3), и iк – M(i,1:) и оба – M(i,::2), и даже все три элемента триплета вместе – M(i,:). Поэтому, например, M(i,:) и M(i,1:3) эквивалентны. Опущенные iн-начало и iк-конец выбираются из описания массива. Понятно, что M(:,:) писать не стоит, потому что это эквивалентно M. Секция массива – это тоже массив, который можно применять почти везде, где применяют массивы. Как массив секция имеет свою форму.
Часто наряду с секциямииспользуют неявный цикл Do, когда требуется изменить стандартный порядок ввода/вывода. И ту, и другую конструкцию применяют, в частности, для ввода-вывода.
Таблица 32.
Ввод-вывод на матрице Integer,dimension(1:3,1:4)::M
Задание | Неявный Do | Используя секции |
Ввод 1-ой строки | read(*,*) (M(1,j), j=1,4) | read(*,*) M(1,1:4) |
Вывод по строкам | read(1,*)((M(i,j),j=1,4),i=1,3) | read(1,*) (M(i,:),i=1,3) |
Вывод матрицы по строкам | write(*,7) ( i, M(i,:),i=1,3 ) 7format(1x,'№',i1,':',4i3) | |
То же, но длиннее, с номерами | write(*,7) (i, M(i,1:4),i=1,3) | |
Ввод 2-го столбца | read(*,*)(M(i,2),i=1,3) | read(*,*) M(:,2) |
Ввод диагонали матрицы | read(*,*) (M(i,i),i=1,3) В данных - диагональ матрицы |
Дата добавления: 2016-02-13; просмотров: 6390;