1

这可能非常简单,但是在编译我的小 Fortran 程序时出现错误。(文件是 .f90)这与固定行长度与自由行长度有关吗?这似乎是我可以从谷歌搜索中收集到的全部信息。

这是程序:

program array
    integer :: k, n, i, j, h, f, AllocateStatus
    real*8, dimension(:, :, :), allocatable :: a
    character, parameter :: "fname"

k = 5
n = 5
h = 1
    allocate(a(n,k,h), stat = AllocateStatus)
    if (AllocateStatus /= 0) stop "*** Not enough memory ***"

    a(1,:,:) = 5
a(2,:,:) = 6

call writeArray(7,a,"testOutput")

deallocate(a)

end program array

subroutine writeArray(f,array,fname)
implicit none
integer :: f, i, j, k, n
character, parameter :: "fname"
real*8, dimension(:, :, :), allocatable :: array
        open(unit = f, file="fname")
    do, i=1,n
        do, j=1,k
                write(7,"(F5.2)") array(i,j,:)  
        if (j==k) write(7,"(A1)") "X"
        enddo
    enddo
    !write(7,"(I5)") size(a)

    close(f)
end subroutine writeArray

和错误:

test.f90:4.29:

character, parameter :: "fname"
                         1
Error: Invalid character in name at (1)
test.f90:24.26:

character, parameter :: "fname"
                      1
Error: Invalid character in name at (1)
test.f90:21.35:

subroutine writeArray(f,array,fname)
                               1
Error: Symbol 'fname' at (1) has no IMPLICIT type
4

3 回答 3

3

您不能使用引号来表示初始化。在你的子程序中,你应该有

CHARACTER(LEN=*) :: fname

代替你在那里的东西。您可能不需要PARAMETER带有字符声明的语句。fname在主程序中似乎不需要初始化。

我在您的代码中注意到的另一件事:(1)您不需要声明arrayALLOCATABLE(2)您应该从值开始 file UNITs >= 10 因为个位数的数字偶尔与 (reserved for? ) 标准输出。


另一个建议是你应该把你的writeArray子程序放在它自己的MODULE里面USE,或者把程序写成

PROGRAM Main
...
CONTAINS
  SUBROUTINE writeArray
  ...
  END SUBROUTINE
END PROGRAM

使用任何一种方法,您都会发现参数中的不一致。不仅如此,您还可以毫无问题地使用n变量k

于 2013-10-16T02:55:54.460 回答
2

附加评论:

您绝对不希望parameterfname-- 的声明中指定“变量”是常量,这与虚拟参数不一致。

您可以将参数声明为:

integer, intent (in) :: f
character (len=*), intent (in) :: fname
real*8, dimension(:, :, :), intent (in) :: array

您不需要在子例程中声明array为可分配的原因是您没有在子例程中更改其分配。您可以获得 和 的值n内在ksize,因此不需要将它们作为参数传递。

于 2013-10-16T03:09:47.590 回答
2

我完全同意@kyle。因此,在听取这些建议时,我还将向子例程声明变量的意图writeArray。因此,该计划将遵循以下原则:

program array
    integer :: k, n, h, AllocateStatus
    double precision, dimension(:, :, :), allocatable :: a
    character(len=1024) :: fname

    fname = "testOutput"
    k = 5
    n = 5
    h = 1
    allocate(a(n,k,h), stat = AllocateStatus)
    if (AllocateStatus /= 0) stop "*** Not enough memory ***"

    a(1,:,:) = 5
    a(2,:,:) = 6

    call writeArray(7,a,fname)

    deallocate(a)

contains

subroutine writeArray(f,array,fname)
    implicit none
    integer,                    intent(in) :: f
    integer                                :: i, j, k
    character(len=*),           intent(in) :: fname
    double precision, dimension(:, :, :), intent(in) :: array

    open(unit = f, file=fname)
    i = size(array, 1)
    k = size(array, 2)
    do, i=1,n
        do, j=1,k
                write(7,"(F5.2)") array(i,j,:)..
        if (j==k) write(7,"(A1)") "X"
        enddo
    enddo
    !write(7,"(I5)") size(a)

    close(f)
end subroutine writeArray

end program array 

另外我不喜欢使用real*8,我倾向于将其声明为real(kind=8)double precision

最后,根据您使用的编译器(因此它是标志),请尽量保持迂腐和健谈。对于 gfortran,我通常-Wall -pedantic在编译时使用这些选项。

于 2013-10-16T03:13:23.090 回答