【问题标题】:Initialize a multdimensional array in C similar to Fortran在 C 中初始化一个类似于 Fortran 的多维数组
【发布时间】:2013-03-02 21:45:17
【问题描述】:

我在 FORTRAN 90 中编写了一个小测试用例程序,它初始化切片中的 3d 数组。可以在 C 中轻松复制相同的行为吗?

  program fortranEngine

  real(4) , dimension(10,10) :: tmp
  real(4) , dimension(10,10,3) :: p    

  tmp = RESHAPE( [  0.973, 1.053, 0,     0,     0,     0,     0,     0,     0,     0, &
                    1.053, 1.080, 0,     0,     0,     0,     0,     0,     0,     0, &
                    1.010, 0.408, 0.442, 0,     0,     0,     0,     0,     0,     0, &
                    1.119, 0.900, 0.399, 0.762, 0,     0,     0,     0,     0,     0, &
                    1.211, 0.975, 0.845, 0.952, 1.105, 0,     0,     0,     0,     0, &
                    1.248, 1.016, 0.485, 0.000, 0.000, 1.110, 0,     0,     0,     0, &
                    1.225, 1.123, 1.056, 0.000, 0.000, 0.949, 0.832, 0,     0,     0, &
                    1.138, 1.232, 1.089, 1.050, 0.930, 0.402, 0.789, 0.774, 0,     0, &
                    1.149, 1.406, 1.201, 1.052, 0.416, 0.878, 0.896, 0.431, 1.144, 0, &
                    1.351, 1.255, 1.290, 1.358, 1.240, 1.228, 1.257, 1.140, 1.123, 1.228] &
                    , [10,10] )    

    p(:,:,1) = tmp    

    ...

    end program fortranEngine

【问题讨论】:

  • 为什么要在 C 中复制这个?只需从 C 程序中调用 Fortran 例程即可。
  • 试试[this][1],看起来很简单。 [1]:stackoverflow.com/questions/2178909/…
  • 与往常一样,real(4) 可能不会做你可能认为它会做的事情。特别是它不等同于 real*4

标签: c fortran


【解决方案1】:

您或多或少可以在 C99 或 C2011 中执行此操作,但不如在 Fortran 中方便。当心initialization订单; Fortran 以一种顺序(以列为主),而 C 以另一种顺序(以行为主)。忽略这一点,您可以这样做:

float tmp[10][10] =
{
    { 0.973, 1.053, 0,     0,     0,     0,     0,     0,     0,     0,    },
    { 1.053, 1.080, 0,     0,     0,     0,     0,     0,     0,     0,    },
    { 1.010, 0.408, 0.442, 0,     0,     0,     0,     0,     0,     0,    },
    { 1.119, 0.900, 0.399, 0.762, 0,     0,     0,     0,     0,     0,    },
    { 1.211, 0.975, 0.845, 0.952, 1.105, 0,     0,     0,     0,     0,    },
    { 1.248, 1.016, 0.485, 0.000, 0.000, 1.110, 0,     0,     0,     0,    },
    { 1.225, 1.123, 1.056, 0.000, 0.000, 0.949, 0.832, 0,     0,     0,    },
    { 1.138, 1.232, 1.089, 1.050, 0.930, 0.402, 0.789, 0.774, 0,     0,    },
    { 1.149, 1.406, 1.201, 1.052, 0.416, 0.878, 0.896, 0.431, 1.144, 0,    },
    { 1.351, 1.255, 1.290, 1.358, 1.240, 1.228, 1.257, 1.140, 1.123, 1.228 },
};
float p[3][10][10];    

for (int i = 0; i < 3; i++)
    memmove(p[i], tmp, sizeof(tmp));

请注意,我将维度 [3] 从声明的末尾移到了声明的开头。反过来,在 C 中就没有多大意义了。因此,这种表示法或多或少是可用的,但是存储管理的细节使得如何准确地实现您想要的东西变得不那么明显了。

【讨论】:

    【解决方案2】:

    这够简单吗?

    for(int i = 0 ; i < 10 ; ++i) 
        for(int j = 0 ; j < 10 ; ++j )
            p[0][i][j] = tmp[i][j] ;
    

    【讨论】:

    • 或者,如果您不介意 tmp 和 p 共享空间,您可以声明 double (*p[3])[10][10] ; 并分配 p[0] = &amp;(tmp[0][0]) ;。然而,其他两个切片由空指针表示。
    • 这些数组的数组与 Fortran 3D 数组并不完全相同。
    • @Vladimir F. 如果你的意思是我评论中的那个,你是对的。对于我的回答,我假设 p 被声明为 double [3][10][10];,我认为它类似于 fortran。但是,自从 f77 天以来,我就没有使用过 fortran,所以可能发生了一些变化。
    • 对于这个简单的案例你是对的,我没有检查声明。但是通常不会使用小的静态分配数组。
    猜你喜欢
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 2013-05-29
    • 1970-01-01
    • 2021-04-04
    • 2011-04-03
    相关资源
    最近更新 更多