指针作为伪参数

时间:2010-10-15 09:01:16

标签: pointers fortran90

我对以下程序感到有些困惑

module test
   implicit none

   type TestType
      integer :: i
   end type

contains
   subroutine foo(test)
      type (TestType), intent(out) :: test
      test%i = 5 
   end subroutine

   subroutine bar(test)
      type (TestType), intent(out) :: test
      test%i = 6 
   end subroutine

end module

program hello
   use test
   type(TestType) :: t

   call foo(t)
   print *, t%i 
   call bar(t)
   print *, t%i 
end program hello

及其衍生物。稍后会详细介绍。我们知道,Fortran将常规参数作为pass-by-reference传递,这意味着testfoo的伪参数bar处出现的实体是相同的内存空间。 program hello中的堆栈。到目前为止一切都很好。

假设我在program hello中将type(TestType) :: t定义为指针,然后分配它。

program hello
   use test
   type(TestType), pointer :: t

   allocate(t)

   call foo(t)
   print *, t%i
   call bar(t)
   print *, t%i

   deallocate(t)
end program hello

代码与以前一样工作,唯一的区别是对象没有在堆栈上分配,而是在堆上。

现在假设回到堆栈分配的程序,该子程序栏被定义为

 subroutine bar(test)
    type (TestType), pointer :: test
    test%i = 6 
 end subroutine

程序不再编译,因为您必须使用堆分配的版本才能使其工作,或者为了更准确,当定义例程以将指针接受为虚拟时,必须将指针传递给例程论点。另一方面,如果伪参数不包含pointer关键字,则例程将接受指针和非指针。

这让我想知道......将伪参数声明为指针是什么意思?

1 个答案:

答案 0 :(得分:4)

转自comp.lang.fortran,Tobias Burns的回答:

  

现在假设回到堆栈分配的程序那   子程序栏改为定义为

     

子程序栏(测试)        type(TestType),pointer :: test        测试%i = 6     结束子程序

     

程序不再编译,因为你必须使用   堆分配版本,使其工作,

这不太正确:您也无法传递ALLOCATABLE变量 到具有POINTER属性的虚拟对象。我认为一个(实际)原因是 指针地址可以转义,因此你会导致别名 问题。一个正式的理由是ALLOCATABLE根本就不是 指针;另外,标准没有谈论堆与堆栈 与静态记忆。实际上,本地数组[具有常量边界]将会 通常是在静态内存中创建而不是在堆栈中创建(除非您使用 OpenMP或RECURSIVE属性)。因此,您的“堆栈”示例可以 也是一个“静态内存”的例子,取决于编译器和 使用过的选项。

  

或者更准确   必须在定义例程时将指针传递给例程   接受指针作为伪参数。

这也不完全正确。在Fortran 2008中你可以传递一个 非POINTER,具有TARGET属性,指向指针虚拟 具有INTENT(IN)属性。 (指针意图相对于指针 协会地位;对于非指针假人,意图是关于 存储在变量中的值。)

  

这让我想知道...宣布一个虚假的论点是什么意思   指针?

好吧,如果参数有POINTER属性,你可以分配和 释放指针目标,可以将指针与某个目标相关联 等到Fortran 95,不可能有ALLOCATABLE假人 因此,如果必须使用(虚拟)参数,则必须使用指针 在程序中分配。

如果可以的话,你应该尝试使用比指示器更好的ALLOCATABLE - 它们更容易使用,不会泄漏记忆并且没有姿势 编译器的别名分析问题。另一方面,如果你想 要创建例如链表,您需要一个指针。 (虽然,对于一堆 用法,也可以使用Fortran 2008的可分配组件。*)

*I mean:
   type t
       type(t), allocatable :: next
   end type

其中组件与所定义的类型相同; 在F2008之前,这只允许指针,但不允许分配。

和R. Maine

  

正如我们所知,Fortran将常规参数转换为   通过按引用,

然后我们显然知道了这种情况。标准从未指定 并且,确实在避免这种规范方面走了很多路。 虽然你的常见误解,但并不严格准确 即使在大多数较旧的编译器中,尤其是在启用优化的情况下 严格的引用传递会导致很多常见的优化。

根据最近的标准,传递参考在某些方面几乎是不允许的 案例。该标准不在其规范性文本中使用这些词语,而是 实施的东西是不切实际的 通过按引用。

当你开始涉及像指针之类的东西时,假设的错误 一切都是通过引用将开始使自己更多 比以前明显。你不得不放弃这种误解或许多错误 事情会让你感到困惑。

我认为其他人已经充分回答了其余的帖子。一些 也谈到了上述观点,但我想强调一下。

希望这能回答你的问题。