Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Fortran:指针数组的数组?_Arrays_Fortran - Fatal编程技术网

Arrays Fortran:指针数组的数组?

Arrays Fortran:指针数组的数组?,arrays,fortran,Arrays,Fortran,我正在使用一些Fortran代码(在本项目之前我从未使用过这些代码…),遇到了一个问题。我需要与另一个程序共享一些内存空间。为了让Fortran识别每个内存块,我使用以下代码:        do 10 i = 0, 5        CALL C_F_POINTER(TRANSFER(memory_location + : VarNamesLoc_(i),        : memory_location_cptr) , VarNames_(i), [3])       

我正在使用一些Fortran代码(在本项目之前我从未使用过这些代码…),遇到了一个问题。我需要与另一个程序共享一些内存空间。为了让Fortran识别每个内存块,我使用以下代码:

       do 10 i = 0, 5 
       CALL C_F_POINTER(TRANSFER(memory_location +
       : VarNamesLoc_(i), 
       : memory_location_cptr) , VarNames_(i), [3]) 
       exit 
    10 continue
其中:

VarLoc(i)是表示内存位置的整数

VarNames(i)?指针数组的数组

我遇到的问题是创建指针数组的VarNames数组。我在谷歌上找到了一些示例代码,但我发现Fortran很难理解!!有人能告诉我如何设置指针数组吗?或者如果我处理问题的方法不正确,请指出另一种选择

作为参考,Fortran代码以自由形式编写,并使用intel编译器


谢谢你的帮助

好的,我假设冒号与连续行有关,忽略它们,然后尝试这样做:

do i = 0, 5 
    CALL C_F_POINTER(&
          TRANSFER(memory_location + VarNamesLoc_(i), memory_location_cptr), &
          VarNames_(i), [3] ) 
enddo 
这样做的目的是:(传输)获取一个表示现有C指针的整数(我假设)
内存位置
,在其上添加一个偏移量(
VarNamesLoc\ui)
),并将其转换为一种类型的
C\u ptr
。然后(C_F_指针)将其转换为Fortran形式的指针[3]

我认为在Fortran端执行C指针算法不是一个好主意,但是

因此,您希望
VarNames\uu
是一个由5个指针组成的数组,指向3的数组。。有些事,你还没说。让我们说整数

让我们从一个简单的例子来看:假设我们在C中有一个一维整数数组,在Fortran中需要一个指向它们的指针。如果我们的C例程是这样(
croutine.C
):

和这样的生成文件:

FC=gfortran
CC=gcc
CFLAGS=-std=c99 -g
FFLAGS=-g

main: driver.o croutine.o 
        $(FC) -o $@ $^

driver.o: driver.f90
        $(FC) $(FFLAGS) -c $<

clean:
        rm -rf main driver.o croutine.o 
注意,在C中,我们分配了一个5个整数的数组;Fortran程序主要是定义C例程的接口,以便我们可以从Fortran调用它们,然后调用它们。
c\u f\u指针执行c指针(
cdata
)和Fortran指针(
fdata
)之间的转换

如果我们想用Fortran做一些C指针算法,我们可以这样做:

但我真的不建议这样做;最好在Fortran中执行指针操作:

type(c_ptr) :: cdata
integer, pointer, dimension(:) :: fdata, newfdata
integer                        :: n = 5

call makearray(cdata, n);
call c_f_pointer(cdata, fdata, [n])

newfdata => fdata(3:n)
print *, 'newfdata = ', newfdata
call freearray(cdata, n)
type(c_ptr) :: cdata
integer                        :: n = 10
integer, parameter             :: nptrs = 5
integer :: i, intsperptr
integer(kind=c_int) :: cint
integer(kind=int64) :: cdata_as_int

! our new "ptrelement" type which we can define arrays of
type ptrelement
     integer, pointer, dimension(:) :: p
end type ptrelement
type(ptrelement) :: ptrs(nptrs)

call makearray(cdata, n);
cdata_as_int = TRANSFER(cdata, cdata_as_int)

intsperptr = n/nptrs
do i=1,nptrs
    call c_f_pointer( &
         TRANSFER(cdata_as_int + (i-1)*intsperptr*c_sizeof(cint), cdata),&
         ptrs(i)%p, [intsperptr] )
enddo

do i=1,nptrs
    print '(A,I2,A,99(I5,X))', 'ptrs(',i,')%p = ', ptrs(i)%p
enddo

call freearray(cdata, n)
更干净,不太可能导致wierd错误,而且更小

最后,让我们做一个指针数组。不可否认,这比在Fortran中更难,因为Fortran不容易让您定义指针数组;您必须创建一个已定义的类型(Fortran相当于C中的结构)。但这很容易。让我们按照我推荐的方式来做,在Fortran端做指针数学:

type(c_ptr) :: cdata
integer, pointer, dimension(:) :: fdata
integer                        :: n = 10
integer, parameter             :: nptrs = 5
integer :: i, intsperptr, istart, iend

! our new "ptrelement" type which we can define arrays of
type ptrelement
     integer, pointer, dimension(:) :: p
end type ptrelement
type(ptrelement) :: ptrs(nptrs)

call makearray(cdata, n);
call c_f_pointer(cdata, fdata, [n])

intsperptr = n/nptrs
do i=1,nptrs
    istart = (i-1)*intsperptr+1
    iend   = istart + intsperptr-1
    ptrs(i)%p => fdata(istart:iend)
enddo

do i=1,nptrs
    print '(A,I2,A,99(I5,X))', 'ptrs(',i,')%p = ', ptrs(i)%p
enddo

call freearray(cdata, n)
在这里,我们创建了一个类型
ptrellment
,它是一个一维指针数组,然后创建了这些指针数组。这为我们提供了指针数组,我们通过对
fdata
进行切片来设置指针数组,它仍然是指向整个数据的指针

跑步给我们力量

$ ./main
ptrs( 1)%p =     0     1
ptrs( 2)%p =     2     3
ptrs( 3)%p =     4     5
ptrs( 4)%p =     6     7
ptrs( 5)%p =     8     9
或者,正如我不建议的那样,在Fortran中进行C型指针数学运算:

type(c_ptr) :: cdata
integer, pointer, dimension(:) :: fdata, newfdata
integer                        :: n = 5

call makearray(cdata, n);
call c_f_pointer(cdata, fdata, [n])

newfdata => fdata(3:n)
print *, 'newfdata = ', newfdata
call freearray(cdata, n)
type(c_ptr) :: cdata
integer                        :: n = 10
integer, parameter             :: nptrs = 5
integer :: i, intsperptr
integer(kind=c_int) :: cint
integer(kind=int64) :: cdata_as_int

! our new "ptrelement" type which we can define arrays of
type ptrelement
     integer, pointer, dimension(:) :: p
end type ptrelement
type(ptrelement) :: ptrs(nptrs)

call makearray(cdata, n);
cdata_as_int = TRANSFER(cdata, cdata_as_int)

intsperptr = n/nptrs
do i=1,nptrs
    call c_f_pointer( &
         TRANSFER(cdata_as_int + (i-1)*intsperptr*c_sizeof(cint), cdata),&
         ptrs(i)%p, [intsperptr] )
enddo

do i=1,nptrs
    print '(A,I2,A,99(I5,X))', 'ptrs(',i,')%p = ', ptrs(i)%p
enddo

call freearray(cdata, n)

哇,这是古代(fortran 77或更早版本)和现代(fortran 2003)构造的一个非常混乱的混合体。你能澄清要转移的论点吗?那些冒号在那里干什么?那个出口真的在那里吗?哇,谢谢你详细的回答,乔纳森!我今天会消化它,让你知道我的进展如何。您对冒号的假设是正确的,自由形式使用冒号而不是“&”(我正在处理的Fortran代码可以追溯到80年代初!)
$ ./main
ptrs( 1)%p =     0     1
ptrs( 2)%p =     2     3
ptrs( 3)%p =     4     5
ptrs( 4)%p =     6     7
ptrs( 5)%p =     8     9
type(c_ptr) :: cdata
integer                        :: n = 10
integer, parameter             :: nptrs = 5
integer :: i, intsperptr
integer(kind=c_int) :: cint
integer(kind=int64) :: cdata_as_int

! our new "ptrelement" type which we can define arrays of
type ptrelement
     integer, pointer, dimension(:) :: p
end type ptrelement
type(ptrelement) :: ptrs(nptrs)

call makearray(cdata, n);
cdata_as_int = TRANSFER(cdata, cdata_as_int)

intsperptr = n/nptrs
do i=1,nptrs
    call c_f_pointer( &
         TRANSFER(cdata_as_int + (i-1)*intsperptr*c_sizeof(cint), cdata),&
         ptrs(i)%p, [intsperptr] )
enddo

do i=1,nptrs
    print '(A,I2,A,99(I5,X))', 'ptrs(',i,')%p = ', ptrs(i)%p
enddo

call freearray(cdata, n)