2016-01-23 3 views
1

По какой-то причине мне нужно передать указатель Fortran на подпрограмму. Подпрограмма находится внутри модуля, и основная программа использует этот модуль для обеспечения явного интерфейса.Как передать указатель fortran в подпрограмму?

Мой вопрос: какой атрибут я должен указывать в фиктивном аргументе подпрограммы, чтобы получить переданный указатель?

Я пробовал код ниже.

module aaa 

contains 

integer*4 function print_ptr_arr_1(ptr) 

    implicit none 

    integer*4, intent(in), pointer :: ptr(:) 

    print *, 'as pointer' 
    print *, size(ptr) 
    print '(10i3)', ptr 
    print * 

end function print_ptr_arr_1 

integer*4 function print_ptr_arr_2(ptr) 

    implicit none 

    integer*4, intent(in), target :: ptr(:) 

    print *, 'as target' 
    print *, size(ptr) 
    print '(10i3)', ptr 
    print * 

end function print_ptr_arr_2 

integer*4 function print_ptr_arr_3(ptr) 

    implicit none 

    integer*4, intent(in) :: ptr(:) 

    print *, 'as assumed shape array' 
    print *, size(ptr) 
    print '(10i3)', ptr 
    print * 

end function print_ptr_arr_3 

end module aaa 

и

program main 

    use aaa 

    implicit none 

    integer*4 :: i1, ierr 
    integer*4, target :: arr(10) 
    integer*4, pointer :: ptr_arr(:) 

    do i1 = 1, 10 
     arr(i1) = i1 
    end do 

    ptr_arr => arr 

    ierr = print_ptr_arr_1(ptr_arr) 
    ierr = print_ptr_arr_2(ptr_arr) 
    ierr = print_ptr_arr_3(ptr_arr) 

    nullify(ptr_arr) 

end program main 

Три подпрограммы в модуле ааа показывают правильные выходы, как показано ниже.

[email protected]:~/work/practice/fortran_pointer$ ./a.out 
as pointer 
      10 
    1 2 3 4 5 6 7 8 9 10 

as target 
      10 
    1 2 3 4 5 6 7 8 9 10 

as assumed shape array 
      10 
    1 2 3 4 5 6 7 8 9 10 

[email protected]:~/work/practice/fortran_pointer$ 

Что является правильным, а какие нет? Или все это правильно?

ответ

2

Это зависит от того, как вы собираетесь использовать то, что вы передаете функции. Вам нужно, чтобы он был указателем? Затем укажите атрибут pointer. Вам нужно указать на него другим указателем в функции? Затем укажите атрибут target. Фиктивный аргумент возьмет на себя все атрибуты, которые вы ему даете.

Если вы объявите его как pointer, тогда вы можете использовать его в качестве указателя и выделить/указать на новые вещи внутри функции.

Если вы объявите его как target, тогда другие указатели внутри функции могут указать на него, но вы не сможете указать на него target, поскольку это не указатель.

Если вы просто хотите рассматривать его как массив, вы можете просто объявить его как массив предполагаемого размера и рассматривать его как обычный массив, но опять же вы не сможете использовать его так же, как если у него есть атрибут pointer или target.

Значит, все в порядке. Это зависит от контекста. Однако, если вам действительно не нужно, чтобы он был указателем или целью по определенной причине, и вы просто рассматриваете его как массив, тогда вам лучше объявить его массивом предполагаемого размера, чтобы избежать возможных проблем с памятью.

+0

Большое вам спасибо. Это очень помогло. – user79973

Смежные вопросы