【问题标题】:Filling an array with unknown size in fortran90在fortran90中填充未知大小的数组
【发布时间】:2017-07-11 04:50:28
【问题描述】:

我想在 fortran90 中填充一个未知大小的数组。 这是 MATLAB 中的等效代码:

for i=1:10
 A[i] = i
end

我知道我可以通过大小,但是 在不传递数组大小的情况下,我如何在 fortran90 中做到这一点。我读到我们可以使用指针,但我真的不知道如何处理指针

【问题讨论】:

标签: fortran gfortran fortran90


【解决方案1】:

我知道您想在知道数组的最终大小之前就开始向数组添加元素。

例如,您想从文件中读取值直到到达文件末尾,但不知道有多少值。

我能想到三种方法:

  1. 创建一个足够大的数组,并记住最终值。

     integer :: a(200), n
     n = 1
     do
         a(n) = <value>
         if (<finished>) exit
         n = n + 1
     end do
    
     <use a(1:n)>
    
  2. 创建两个可分配数组,当你到达一个数组的末尾时,将另一个变大,然后交换它们:

     integer, allocatable :: a(:), tmp(:)
     integer :: i, n
     n = 8
     allocate(a(n))
     i = 1
     do
         if (i > n) then 
             allocate(tmp(2*n))
             tmp(1:n) = a(:)
             call move_alloc(tmp, a)
             n = n * 2
         end if
         a(i) = <value>
         if (<finished>) exit
         i = i + 1
     end do
     allocate(tmp(i))
     tmp(:) = a(1:i)
     call move_alloc(tmp, a)
    
  3. 我不再推荐这个。指针可能会造成混淆并产生奇怪且难以调试的错误。 但我将其留给后人使用:创建一个链表(此处使用堆栈)

     type t_node
         integer :: value
         type(t_node), pointer :: next => NULL()
     end type t_node
    
     type(t_node), pointer :: list, tmp
     integer, allocatable :: a(:), i, n
    
     nullify(list)
     nullify(tmp)
    
     do
          allocate(tmp)
          tmp % value = <value>
          tmp % next => list
          list => tmp
          nullify(tmp)
          if (<finished>) exit
          n = n + 1
     end do
     allocate(a(n))
     do i = n, 1, -1
         a(i) = list % value
         tmp => list
         list => list % next
         deallocate(tmp)
     end do
    

【讨论】:

  • 别忘了a=[a,i]
  • 等等,什么?你在拉我的腿吗?
  • 对于 a 分配的可分配整数数组,它可能最接近问题的 MATLAB。我的片段只是一个数组构造函数,在内部赋值时自动重新分配(当然不是 F90,但move_alloc 也不是)。
  • 感谢您的回答,我不知道什么是分配,但我会尽力弄清楚
  • 如果您以前从未使用过可分配数组,请查看以下信息:pcc.qub.ac.uk/tec/courses/f90/stu-notes/F90_notesMIF_11.html -- 哦,不要使用指针(如在我的第三个选项中),直到您确切知道自己是什么'重新做。指针可能会非常混乱。
【解决方案2】:

按照我阅读您的问题的方式,您有一个需要填充数组的子例程,但该数组的大小未知,您不想传递大小。所以你不想要这个:

SUBROUTINE FILL( A, N )
    INTEGER N
    INTEGER A(N)
    INTEGER I
    DO I=1,N
        A(I) = I
    END DO
END SUBROUTINE FILL

相反,您想获取数组的SIZE

SUBROUTINE FILL( A )
  INTEGER A(:)
  INTEGER I
  DO I=1,SIZE(A)
     A(I) = I
  END DO
END SUBROUTINE FILL

【讨论】:

  • 第二个代码我没看懂,获取数组的大小是什么意思
  • DO循环中,循环在I .GT. SIZE(A)时结束。 SIZE 是一个 Fortran 内部函数,它返回数组的维度。
  • 哦,我明白了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-07
  • 1970-01-01
  • 1970-01-01
  • 2016-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多