2

这是我的第一个问题帖子......请不要残忍。

我的问题如下。我想将 fortran 指针分配为表达式。我认为通过简单的 fortran 技术是不可能的。但由于新的 fortran 版本似乎提供了处理 C 和 C++ 中使用的东西的方法(如 c_ptr 和 c_f_pointer ... ),也许有人知道解决我的问题的方法。(我并不真正了解 C,但我读到 C 中可以使用指针运算)为了让事情更清楚,这是我立即想到但不起作用的代码:

program pointer

real(8),target :: a
real(8),pointer :: b

b=>a*2.0d0  ! b=>a is of course working

do i=1,10
   a=dble(i)*2.0d0
   write(*,*)b
end do

end program

我知道有解决这个问题的方法,但在实际程序中,我想到的所有这些都会导致更长的计算时间和/或相当奇怪的代码。

非常感谢,提前!

最好的,彼得

4

4 回答 4

1

迈克尔梅特卡夫

指针是具有 POINTER 属性的变量;它们不是一种独特的数据类型(因此不可能有“指针算术”)。

它们在概念上是一个描述符,列出了指针可能指向的对象(目标)的属性,以及目标的地址(如果有的话)。在分配或以其他方式关联之前,它们没有关联的存储(通过指针分配,见下文):

所以你的想法b=>a*2不起作用,因为b分配a而不是被赋予.a

于 2013-10-17T20:03:46.093 回答
1

一般来说,表达式(有两个半非常重要的例外)不是有效的指针目标。表达式的评估(通常)产生一个值,而不是一个对象。

(例外情况与整体表达式导致对具有数据指针结果的函数的引用的情况有关 - 在这种情况下,表达式可以在指针赋值语句的右侧使用,或者作为实际参数在在可能需要变量的任何上下文中,例如普通赋值语句的左侧,对应于指针虚拟参数或[可能 - 和 F2008] 的过程引用。但是您的表达式不会导致这样的函数引用而且我认为用例与您不想做的事情无关。)

我认为您希望 b 的值根据初始表达式的形式随着 a 的“基础”值的变化而变化。除了有效指针目标问题之外,这还需要与语言的基本原则之一相反的行为(实际上是大多数语言) - 表达式的评估在表达式评估时使用其初级的值 - 这些初级的后续更改确实不会导致历史评估值发生变化。

相反,请考虑编写一个基于 a 计算 b 的函数。

program pointer
  IMPLICIT NONE
  real(8) :: a
  do i=1,10
    a=dble(i)*2.0d0
    write(*,*) b(a)
  end do
contains
  function b(x)
    real(kind(a)), intent(in) :: x
    real(kind(a)) :: b
    b = 2.0d0 * x
  end function b
end program
于 2013-10-17T20:34:17.317 回答
1

更新:我越来越接近我想要的(对于那些感兴趣的人):

module test

real,target :: a
real, pointer :: c

abstract interface
   function func()
      real :: func
   end function func
end interface

procedure (func), pointer :: f => null ()

contains

function f1()
  real,target :: f1

  c=>a
  f1 = 2.0*c

  return
end function f1

end module

program test_func_ptrs

use test

implicit none

integer::i

f=>f1

do i=1,10
   a=real(i)*2.0
   write(*,*)f()
end do

end program test_func_ptrs

如果我能找到一种避免虚拟参数的方法(至少在我调用 f 时),我会完全满意。

附加信息:关键是我想在开始循环之前定义不同的函数 f1 和 deside,f 将在循环内部(取决于任何输入)。

于 2013-10-17T22:12:33.540 回答
0

从指针计算地址偏移量的意义上来说,指针算术在 Fortran 中是不允许的。指针算法很容易导致内存错误,Fortran 的作者认为没有必要。(可以通过与 C 互操作性的后门来做到这一点。)

Fortran 中的指针对于将过程作为参数传递、设置数据结构(例如链表)(例如,我如何在 fortran 2003-2008 中实现链表)等非常有用。

于 2013-10-17T20:16:42.437 回答