2010-10-15 138 views
2

我有点通过以下程序指针作为伪参数

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将常规参数作为参考传递来传递,这意味着在foobar这两个虚拟参数test上出现的实体与在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,则该例程将接受指针和非指针。

这让我想知道......声明一个虚拟参数指针有什么用处?

+0

@Rook:去吧... :) – 2010-10-15 12:18:32

回答

4

转贴自comp.lang.fortran,答案由Tobias伯恩斯:

现在假设回到堆栈分配程序和 子程序栏,而不是定义为

子程序巴(测试) 类型(TestType),指针::测试 试验%I = 6 端子程序

程序不编译任何更多的是因为你必须使用 堆上分配的版本,使其工作,

这是不完全正确:您也可以不通过可分配的变量 与指针属性的假人。我认为其中一个(实际)原因是 指针地址可以转义,因此会导致别名 问题。一个正式的原因是一个ALLOCATABLE不是一个 POINTER;此外,该标准并未谈论堆与堆栈 与静态存储器的关系。实际上,本地数组[常量边界] 通常会在静态内存中创建,而不是在堆栈上创建(除非您使用的是OpenMP或RECURSIVE属性的 )。因此,您的“堆栈”示例可能也是“静态内存”示例,具体取决于编译器和所使用的选项。

或更准确它是 强制将指针传递给该例程时,例程定义 接受指针作为伪参数。

这也不完全正确。在Fortran 2008中,您可以将一个 非POINTER(具有TARGET属性)传递给一个指针伪元,其中的 具有INTENT(IN)属性。 (指针的意图是相对于指针 关联状态;对于非指针假人的意图是关于存储在变量中的值 )

这使我不知道......什么是宣告一个虚拟的点参数 一个指针?

好吧,如果参数具有指针属性,可以分配和 免费指针目标,则可以将指针与一些目标 等多达Fortran 95的关联是不可能有ALLOCATABLE虚拟 因此如果在过程中必须分配(虚拟)参数为 ,则必须使用参数。

如果可以的话,你应该尝试,而ALLOCATABLEs使用比指针 - 他们更容易使用,不漏内存,并具有不构成 别名分析问题的编译器。另一方面,如果您想要创建 (例如,链接列表),则需要一个指针。 (虽然,对于堆 使用,也可以使用的Fortran 2008的分配组件。*)被定义

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

其中所述组件是相同的类型的类型;在F2008之前,这只能用于指针,不能用于可分配。

和R.缅因州

我们知道,Fortran语言转让程序参数为 传递通过引用,

我们显然知道incorectly,然后。该标准从未指定 ,并且确实避免了这种规范。 虽然你的是一个常见的误解,但即使在大多数较老的编译器中,它也不是严格准确的 ,特别是在打开优化的情况下。 严格的按引用传递会导致许多常见的优化。

根据最近的标准,在某些 的情况下,通过引用几乎都是不允许的。该标准在其规范性文本中不使用这些词语,但 有些事情是不切实际的,通过 传递参考。

当你开始进入像指针这样的事情时,假设 所有东西都是通过引用的错误将开始使自己比以前更明显。你将不得不放弃这种误解或许多事情会让你迷惑不解。

我认为其他人已经充分回答了帖子的其余部分。一些 也解决了上述问题,但我想强调它。

希望能回答你的问题。

+0

唯一的答案是我不了解fortran,就像我做过的那样。这已经是非常重要的一步,我感谢你在这方面的努力。 – 2010-10-17 22:46:36