Fortran可变大小数组的数组

cer*_*586 3 fortran multidimensional-array

问题的简化描述:

确实maxSize人在商店购物.他们每个都有一个购物清单,包含物品的价格(作为整数).使用Fortran数组,我如何表示所有购物清单.购物清单可以包含任意数量的项目(1,10,1000000000).

(注意:实际问题要复杂得多.甚至不是购物.)

懒惰的方法是:

integer :: array(maxSize, A_REALLY_BIG_NUMBER)
Run Code Online (Sandbox Code Playgroud)

然而,这是非常浪费的,我基本上希望第二个维度是可变的,然后单独为每个人分配它.

注定要失败的显而易见的尝试:

integer, allocatable :: array(:,:)
allocate(array(maxSize, :)) ! Compiler error
Run Code Online (Sandbox Code Playgroud)

Fortran似乎要求数组在每个维度上都有固定的大小.

这很奇怪,因为大多数语言将多维数组视为"数组数组",因此您可以单独设置"数组数组"中每个数组的大小.

下面是一些的工作:

type array1D
    integer, allocatable :: elements(:) ! The compiler is fine with this!
endtype array1D

type(array1D) :: array2D(10)
integer :: i

do i=1, size(array2D)
    allocate(array2D(i)%elements(sizeAt(i))
enddo
Run Code Online (Sandbox Code Playgroud)

如果这是唯一的解决方案,我想我会用它.但我有点希望有一种方法可以使用内在函数来做到这一点.必须为这么简单的东西定义自定义类型有点烦人.

在C中,由于数组基本上是具有花哨语法的指针,因此您可以使用指针数组执行此操作:

int sizeAt(int x); //Function that gets the size in the 2nd dimension
int * array[maxSize];

for (int x = 0; x < maxSize; ++x)
        array[x] = (int*)(calloc(sizeAt(x) , sizeof(int)));
Run Code Online (Sandbox Code Playgroud)

Fortran似乎也有指针.但我发现的唯一教程都说"永远不要使用这些"或类似的东西.

mgi*_*son 8

你似乎在抱怨Fortran不是C.这是真的.标准委员会选择以不同方式做事的原因可能有无数原因,但这里有一些想法:

fortran数组的一个强大功能是可以切片.

a(:,:,3) = b(:,:,3)
Run Code Online (Sandbox Code Playgroud)

是一个完全有效的声明. 如果数组是"指向数组的指针数组",则无法实现这一点,因为沿每个轴的维度不一定是一致的(您尝试实现的情况).

在C中,确实没有多维数组这样的东西.您可以使用指向数组的指针数组来实现看起来类似的东西,但这实际上并不是一个多维数组,因为它不共享一个公共的内存块.这可能会影响性能.事实上,在HPC(许多Fortran用户花费时间)中,多维C数组通常是包含在宏中的一维数组,以根据维度的大小计算步幅.另外,解除引用7D数组如下:

a[i][j][k][l][m][n][o]
Run Code Online (Sandbox Code Playgroud)

打字比打字更难:

a(i,j,k,l,m,n,o)
Run Code Online (Sandbox Code Playgroud)

最后,您发布的解决方案最接近您尝试模拟的C代码 - 它有什么问题?请注意,对于您的问题陈述,可能会有一个更复杂的数据结构(如链接列表)(可以在C或Fortran中实现).当然,就性能而言,链接列表是最糟糕的,但如果这不是一个问题,可能正确的数据结构用作"购物者"可以决定在他们的"购物车"中添加更多东西,即使它他们带到商店的购物清单上没有.

  • 你作为问题海报不应该投票,而是接受或不接受问题.其他人会或不会投票支持这个答案(但问题已经结束). (2认同)