program test
implicit none
real(dp),allocatable :: a(:), b(:)
allocate (a(10))
a = 1.d0
(*) b = a
end program
在上面的代码中,我设置了两个可分配对象——a
和b
——并且只在代码中分配了a
。我预计代码无法编译,但它编译得很好,而且似乎运行良好,而下面的代码(执行类似工作)显示 SEGFAULT。
program test_fail
implicit none
real(dp),allocatable :: a(:), b(:)
integer :: i
allocate ( a(10) )
a = 1.d0
do i = 1, 10
b(i) = a(i)
enddo
end program
可以理解为前面的代码自动分配b
吗?
subroutine test_sub(a)
implicit none
real(dp),intent(inout) :: a(:,:)
...
end program
还有在上面的子程序中输入整形数组,可以理解代码自动检测输入数组a
的大小,并在子程序中分配自己的数组并释放它返回到它的上框架?
最后,当我将一个数组复制到另一个数组时,哪个更快?
program speed1
implicit none
real(dp), allocatable :: a(:,:,:), b(:,:,:)
allocate( a(10000,10000,10000) )
a = 1.d0
b = a
end program
program speed2
implicit none
real(dp), allocatable :: a(:,:,:), b(:,:,:)
integer :: i, j, k
allocate( a(10000,10000,10000), b(10000,10000,10000) )
a = 1.d0
do i = 1,10000
do j = 1,10000
do k = 1,10000
b(i,j,k) = a(i,j,k)
enddo
enddo
enddo
end program
最佳答案
我没有太多时间,所以这可能相当压缩。还要注意,正如上面的评论中所指出的(为了突出和后代而在此处复制)代码的有效性以及此答案的有效性取决于版本(有关更多详细信息,请参见 this question)。
如你所见,声明
b = a
将自动将数组b
分配给与a
相同的大小(和形状),并赋予其元素与a的元素相同的值
。这一切都符合标准。但是,声明
b(i) = a(i)
左边没有array
,它有一个array element
,这种情况下Fortran不会自动分配数组。很不幸,但这是(我相信)语言标准不需要编译器发现错误的情况之一——这就是您在运行时发现错误的原因。您的编译器似乎与我最近使用过的其他编译器一样 - 实际上,没有元素 b(1)
可以将 a(1)
的值分配给, 等.
至于子程序中的'allocation'语句
real(dp),intent(inout) :: a(:,:)
这不太一样。这里的 a
是 assumed-shape 并且只是假定传递给例程的相应参数的形状(和值)。该标准没有说明这是如何完成的。大多数编译器不会复制数组(出于对 Fortran 程序员通常很重要的性能原因),但有些可能会,并且很容易构建大多数编译器将复制作为参数传递的数据结构的示例。
至于最后两个小码中哪个更快 - 为什么不告诉我们?
关于Fortran 90 自动(?)分配可分配对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62534248/