Обратная связь
|
Типичные недочеты и ошибки в работе с массивами На массивы приходится наибольшее число нововведений и оригинальных возможностей современного Фортрана, поэтому в помощь начинающим методичка дополнена данным разделом. Массив – не самый простой объект, поэтому требуются практические разъяснения.
Таблица 42. Статический массив
Нехорошо, неправильно
| Правильно – статический массив
| Пояснения
| Real X(10)
Real,&
dimension(1:10)::Y
| Real,dimension(1:10)::X,Y
| Конформные массивы дают единым списком
| Integer::N=10 !переменная
Real,dimension(1:N)::X
Неверно: размерность-переменная
| Integer,parameter::N=10!размерность N – константа
Real,dimension(1:N)::X
| Размерность статического массива должна быть константой.
| RealX(10)
Real,dimension(1:10)::Y
нехорошо, размерность 10 надо менять во многих местах
| Integer,parameter::N=10!размерность N – константа
Real,dimension(1:N)::X,Y
| Меняем только N – перекомпилируем
| Real,dimension(1:10)::X
.. x (i)= Y(i) Ошибка не при компиляции, а при компоновке: Y – unresolved external
| Real,dimension(1:10)::X,Y x(i) = y(i)
x,Y – оба массивы
| не описали y – воспринимается не как массив, а как неизвестная функцияотодногоаргументаy(i)
| Real,dimension(1:4)::X,Y
Y(i) = x (i) Ошибка при компиляции
| Real,dimension(1:4)::X,Y i =4; y (i) = x (i)
x,Y – оба массивы
| не описали y – воспринимается как ошибка
| Real,dimension(1:4)::X,Y
x(i)=y(i)! индекс i = ?
| Real,dimension(1:4)::X,Y
do i =1,4
x (i)= y(i)
enndo
| Ошибка при выполнении: защита записи – индекс не определен
| Real,dimension(1:4)::X,Y
x(i)=y(i)! индекс i = ?
| Real,dimension(1:4)::X,Y
X = Y
| Ошибка при выполнении: – индекс i не определен
|
Таблица 43.
Динамический массив
Нехорошо, неправильно
| Правильно-динамический массив
| Пояснения
| Real,dimension(:)::X
Неправильно – надо
allocatable
| Real,allocatable,&
dimension(:)::X
| нужен атрибут allocatable
размерность свободна ! форма (1:4) – неправильно
| Real,allocatable,&
dimension(1:4)::X
| Real,dimension(1:4)::X=1
real,allocatable,&
dimension(:)::Y
!allocate(y(1:size(x)))
Y = X
| Real,dimension(1:4)::X,Y=1
real,allocatable, &
dimension(:)::y
allocate(y(1:size(x)))
y = x
| забыли allocate:адрес y не определен
| Real,dimension(1:4)::X=4
Real,dimension(1:8)::z=8
Real,allocatable,&
dimension(:)::Y
allocate(y(1:size(x)))
Y=X
! deallocate(y)
allocate(y(1:size(z))) y = z
| real,dimension(1:4)::X=4
Real,dimension(1:8)::Z=8
real, allocatable,&
dimension(:)::y
allocate(y(1:size(x)))
Y = X deallocate(y)
allocate(y(1:size(z)))
y = z
| забыли deallocate В результатеповторный allocate не выполняется
| Real,allocatable,&
dimension(:)::X
Integer :: N=8
allocate(X(1:N))
|
Real,dimension(1:8)::X
| ошибки нет,
но нет смысла строить динамический массив постоянного объема
|
Таблица 44. Выражения и присваивания с массивами
Нехорошо, неправильно
| Правильно
| Пояснения
| Real,dimension(1:4)::P
Real,dimension(1:8)::Q
P= Q; Q= P плохо: массивы разной длины
| Real,dimension(1:4)::X,Y
X=(/ 3.1, 3.7, -15. /)
Y= X**2+3*X+1
| Массив = Выражение и присваивают, и строят выражение только из конформных массивов,
исключение – скаляры как sin(z) или 1 в выражении
| Real,dimension(1:4)::X
Real,dimension(1:4,1:3)::M
M= X; X= M
плохо: массивы с разным числом измерений не присваивают
| Real:: z=0.72
Real,dimension(1:4)::X
Real,dimension(1:4,1:3)::M=1
X=sin(z) + 1; M(:,1)=X; M(:,2)=2
| Real,dimension(1:4,1:3) :: M
Real,dimension(1:3, 1:4)::K
M=K !shape(M)≠shape(K)
| Real,dimension(1:4,1:3)::M,K
Real,dimension (1:4,-1:1)::R
K = M ; M= R
shape(M)=shape(K)=shape(R)
| конформные массивы - это массивы одинаковой формы [1:4,1:3], нумерация может быть разная
|
Таблица 45. Встроенные функции для работы с массивами
Нехорошо, неправильно
| Правильно
| Пояснения
| Real,dimension(1:8)::X
Print *, sum(X, X>0 )
| Real,dimension(1:8)::X
Print *, sum(X, mask=X>0 )
| Mask – 3-ий аргумент:
-надо указать имя mask
-задать после 2-го аргумента
| Print *, sum(X, 1,X>0 )
| Real,dimension(1:8)::X
Print *,count(Array=X,X>0 )
| Real,dimension(1:8)::X
Print *, count(X>0 )
| У функции count нет аргумента array
| Real,dimension(1:8)::X
Print*,sum(X(1:4),mask=X>0)
| Real,dimension(1:8)::X
Print*,sum(X(1:4),mask=X(1:4)>0)
| На ошибку Size(X(1:4))≠ Size(X) укажет компилятор
| Real,dimension(1:8)::X
Real g; integer N
g = sum(X(1:N), mask=X>0 )
правильно только при N=8
| Real,dimension(1:8)::X
Real g; integer:: N=4
g =sum(X(1:N), mask=X(1:N)>0 )
правильно при любом N≤8
| Size(X(1:N))≠Size(X)
компилятор не укажет на ошибку при неизвестном N
| IntegerN
Real,dimension(1:8)::A
N= MinLoc(A)
MinLoc- возвращает вектор, который не конформен скаляру N
| Real,dimension(1:8)::A
IntegerN
N=sum(MinLoc(A))
| Найти номер максимального элемента из массива A.
Также правильно:N=sum(MinLoc(A))
| Real,dimension(1:8)::A
IntegerN; Integer &, dimension(1:1)::Num
Num=MinLoc(A); N=Num(1)
|
Таблица 46.
Ввод - вывод массивов
Нехорошо, неправильно
| Правильно
| Пояснения
| Real,dimension(1:4,1:3)::M
read(1,*)M
Нехорошо: читают, как хранится в памяти – по столбцам
| Integer i Real,dimension(1:4,1:3)::M
read(1,*) ( M(i,1:3),i=1,4)
Надо читать по строкам
| Матрица ошибочно читается по столбцам, а обычно читают по строкам.
| Real,dimension(1:4,1:3)::M
write (1,7) M 7format(3f5.1)
| integer i ; Real, & dimension(1:4,1:3)::M write(1,7) ( M(i,:),i=1,4)
7format (3 f5.1)
вывод изменен – по строкам
| Матрица выводится по столбцам, а надо выводить по строкам
| Real,dimension(1:4,1:3)::M write(1,7)(M(i,1:3),i=1,4)
7format (4 f5.1)
Ошибочно: 4 –число строк
| Real,dimension(1:4,1:3)::M write (1,7) ( M(i,1:3),i=1,4)
7format ( 3 f5.1)
Надо 3– число столбцов
| 1-й индекс – строка 2-ой индекс - столбец Перепутали числа: столбцов 3, а строк 4.
| Real,dimension(1:3,1:3)::K
read(1,*)K !чтение транспонирует K 7 format(3 f5.1)
write (2,7) K
| Real,dimension(1:3,1:3):: K
read (1,7) (K (i,1:3),i=1,3)
write (2,7) ( K (i,1:3),i=1,3)
7 format(3f5.1)
| Матрица K хранится по столбцам. При неправильном вводе и выводе – создается иллюзия правильности..
| Вывести левую половину матрицы (2 из 4 колонок)
Real,dimension(1:2,1:4)::A
write(2,7)(A(i,1:2), i=1,2)
7 format(‘левая’/2f5.1) ! перед каждой строкой чисел – заголовок левая
| Вывести левуюполовину матрицы (2 из 4 колонок)
Real,dimension(1:2,1:4) :: A
write (2,7)(A(i,1:2), i=1,2)
7 format(‘левая’/ 2(f5.1) )
| Неправильно
левая 4.0 4.0 левая 4.0 4.0
| Правильно
левая 4.0 4.0 4.0 4.0 4.0 4.0
| Вывести левую половину матрицы (2 из 4 колонок)
Integer :: N=2
Real,dimension(1:2,1:4)::A
write(2,7)(A(i,1:2), i=1,2)
7format(‘левая’/ & (<N>f5.1))
Ошибка компилятора FPS40
| Вывести левуюполовину матрицы (2 из 4 колонок)
Integer:: N
Real,dimension(1:2,1:4) ::A
N=2;
write (2,7)(A(i,1:2), i=1,2)
7 format (‘левая’ / <N>(f5.1))
Только так работает в FPS40
| Неправильно
левая 4.0
4.0 4.0
4.0
| Правильно
левая
4.0 4.0 4.0 4.0
|
Таблица 47.
Описание массивов в процедурах
|
|