如何在Fortran 90中向动态数组添加新元素 [英] How to add new element to dynamical array in Fortran 90

查看:542
本文介绍了如何在Fortran 90中向动态数组添加新元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我最初无法预测数组的确切大小时,我需要在Fortran 90中使用动态数组。所以我写了一段代码,每次将新元素添加到数组末尾时,它都应该扩展可分配数组:

I need to use dynamical arrays in Fortran 90 for cases when I can't predict exact size of array initially. So I wrote a code, which should expand allocatable array each time new element is added to the end of array:

  subroutine DArray()

  double precision, dimension(:), allocatable :: list

  allocate(list(1))

  list(1) = 1.1

  call AddToList(list, 2.2)
  call AddToList(list, 3.2)
  call AddToList(list, 4.2)
  call AddToList(list, 5.2)

  print *, list(1)
  print *, list(2)
  print *, list(3)
  print *, list(4)
  print *, list(5)


  end



  subroutine AddToList(list, element)

  double precision :: element
  double precision, dimension(:), allocatable :: list
  double precision, dimension(:), allocatable :: clist

  if(allocated(list)) then
    isize = size(list)
    allocate(clist(isize+1))
    do i=1,isize
        clist(i) = list(i)
    end do
    clist(i+1) = element

    deallocate(list)
    allocate(list(isize+1))

    do i=1,isize+1
        list(i) = clist(i)
    end do

    deallocate(clist)

  end if


  end

那么有人看到我在这里是否遗漏了什么吗?

So does anyone see if I missing something here?

francescalus 解决。

双精度工作代码动态数组是:

Working code for double precision dynamical arrays is:

  module DynamicalArrays

  contains

      subroutine AddToList(list, element)

          IMPLICIT NONE

          integer :: i, isize
          double precision, intent(in) :: element
          double precision, dimension(:), allocatable, intent(inout) :: list
          double precision, dimension(:), allocatable :: clist


          if(allocated(list)) then
              isize = size(list)
              allocate(clist(isize+1))
              do i=1,isize          
              clist(i) = list(i)
              end do
              clist(isize+1) = element

              deallocate(list)
              call move_alloc(clist, list)

          else
              allocate(list(1))
              list(1) = element
          end if


      end subroutine AddToList


  end module DynamicalArrays

可以从中填充数组的演示子例程为:

The demo subroutine, from which array can be filled would be:

  subroutine UserDArrayTest()

  use DynamicalArrays


  integer :: i
  double precision, dimension(:), allocatable :: list
  double precision :: temp

  temp = 0.1
  do i=1,10
    temp = temp+1
    call AddToList(list, temp)
  end do

  do i=1,10
    print *, i, list(i)
  end do


  end

请注意,最好将模块代码保存在单独的文件中,但是我也发现当模块代码位于主程序和子例程代码之上。

Note that it's best to keep module code in the separate file, but I also find out that it works when module code is above main program and subroutine codes.

推荐答案

我怀疑是人工制品,您注意到了问题-但很快

I suspect, looking at an artefact, that you noticed the problem - but quickly moved on.

对我来说,可疑之处是:

The suspicious line, to me is:

    allocate(clist(isize+2))

为什么新大小不是 isize + 1 ?我猜您尝试过,但随后程序失败。

Why isn't the new size isize+1? I guess that you tried that, but then the program failed.

了解为什么程序失败(可能崩溃)是您无法获得正确结果的关键。仔细查看循环(为清楚起见,删除了打印语句)。

Seeing why the program failed (possibly crashed) is key to why you aren't getting the correct result. Look closely at the loop (print statement removed for clarity).

do i=1,isize
    clist(i) = list(i)
end do
clist(i+1) = element

您想说将所有元素从列表复制到clist,然后追加元素。哪个是正确的。但是

You want to say "copy all elements from list to clist, then append element". Which is correct. However

do i=1,isize
    clist(i) = list(i)
end do
! Here, i=isize+1
clist(i+1) = element
! Which means
! clist(isize+2) = element.

总而言之,在循环之后,循环索引变量没有最终值迭代。

In summary, after the loop the loop index variable doesn't have the value it had in the final iteration.

这篇关于如何在Fortran 90中向动态数组添加新元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆