【问题标题】:Print a Fortran 2D array as a matrix将 Fortran 二维数组打印为矩阵
【发布时间】:2018-10-01 18:44:17
【问题描述】:

我有一个当前为 3x3 的数组。当我打印出字符时,我会以环绕线样式打印结果。我希望打印一个更具可读性的方阵 而不是 XXXXXXXXXXXXX 在一行上。是否可以使用 do 循环?

我有以下几点:

CHARACTER(len=1) :: Grid(2,2)
Grid = "*"
Print *, Grid

【问题讨论】:

    标签: fortran


    【解决方案1】:

    根据您想要的输出格式,您不一定需要 do-loop,这是最简单的:

    program simple
        implicit none
        CHARACTER(len=1) :: Grid(2,2)
        Grid = reshape( ["1","2","3","4"] , shape=shape(Grid) )
        write( * , "(A)" ) Grid
    end program simple
    

    reshape 的行使用 Fortran >2003 数组构造函数语法 []。因此,请确保您的编译器设置已设置为 Fortran 2008 标准。否则,只需将 [] 替换为旧的数组构造函数语法 (//)

    如果您希望将每一行打印在不同的行上,那么循环将是必要的,至少,一个隐含的do-loop

    program simple
        implicit none
        integer :: i,j
        integer, parameter :: n=2
        CHARACTER(len=1) :: Grid(n,n)
        Grid = reshape( ["1","2","3","4"] , shape=shape(Grid) )
        write( * , "(*(g0))" ) ( (Grid(i,j)," ",j=1,n), new_line("A"), i=1,n )
    end program simple
    

    我相信,上述版本避免了编译器创建不必要的临时数组来存储非传染性数组部分Grid(i,:),然后再将其打印到输出。 g0 编辑描述符是 Fortran 2008 的一个方便的功能。所以请确保您的编译器支持 Fortran 2008 标准。

    【讨论】:

    • [] 是 >= 2003,所以 2003 合规性就足够了。此外,OP 要求以矩阵样式(逐行)打印,而不是每个元素一行
    【解决方案2】:

    类似于一次打印一个数组行:

    program printarray
      implicit none
      CHARACTER(len=1) :: Grid(3,2)
      integer :: i
      Grid = "x"
      do i = 1, ubound(Grid, 1)
         print *, Grid(i, :)
      end do
    end program printarray
    

    或者,可以依赖于这样一个事实,即如果要编写的内容多于格式说明符中的元素,则它会切换到新行。所以,类似:

    program printarray2
      implicit none
      CHARACTER(len=1) :: Grid(4,2)
      character(len=10) :: fmt
      Grid = "x"
      write(fmt, '(A,I0,A)') '(', ubound(Grid, 2), 'A)'
      write(*, fmt) transpose(grid)
    end program printarray2
    

    这里有一个小技巧,打印整个数组会按内存顺序打印,这是 Fortran 中的主要列。这就是为什么你必须转置它(以及为什么你在创建格式字符串时采用维度 2 的 ubound 而不是第一个示例中的 1)。

    【讨论】:

    • 您的第二种方法似乎令人震惊,您能否向我解释一下它是如何工作的/向我推荐一个可以阅读更多有关其用法的来源?
    • 第一个 write 语句创建一个具有正确重复计数的格式字符串,第二个写入实际数组。
    【解决方案3】:
    do mi=1, 6
        do ni=1, 6
            write(*,"(ES8.1,$)") real(H(mi,ni))
        end do
        write (*,*) ''
    end do
    

    【讨论】:

    • edit您的回答添加有关此(非标准)代码示例的作用以及为什么它比符合标准的替代方案更好的详细信息。
    • 另见*.com/questions/28724722/… 当然,请不要只是将一段代码转储到答案中,而是告诉我们代码的作用。