Fortran动态数组扩充理解

  利用Fortran算法实现过程中,会使用大量动态数组,在动态数组append的时候,会遇到扩充数组长度的问题,近期在网上看到一种之前没见过的动态数组扩充方法,并对其进行测试,这里将测试情况和另外一种常用的动态数组扩充方法进行总结。

数组扩充方法一

测试示例

program test_4

integer,allocatable :: iv1(:)
real(8),allocatable :: iV2(:) 
complex(8),allocatable :: iV3(:)
logical,allocatable :: iv4(:)
character(len=3),allocatable :: iv5(:)

integer :: i
integer :: num1
real(8) :: num2
complex(8) :: num3
logical :: num4
character(len = 3) :: num5

! integer
iv1 = [integer ::]  !< an empty array, empty array constructor
do i = 1,4
    num1 = i
    iv1 = [iv1,num1]      !< append array
enddo
print *,"interer = ",(iv1(i),i=1,4)

! real(8)
iv2 = [real(8) ::]  
do i = 1,4
    num2 = real(i,8)
    iv2 = [iv2,num2]      
enddo
print *,"real(8) = ",(iv2(i),i=1,4)

! 
iv3 = [complex(8) ::]  
do i = 1,4
    num3 = cmplx(i,1E-2)
    iv3 = [iv3, num3]  
enddo
print *,"complex = ",(iv3(i),i=1,4)

! logical
iv4 = [logical ::]  
do i = 1,4
    num4 = (mod(i,2)==0)
    iv4 = [iv4, num4]  
enddo
print *,"logical = ",(iv4(i),i=1,4)

! character(3)
iv5 = [character(3) ::] 
do i = 1,5
    num5 = "aaa"
    iv5 = [iv5, num5]  
enddo
print *,"character(3) = ",(iv5(i),i=1,4)

end program

运行结果

 interer =  1   2   3   4
 real(8) =  1.00   2.00   3.000   4.00
 complex =  
    (1.0,9.999999776482582E-003) 
    (2.0,9.999999776482582E-003)
    (3.0,9.999999776482582E-003)
    (4.0,9.999999776482582E-003)
 logical =  F T F T
 logical = aaa aaa aaa aaa aaa

  上边是F90 常见数据类型动态数组扩充的示例,并没有出现allocate等关键字,Console下可以正常运行,说明基础数据类型都可以用上边方法进行数组扩充;从示例可以看到最关键的两句是:(以integer为例子)

! integer
iv1 = [integer ::]  !< an empty array, empty array constructor
iv1 = [iv1,num1]      !< append array

  之前没用过这样的扩充方法,所以不知道其语法版本,也没查到,为了进一步理解该方法的适用性,又做了两个测试,仅调整了数据类型,测试1整形二维数组;测试二 Type类型;
(1)测试1 - 二维数组

! 示例
program Test_1

    integer,allocatable :: iv1(:,:)
    integer :: i,j
    integer :: num1

    ! integer
    iv1 = [integer ::]  !< an empty array, empty array constructor
    do i = 1,4
        do j = 1,3
            num1 = i*j
            iv1 = [iv1,num1]      !< append array
        enddo
    enddo
    do j = 1,3
        print *,"interer = ",(iv1(i),i=1,4)
    enddo

end program

测试1编译报错,显示数组维度不一致,应该和 iv1 = [inte] 有关,暂时不知道怎么改,有理解的可以交流一下;

(2)测试2 – type

program test_3

    type :: Vec_type
        real(8) :: x
        real(8) :: y
        real(8) :: z
    end type
    type(Vec_type),allocatable :: iV(:) 
    integer :: i
    type(Vec_type) :: v1

    iv = [Vec_type ::]  !< an empty array, empty array constructor
    do i = 1,4
        v1.x = 0.d0
        v1.y = 0.d0
        v1.z = 0.d0
        iv = [iv,v1]      !< append array
    enddo
    print *,iv
end program

测试二同样编译报错,错误显示 Compilation Aborted (code 1) 这个错误类型还不能确定具体问题,我想应该和测试一的问题是一样的。

  暂时综上,该扩充方法对基础数据类型一维数组扩充是比较容易的,但其有很大的适用局限,除基础类型一维数组外其他类型均无法使用。

数组扩充方法2

  该方法适用性强,逻辑简单,下面以integer数组的扩充为例,写了个Subroutine,其他类型(Type、Pointer)的动态数组扩充都可以根据该方法简单修改实现:

!!整形数组扩充2倍
subroutine Array_Extend(array)
    implicit none
    integer,allocatable :: array(:) ! 要对array进行扩充2倍    

    integer,allocatable :: array2(:)
    integer :: size1

    if(allocated(array) == .false.)return  ! 数组未分配,不用扩充
    size1 = size(array)
    allocate(array2(2*size1))  ! 临时数组,接收原始数组数据
    ! allocate(array2(size1+1) ! 每次扩充1个长度
    array2(1:size1) = array(1:size1)
    call move_alloc(array2,array) ! 临时数组释放,并将分配的空间赋给array
end subroutine

小结

  Fortran动态数组扩充总结两个方法,如果还有更好的方法可以分享一下思路呦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咋(za)说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值