零大小数组的分配和在数组构造函数中的使用

问题描述 投票:0回答:2

在下面的代码中,我试图分配一个大小为 0 的空数组,然后使用自动重新分配添加更多元素:

integer, allocatable :: a(:)

allocate( a(0) )        ! Line 1
print *, size( a )
print *, "a(:) = ", a

a = [ a, 1 ]
print *, "a(:) = ", a

a = [ a, 2 ]
print *, "a(:) = ", a

!! Error
! a = []
! a = [ integer :: ]

这段代码给出了预期的结果(例如,使用 gfortran 或 ifort -assume realloc_lhs)

           0
 a(:) = 
 a(:) =            1
 a(:) =            1           2

这里我有三个问题:

  • 首先,分配大小为零的数组如
    allocate( a( 0 ) )
    可以吗?
  • 如果我们省略这样的显式分配,
    a(:)
    会自动初始化为零大小的数组吗? (事实上 ,即使我注释掉第 1 行,代码似乎也能正常工作。)
  • 在像
    a = [a, 1]
    这样的数组构造函数中包含零大小的数组没有问题吗? (我也试过使用像
    a = []
    a = [integer::]
    这样的空数组构造函数,但它们没有编译,所以似乎是不允许的。)

编辑

如果我在上面的代码中取消注释

a = []
,gfortran5.3给出错误信息:

Error: Empty array constructor at (1) is not allowed

但是如果我只取消注释

a = [ integer :: ]
行,它就没有问题!因为我最初同时取消注释这两行,所以我误解了这两种方式都是非法的,但实际上后者似乎还可以(请参阅@francescalus 的回答)。

arrays fortran allocation
2个回答
9
投票

1 是的。 Fortran 非常适合大小为 0 的数组。

2

a(:)
不是 array 而是 array-section(尽管它包含整个数组)。自动重新分配未定义为适用于数组部分,所以

allocate(a(0))
a(:) = [1 2 3]

不起作用。在我的测试中,代码已编译并执行,但

a
的大小为
0

至于代码

a = [a,1]
是否应该工作,如果
a
之前没有分配(0-或任何其他大小)我对标准的理解是这不符合标准并且你的编译器(我的也是)是错误的。我希望这是我对标准的误读。也许其他人会过来并正确解释。

3 是

allocate(a(0))
a = [a, 1]

很好,它符合标准并按您的预期工作。正如您所注意到的,自动分配中不允许使用空数组构造函数


4
投票

High Performance Mark 的回答 涵盖了大部分内容,但还有更多要添加(或以不同方式重述)。关于

a
是否“初始化为零大小的数组”,它不是,您可以在另一个问题中看到更多细节。请特别注意,
a
最初是未定义的(和未分配的)。

正如您的其他答案所述,

a(:)
是一个数组部分,它不能在内部赋值时自动分配。可能值得注意的是,这是因为
a(:)
没有
allocatable
属性。这还有其他影响,例如不允许它与具有该属性的虚拟参数相关联。

在高层次上,是的,零大小的数组很好(再次,请参阅链接的问题,其中零大小和未分配之间存在有意义的差异)。您使用该

allocate
语句并在后续数组构造函数中使用的方法是完全合理的。

特别是,为了支持 High Performance Mark 的回答,不允许在数组构造函数中使用未分配的数组:不得引用未分配的变量。

开始构造零大小的数组:可以构造零大小的数组,零大小的数组用于对可分配变量的内部赋值没有什么特别之处。

构造数组时,必须知道数组的类型(和类型参数)。对于像

[a,1]
这样的数组构造函数(假设
a
是默认类型的整数),这个数组是默认类型的整数。编译器如何知道
[]
的类型/参数?

不能,这就是为什么零大小数组的数组构造函数的语法与您所拥有的一样:

[integer::]
是默认类型的(rank-1)零大小整数数组的数组构造函数.

在 Fortran 2008 中,您可以看到这种语法为 R468、R469 (4.8),类似的语法可以在 Fortran 2003 中找到。

最后,零大小的数组构造函数还有另一种方法:

integer i
print*, [(i, i=1,0)]
end
© www.soinside.com 2019 - 2024. All rights reserved.