Ввод и вывод массивов
Традиционное представление матрицы в математике – по строкам. Если таким образом подготовить в текстовом файле матрицу, рассмотренную выше, то элементы в этом файле будут расположены по строкам – сначала первая строка, затем – вторая:
a(1,1), a(1,2), a(1,3), a(2,1),a(2,2), a(2,3)
Оператор
read(1,*) A
введет последовательность значений из файла и в том же порядке поместит эти значения в область памяти, предназначенную для массива. Но ведь в памяти эти элементы должны расположиться по столбцам!
В файле a(1,1), a(1,2), a(1,3), a(2,1),a(2,2), a(2,3) – для сравнения.
В памяти a(1,1), a(2,1), a(1,2), a(2,2),a(1,3), a(2,3)
Значения элементов массива попали не на свои места, а значит, программа будет выполняться с неправильными данными.
Оператор
write(1,*) A
выводит массив в порядке размещения его в памяти, т.е. по столбцам, а не по строкам, как традиционно должна выглядеть матрица.
Внимание! Последовательность операторов
read(1,*) A; Write(2,*) A
приведет к получению при выводе с виду правильной матрицы, то есть той же, что была введена, хотя из-за неправильного размещения массива в памяти результаты работы программы будут неожиданными.
Ввод двумерного массива
Задача состоит в том, чтобы элементы матрицы, введенные из файла по строкам, расположить в памяти по столбцам. Для этого обязательным является цикл по строкам, внутри которого вводятся элементы строки. Ввод массива выполняется под управлением списка, то есть формат не используется.
Пример
integer, parameter::kLine=2, kCol=3 ! число строк и столбцов
integer::nLine, nCol ! номера строки и столбца
real, dimension(1: kLine,1: kCol):: A! массив
Далее показаны три возможности написания оператора read.
1) использовать неявный цикл по строкам массива, представив каждую строку в виде секции массива A(nLine,1: kCol):
read(1,*)(A(nLine,1: kCol), nLine =1, kLine)
2) в том же неявном цикле по строкам в секции-строке диапазон индекса столбца использовать по умолчанию A(nLine,:):
read(1,*)(A(nLine,:), nLine =1, kLine)
3) в неявном цикле по строкам массива использовать вложенный неявный цикл по столбцам этого массива:
read(1,*)((A(nLine,nCol),nCol=1,kCol),nLine=1,kLine)
Вывод двумерного массива
При выводе массива задача состоит в том, чтобы элементы матрицы, расположенные в памяти по столбцам, вывести в файл по строкам. При решении этой задачи также не обойтись без цикла по строкам, внутри которого выводятся элементы строки. Следует только учесть одно важное дополнение – вывод должен быть форматным.
Для вывода массива из предыдущего примера можно воспользоваться следующими операторами:
write(2,*) ‘Матрица’
do nLine = 1, kLine ! цикл по строкам
write(2,11) A(nLine,:) ! строка – секция массива
Enddo
11 format (20(F7.2))
Здесь каждой строке соответствует оператор write.Повторитель спецификаций формата не должен быть меньше, чем длина строки массива.
Более компактно то же самое можно записать с использованием неявного цикла:
write (1,11)(A(nLine,:), nLine =1, kLine)
11 format(‘Матрица’/<kCol>( F7.2))
Здесь для вывода всего массива используется один оператор write, то есть длина списка вывода равна длине массива. Для того, чтобы каждая строка массива была выведена в отдельной строке файла, служит повторитель спецификации в операторе format. Если в качестве повторителя используется переменная, ее имя заключается в угловые скобки.
Пример 1. Вывести в виде матрицы элементы нижней правой четверти вещественной матрицы A из 4 строк и 6 столбцов.
real, dimension(1:4, 1:6) :: A! массив
integer::nLine ! номер строки
write (1,11)(A(nLine, 4:6), nLine =3, 4)
11 format(3(F7.2))
Пример 2. Вывести в виде одномерных массивов элементы главной и побочной диагоналей квадратной вещественной матрицы A размером Size ´ Size.
integer, parameter::Size=8 ! число строк и столбцов
integer::Number ! номера строки и столбца
real, dimension(1: Size,1: Size):: A! массив
! главная диагональ
write (1,11)(A(Number, Number), Number=1, Size)
! побочная диагональ
write (1,11)(A(Number, Size-Number+1), Number= Size, 1, -1)
11 format(<Size>(F7.2))
Примеры задач.
Пример 3. Создать и вывести вещественную матрицу, значение каждого элемента которой равно квадратному корню из суммы его индексов.
integer, parameter::kLine=2, kCol=3 ! число строк и столбцов
integer::nLine, nCol ! номера строки и столбца
real, dimension(1: kLine,1: kCol):: A! массив
do nLine = 1, kLine ! цикл по строкам
do nCol = 1, kCol ! цикл по столбцам
A(nLine, nCol) = SQRT(Real(nLine+nCol))
Enddo
Enddo
write(2,11)(A(nLine,:), nLine =1, kLine)
11 format (<kCol> (F7.2))
Обратите внимание – аргумент функции SQRTдолжен быть вещественным.
Пример 4. В каждой строке прямоугольной вещественной матрицы изменить знак максимального по модулю элемента.
1) Цикл по строкам – внешний, в каждой строке – цикл по столбцам.
2) Вместо значения максимального по модулю элемента отслеживается его номер в строке jmax. По индексам элемента доступно его значение.
Дата добавления: 2017-09-19; просмотров: 796;