Fortran可变大小数组的数组

3

问题简述:

商店里恰好有maxSize个人在购物。每个人都有一个购物清单,其中包含物品的价格(以整数表示)。如何使用Fortran数组表示所有购物清单。购物清单可能包含任意数量的物品(1、10、1000000000等)。

(注意:实际问题要复杂得多。它甚至与购物无关。)

懒惰的方法是:

integer :: array(maxSize, A_REALLY_BIG_NUMBER)

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

显然的尝试注定要失败:

integer, allocatable :: array(:,:)
allocate(array(maxSize, :)) ! Compiler error

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

如果这是唯一的解决方案,我想我会使用它。但我有些希望能够使用内部函数来完成这个任务。为了实现如此简单的事情而定义一个自定义类型有点烦人。
在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)));

Fortran似乎也有指针。但我找到的所有教程都说“永远不要使用这些”或类似的话。


10
这是一篇抱怨,不是一个问题。 - High Performance Mark
3
这是Fortran中针对您想要完成的标准解决方案。它没有任何问题。Fortran指针也没有问题。我使用它们来处理数据结构,例如链表。如果可分配变量可以胜任,则建议不要使用指针。不要期望Fortran和C是相同的。 - M. S. B.
我肯定不是想通过发布 C 代码来冒犯大家! 我只是好奇是否有一种更好的方法在 Fortran 中实现,可能类似于 C 的解决方案。 - cerberus586
1个回答

8
你似乎在抱怨Fortran不是C语言。这是正确的。标准委员会选择以不同的方式处理事情可能有近乎无限的原因,但是以下是一些想法:
Fortran数组中的一个强大之处在于它们可以被切片。
a(:,:,3) = b(:,:,3)

这是一个完全有效的陈述。如果数组是“指向数组的指针数组”,那么沿着每个轴的维度不一定是一致的(这正是您要实现的情况)。

在C语言中,真正意义上的多维数组并不存在。您可以使用指向数组的指针数组来实现类似的功能,但这并不是真正的多维数组,因为它们没有共享同一块内存。这可能会影响性能。事实上,在高性能计算(HPC)领域(许多Fortran用户都在此领域中工作),多维C数组通常是一个1D数组,包装了一个宏来根据维度大小计算步幅。此外,像这样解引用一个7D数组:

a[i][j][k][l][m][n][o]

相对于以下内容,这段文字的输入难度要高一些:

a(i,j,k,l,m,n,o)

最后,您发布的解决方案最接近您试图模拟的C代码 -- 它有什么问题吗?请注意,针对您的问题陈述,可能需要更复杂的数据结构(如链接列表)(可在C或Fortran中实现)。当然,链接列表在性能方面是最糟糕的,但如果这不是一个问题,那么它可能是正确的数据结构,因为“购物者”可以决定将更多东西添加到他们的“购物车”中,即使它不在他们带去商店的购物清单上。


这是一个很好的答案,但我不能为它投票。谢谢。 - cerberus586
2
作为问题发布者,您不应该投票,而是接受或不接受问题。其他人会或不会为此答案投票(但问题已关闭)。 - Vladimir F Героям слава

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接