<p>下面是一个Fortran函数返回可变长度数组的示例。这是Fortran 2003的一个特性。测试驱动程序中还使用了另一个Fortran 2003特性自动分配任务。</p>
<pre><code>module my_subs
contains
function select(x) result(y)
implicit none
integer, dimension (:), intent (in) :: x
integer, dimension (:), allocatable :: y
integer :: i, j
j = 0
do i=1, size (x)
if (x(i)/=0) j = j+1
enddo
allocate ( y (1:j) )
j = 0
do i=1, size (x)
if (x(i)/=0) then
j = j+1
y(j) = x(i)
endif
enddo
return
end function select
end module my_subs
program test
use my_subs
implicit none
integer, dimension (6) :: array = [ 5, 0, 3, 0, 6, 1 ]
integer, dimension (:), allocatable :: answer
answer = select (array)
write (*, *) size (array), size (answer)
write (*, *) array
write (*, *) answer
stop
end program test
</code></pre>
<p>这里有一个替代的解决方案,它使用一个临时数组来根据需要“增长”输出数组(函数返回)。虽然避免了两次通过输入数组,但需要数组副本。Fortran 2003的另一个特性move_alloc减少了所需的副本数量。move_alloc还负责输出数组(此处为“y”)的(重新)分配和输入数组的释放(此处为“temp”)。也许这更优雅,但由于使用了多个副本,因此效率可能更低。这个版本可能更具教育性,而不是实用性。@eryksun的版本使用一个pass和一个copy,代价是使临时数组达到最大。</p>
<pre><code>function select(x) result(y)
implicit none
integer, dimension (:), intent (in) :: x
integer, dimension (:), allocatable :: y, temp
integer :: i, j
j = 0
do i=1, size (x)
if (x(i)/=0) then
j = j+1
allocate (temp (1:j))
if ( allocated (y) ) temp (1:j-1) = y
call move_alloc (temp, y)
y(j) = x(i)
endif
enddo
return
end function select
</code></pre>