我想创建一个数组,其数量基于满足另一个数组中某个条件的元素数量。这需要我初始化一个数组中间例程,Fortran不会让我这样做。
有办法吗?
示例例程:
subroutine example(some_array)
real some_array(50) ! passed array of known dimension
element_count = 0
do i=1,50
if (some_array.gt.0) then
element_count = element_count+1
endif
enddo
real new_array(element_count) ! new array with length based on conditional statement
endsubroutine example
谢谢!
答案 0 :(得分:4)
您的问题不是初始化数组,而是涉及设置其值。
然而,有一种方法可以做你想要的。您甚至可以选择,具体取决于它的一般程度。
我假设element_count
表示在该循环中有some_array(i)
。
您可以new_array
allocatable
:
subroutine example(some_array)
real some_array(50)
real, allocatable :: new_array(:)
allocate(new_array(COUNT(some_array.gt.0)))
end subroutine
或者将它作为自动对象:
subroutine example(some_array)
real some_array(50)
real new_array(COUNT(some_array.gt.0))
end subroutine
后者仅在您的情况“简单”时才有效。 allocatable
情况更为通用,例如当您想要使用完整循环而不是count
内在函数时。
在这两种情况下,您都满足在可执行语句之前拥有所有声明的要求。
[作为旁注,在Fortran 2008下,block
构造允许自动对象,即使在可执行语句之后。]
答案 1 :(得分:2)
试试这个
real, dimension(50) :: some_array
real, dimension(:), allocatable :: other_array
integer :: status
...
allocate(other_array(count(some_array>0)),stat=status)
在这个语句序列other_array
的末尾,some_array
的每个元素都有一个元素大于0,没有必要写一个循环来计算非零元素some_array
。
按照@ AlexanderVogt的建议,检查allocate
声明的状态。
答案 2 :(得分:1)
您可以使用allocatable
数组执行此任务:
subroutine example(some_array)
real :: some_array(50)
real,allocatable :: new_array(:)
integer :: i, element_count, status
element_count = 0
do i=lbound(some_array,1),ubound(some_array,1)
if ( some_array(i) > 0 ) then
element_count = element_count + 1
endif
enddo
allocate( new_array(element_count), stat=status )
if ( status /= 0 ) stop 'cannot allocate memory'
! set values of new_array
end subroutine
答案 3 :(得分:1)
您需要使用allocatable
数组(请参阅this article for more on it)。这会改变你的日常工作
subroutine example(input_array,output_array)
real,intent(in) :: input_array(50) ! passed array of known dimension
real, intent(out), allocatable :: output_array(:)
integer :: element_count, i
element_count = 0
do i=1,50
if (some_array.gt.0) element_count = element_count+1
enddo
allocate(output_array(element_count))
end subroutine
请注意,intent
可能没有必要,但可能是很好的做法。如果您不想调用第二个数组,则可以创建重新分配子例程;虽然这需要将数组声明为allocatable
。