如何通过函数实现Fortran可分配数组的扩容?
Fortran 用函数实现可分配数组扩容的示例
你目前用全局数组+子程序实现了数组扩容,以下是用函数实现相同功能的方案,同时解释数组传递给函数的关键要点:
原代码回顾
program grow_an_array implicit none integer ,dimension(:),allocatable :: num1,num2 integer :: n allocate(num1(10)) do n=1,50 !note that n goes beyond the bounds of array num1 if(n>size(num1,dim=1))call growarray() num1(n)=n end do print * contains subroutine growarray() implicit none allocate(num2(size(num1,dim=1)+1)) num2(1:size(num1))= num1(1:size(num1,dim=1)) call move_alloc(num2,num1) end subroutine end program
推荐方式:函数返回扩容后的数组
这种方式符合Fortran函数的设计逻辑,通过返回新数组实现扩容,主程序直接赋值给原数组即可:
program grow_an_array_func implicit none integer, dimension(:), allocatable :: num1 integer :: n allocate(num1(10)) do n = 1, 50 if (n > size(num1)) then num1 = growarray(num1) ! 调用函数并更新原数组 end if num1(n) = n end do ! 验证结果 print *, "最终数组大小:", size(num1) print *, "数组末尾5个元素:", num1(46:50) contains ! 定义扩容函数:接收可分配数组,返回扩容后的新数组 function growarray(arr) result(new_arr) implicit none integer, dimension(:), allocatable, intent(in) :: arr ! 输入原数组(只读) integer, dimension(:), allocatable :: new_arr ! 函数返回的扩容后数组 ! 扩容为原大小+1(实际场景建议按比例扩容,比如size(arr)*2,减少分配次数) allocate(new_arr(size(arr) + 1)) ! 复制原数组内容到新数组 new_arr(1:size(arr)) = arr end function growarray end program grow_an_array_func
关键说明
- 不需要使用指针,可分配数组直接作为函数的参数和返回值即可完成传递。
- 输入参数
arr声明为intent(in),明确它是只读的,避免意外修改原数组。 - 函数内部创建新的可分配数组
new_arr,完成扩容和复制后返回;主程序中赋值给num1时,Fortran会自动处理旧内存的释放和新内存的接管。 - 注意:每次扩容+1的效率较低,实际开发中建议按比例(比如翻倍)扩容,减少内存分配的开销。
不推荐方式:用函数直接修改输入数组
如果一定要让函数直接修改原数组(不需要主程序赋值),可以用intent(inout)参数,但这种方式不符合函数的设计初衷(函数应返回结果,而非修改输入),更适合用子程序实现:
program grow_an_array_func_inout implicit none integer, dimension(:), allocatable :: num1 integer :: n, dummy allocate(num1(10)) do n = 1, 50 if (n > size(num1)) then dummy = growarray_inout(num1) ! 调用函数修改原数组,接收哑元返回值 end if num1(n) = n end do contains ! 用函数修改输入数组(不推荐) function growarray_inout(arr) result(dummy_val) implicit none integer, dimension(:), allocatable, intent(inout) :: arr ! 可修改的输入数组 integer, dimension(:), allocatable :: temp integer :: dummy_val ! 函数必须返回值,此处为哑元 allocate(temp(size(arr)+1)) temp(1:size(arr)) = arr call move_alloc(temp, arr) ! 将新数组的内存转移给原数组 dummy_val = 0 ! 返回无关值满足函数要求 end function growarray_inout end program grow_an_array_func_inout
内容的提问来源于stack exchange,提问作者kris44dad
相关产品推荐
相关产品推荐

