Выделение массивов одинакового размера
Я хотел бы выделить массив B
одинаковой формы и иметь те же нижние и верхние границы, что и другой массив A
. Например, я мог бы использовать
allocate(B(lbound(A,1):ubound(A,1), lbound(A,2):ubound(A,2), lbound(A,3):ubound(A,3)))
Но не только это неэлегантно, но и становится очень раздражающим для массивов (даже) более высоких измерений.
Я надеялся на что-то большее, чем
allocate(B(shape(A)))
который не работает, и даже если это действительно сработало, каждое измерение начнется с 1, чего я не хочу.
Кто-нибудь знает, как я могу легко выделить массив для того же размера и границ, что и другой массив, для произвольных размеров массива?
Ответы
Ответ 1
Начиная с Fortran 2008, теперь существует необязательный аргумент MOLD
:
ALLOCATE(B, MOLD=A)
Спецификатор MOLD = работает почти так же, как SOURCE =. Если вы укажете MOLD =, а source_expr - переменная, ее значение не обязательно должно быть определено. Кроме того, MOLD = не копирует значение source_expr в назначаемую переменную.
Источник: IBM Fortran Ref
Ответ 2
Вы можете определить его в директиве препроцессора, но это будет с фиксированной размерностью:
#define DIMS3D(my_array) lbound(my_array,1):ubound(my_array,1),lbound(my_array,2):ubound(my_array,2),lbound(my_array,3):ubound(my_array,3)
allocate(B(DIMS3D(A)))
не забудьте скомпилировать, например. параметр -cpp
(gfortran)
Если вы используете Fortran 2003 или выше, вы можете использовать исходный аргумент:
allocate(B, source=A)
но это также скопирует элементы A в B.
Ответ 3
Если вы делаете это много и считаете его слишком уродливым, вы можете написать свою собственную подпрограмму, чтобы позаботиться об этом, copy_dims (template, new_array)
, инкапсулируя строку исходного кода, которую вы показываете. Вы могли бы даже создать общий интерфейс, чтобы он мог обрабатывать массивы нескольких рангов - см. как написать оболочку для "allocate" для примера этой концепции.