【问题标题】:Add element to FORTRAN pointer?将元素添加到 FORTRAN 指针?
【发布时间】:2015-07-14 13:53:35
【问题描述】:

我在 fortran 中有一个数组 arr1 to n 开始,我需要根据前面和后面的元素测试每个元素(即 ii-1i+1) - 问题是元素 @ 987654326@ 和 n 分别具有 n1 作为前任或后继(即循环)。

与其分别测试第一个和最后一个元素,我宁愿运行如下循环:

do i=1,n
   call testi(i-1,i,i+1)
end do

并定义一个指针(为了不使用虚拟数组和两倍的内存)

arrpointer(0) => arr(n)
arrpointer(1:n) => arr(1:n)
arrpointer(n+1) => arr(1)

“模拟”我的数组中的循环。 (注意每个数组元素都是一个向量——arr(i)%vec(1:m)

上述方法不起作用,因为指针的每个新定义都会覆盖以前的定义。那么问题来了:

有没有什么方法可以在不删除之前定义的情况下,将元素实际添加到指针数组中?

PS:

作为当前的解决方法,我使用带有指针的可分配类型数组:

type :: pointerarray
  real, pointer :: elementpointer(:)
end type pointerarray
type(pointerarray), allocatable :: arrpointer(:)

arrpointer(0)%elementpointer => arr(n)
do i=1,n
  arrpointer(i)%elementpointer => arr(i)
end do
arrpointer(n+1)%elementpointer => arr(1)

虽然替换循环如下不起作用:

arrpointer(1:n)%elementpointer => arr(1:n)

但是可能有一种我不知道的更简单的方法,因为指针的类型数组再次使代码不那么可读。

【问题讨论】:

  • 我不确定这里的问题是什么......但是你不能在 Fortran 中拥有一个没有派生类型的指针数组。因此,您的“解决方法”实际上是实现这一点的最简单方法。
  • 如果您只想对数组进行循环测试,那么您会对不涉及指针的答案感到满意吗?我觉得提出你关于指针的问题的背景自然根本不涉及指针。
  • @alexander-vogt 谢谢你的意见 - 我只是相信一个更优雅的解决方案
  • @francescalus 我想插入一个虚拟数组 - 但我担心这会消耗太多时间。
  • dimension(:), pointer 不是指针数组,而是指向数组的指针(您可能知道)。一个是相当受限于可以指出的内容。那么,简单的答案是“不”。如果您真的想使用指针而不是其他方法,我们可以提出一些建议,但我想说其他方法可能更直观/简单。

标签: arrays pointers fortran


【解决方案1】:

我认为没有一种方法可以按照您设想的方式使用指针来做到这一点。相反,我建议使用尺寸为 0:N+1 的整数数组,该数组映射到所需的 1:N 范围。例如:

integer :: i(0:N+1), j 
real :: a(N) 

! -- Setup 
do j=1,N 
   i(j) = j 
enddo 
i(0) = N 
i(N+1) = 1 

! -- Then you can do: 
do j=1,N 
   ! call mysub(a(i(j-1)), a(i(j)), a(i(j+1))) 
enddo 

或者,您可以使用函数来定义 i(j)。

【讨论】:

  • 这肯定很简单,但是在我的情况下,数组是从以前的几个子例程(也改变数组值和部分溢出的数组为两个)传递的,直到需要做这个“循环检查”并将进一步传递 - 我想避免更改我以前和后续的所有代码(经常使用例如size)。然而,i(j) 函数听起来像是一个计划,但可能并不比当前类型的指针数组简单。我只是想知道是否有一个优雅的解决方案可以避免使用虚拟数组和类型指针数组。
  • 有可能会弹出一些带有指针的东西;这里的fortran 社区非常聪明。我也很好奇。
【解决方案2】:

我在这台机器上没有 Fortran,所以没有测试过。 OP 的 testi 例程的作用也不完全清楚。因此,这不是一个完整的答案,但可能会为无指针解决方案提供一些有用(或无用)的提示。

不要忘记内在函数chsift。例如,对数组执行单边差分计算的一种方法是编写

arrdiff = arr - chsift(arr,1)

cshift 将元素从数组的一端移动到另一端,这与它的表亲 eoshift 不同,后者执行结束移位。当然chsift 可能需要创建一个与数组大小相同的临时文件(理论上它可以在没有临时文件的情况下完成,实际上它似乎总是使用一个)所以可能对性能和内存使用没有吸引力理由。

【讨论】:

    猜你喜欢
    • 2013-12-25
    • 1970-01-01
    • 2015-09-09
    • 2018-04-10
    • 1970-01-01
    • 2023-03-24
    • 2021-10-01
    • 1970-01-01
    相关资源
    最近更新 更多