Могу ли я создавать суб-массивы в Фортране, используя указатели? - PullRequest
6 голосов
/ 20 марта 2011

Я хочу иметь возможность иметь большой мастер-массив и ссылаться на разные его части, используя под-массивы.В настоящее время я использую индексы смещения, чтобы сделать это, но это может быть очень сложно сделать это таким образом.

Могу ли я иметь основной массив измерения (9) и 3 вложенных массива измерения (3), чтобы sub_array1 указывал на первые 3 элемента master_array, sub_array2 - на следующие 3 элемента и sub_array3к последним 3 элементам?

Например, массивы будут определены следующим образом:

integer, dimension(9) :: master_array
integer, dimension(3) :: sub_array1, sub_array2, sub_array3

Соотношение между массивами будет:

sub_array1(1) -> master_array(1)
sub_array1(2) -> master_array(2)
sub_array1(3) -> master_array(3)

sub_array2(1) -> master_array(4)
sub_array2(2) -> master_array(5)
sub_array2(3) -> master_array(6)

sub_array3(1) -> master_array(7) 
sub_array3(2) -> master_array(8)
sub_array3(3) -> master_array(9)

Более того, возможно ли иметь смешанные типы данных, чтобы у меня был один подмассив вещественных чисел в большем основном массиве целых чисел?

Заранее спасибо за помощь

1 Ответ

11 голосов
/ 20 марта 2011

Да, вы можете использовать абсолютно указатели, чтобы указывать на субрегионы массива.Это может быть очень удобно во многих ситуациях, например, для расчета трафарета для PDE:

program pointerviews
    real, dimension(10), target :: alldata
    real, dimension(:), pointer :: left
    real, dimension(:), pointer :: centre
    real, dimension(:), pointer :: right

    alldata = (/ (i, i=1,10) /)

    left  => alldata(1:8)
    right => alldata(3:10)
    centre=> alldata(2:9)


    print *, alldata
    print *, left
    print *, centre
    print *, right
    print *, (left - 2*centre + right)
end program pointerviews

Указатели на массив в FORTRAN - это больше, чем просто адрес, они содержат размер массива, шаг и информацию о типетоже.Таким образом, вы можете делать еще более безумные вещи, как это (если вы привыкли к указателям на C) и включать шаги:

program pointerviews2
    real, dimension(10), target :: alldata
    real, dimension(:), pointer :: left
    real, dimension(:), pointer :: centre
    real, dimension(:), pointer :: right

    alldata = (/ (i, i=1,10) /)

    left  => alldata(1:8:2)
    right => alldata(3:10:2)
    centre=> alldata(2:9:2)

    print *, alldata
    print *, left
    print *, centre
    print *, right

    print *, 'Changing alldata(4) = 9999'
    alldata(4) = 9999.

    print *, alldata
    print *, left
    print *, centre
    print *, right

end program pointerviews2

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

...