固定形式的 Fortran 分配数组,其大小要从文件中读取

Fixed form Fortran Allocate array with size to be read from file

我正在读取一个包含值 T 的文件,该文件将用于初始化多个数组,这些数组将以 T 作为第一个维度,稍后进行分配。即

subroutine read_file(T,F,array,A,B,C,...)
    ...
    real, intent(out) :: T,F
    real, intent(in) :: A,B,C
    real, intent(out) :: array
    ...
    read(1,*) T
    ...
    read(1,*) F
    ...
    read(1,*) array(1), array(5), array(6)
    read(1,*) array(2), array(4)
    read(1,*) array(3)
    ...
    if (F.eq.1) then
        array(1) = A(1)
        array(2) = B(2)
        array(3) = C(3)
    endif
    ...
program main
    ...
    do I=1,nproc
        ...
        do J=1,nsteps
            ...
            call read_file(T,F,array,A,B,C,...)
            ...
        enddo
        ...
        if (F.eq.1.and.etc.) then
            ...
            allocate(A(T,3))
            allocate(B(T,6))
            allocate(C(T))
            ...
        endif
        ...
    enddo

读取语句包含在 modules.for 模块的 read_file 子例程中。分配语句在 main.for 中,其中 read_file 也被调用。

子例程 read_file 还读取许多其他内容,并且在执行代码的 1 次过程中被调用多次,其中某些文件的 T 可能为零。

我需要将 A、B 和 C 传入 read_file。根据标志 F 的条件,它也在 read_file 中读取,A、B 和 C 中的值需要分配给数组 (1,6),否则将直接从文件中读取。

所以我想我的问题是:如何传入可能未分配大小的数组?我在代码中编写了检查以确保 A、B 和 C 不会被实际使用,除非它们以用户输入 T 给出的已知大小进行分配,但编译器一直给我问题。

我尝试编译代码,英特尔编译器首先返回错误,指出 A、B、C 的类型未在 read_file 中声明,因此我在 [= 中使用 T 和 real :: A(T,3) 声明它们=41=]。然后它说因为T是intent(out),它不能用来给A,B和C赋维,因为它们是intent(in)。所以我从 T 中删除了 intent(out)(因为它现在只是 real :: T)。

现在,错误显示:

If the actual argument is scalar, the dummy argument shall be scalar unless the actual argument is of type character or is an element of an array that is not assumed shape, pointer, or polymorphic.

我编辑了我的问题以提供更多代码并澄清我的问题。

感谢那些回答和评论的人,我现在知道我可以在子程序中声明一个变量为可分配的,这应该可以解决我的问题。

谢谢!

杰西

看来处理你描述的问题最安全的方法是让read_file处​​理分配,即将A,B,C传递给read_file as

real, intent(inout), allocatable :: A(:,:), B(:,:), C(:,:) 

使用 intent(inout) 允许您使用相同的 A,B,C 多次调用 read_file 而不会丢失之前调用的信息。如果不需要,请随意使用 intent(out)。将未分配的数组作为参数传递是可以的,只需确保在尝试任何访问之前进行分配即可。

在读入 T 之后,您可以在 read_file 中分配 A,B,C

如果无法使用 read_file 进行调整,或者您希望在 main 中进行分配,您也可以使用您描述的方法。首先,将 A、B、C 分配为虚拟数组

allocate(A(0,0), B(0,0), C(0,0)) 

您可以将其传递给 read_file 的第一次调用(允许大小为 0 的数组,只要确保您不要尝试访问它们的条目)。如果我理解正确的话,第一次调用不会对 A,B,C 执行任何操作,它们只需要在对 read_file 的后续调用中分配。如果是这种情况,在 main.for 中分配也有效。

获得T后,可以重新分配A,B,C

if(allocated(A)) deallocate(A)
allocate(A(T,3))

然后您可以将重新分配的数组传递给 read_file 的下一次调用。