如何在Fortran中声明变量中间例程

时间:2014-01-10 14:23:59

标签: fortran

我想创建一个数组,其数量基于满足另一个数组中某个条件的元素数量。这需要我初始化一个数组中间例程,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

谢谢!

4 个答案:

答案 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