1

我想实现以下目标:

使用自定义类型数据(比如 A)的第一个元素的指针来引用 A

我创建了以下代码原型:

program test

    implicit none

    type foo
        integer i
        integer j
    end type foo

    type(foo), target :: a
    type(foo) b
    integer, pointer :: ai

    a%i = 1
    a%j = 2

    ai => a%i

    print *, "Address of a is", loc(a)

    b = transfer(ai, b)

    print *, "The values of a are:", a%i, a%j

    print *, "Address of b is", loc(b)

    print *, "The values of b are:", b%i, b%j

end program test

我希望 的值b应该等于a,但我在计算机中得到的结果为

Address of a is      140736918227392
The values of a are:           1           2
Address of b is      140736918227376
The values of b are:           1           0

的值b%j不同于 的地方a%j。怎么了?

提前致谢!

编辑:我的目的是向用户隐藏定义的类型(比如foo),并且只让用户访问foo(比如数组)的第一部分,当用户提供该数组时,我可以获得foo. 这是一种封装。用户可以从键入“%”中解放出来。

4

2 回答 2

4

我不确定您是否了解该transfer功能的作用。该声明

b = transfer(ai, b)

获取在 location 中找到的数据ai并使用b. 例如, Sotransfer用于允许程序将实数的位视为整数的位。您的语句所做的是获取在 处找到的数据ai,这是一个整数,并将其更改为 的值type(foo),并将其分配给b

我认为您很幸运,因为编译器没有抱怨 的值ai没有提供transfer足够的位来填充b。我并不感到惊讶,因为transfer它本质上是一种规避 Fortran 严格类型的方法。当然,直接赋值例如b = 1会导致编译错误,因为 lhs 和 rhs 没有兼容的类型。

我认为你没有任何权利期望b%j在你写出来的时候它的价值有任何特定的价值。根据我的快速调查b%j,您的程序根本没有修改 的值,在您的情况下,它被初始化0并且没有被修改。

但我认为真正的问题是您正在尝试做一些 Fortran 程序员不会做的事情,即使用指向结构的第一个元素的指针作为对整个结构的引用。那是 C 和它的表兄弟的味道。

在 Fortran 中,更自然地声明ai为 oftype(foo), pointer然后编写语句,例如

ai => a
...
b = ai

你真的想做什么?如果答案是“使用 Fortran 编译器用 C 语言编写程序”,那么祝你好运,享受在收费公路上滚滚而来的痛苦世界。

于 2012-09-26T13:44:23.520 回答
2

只是补充一下,什么

ai => a%i
b = transfer(ai, b)

确实意味着,当翻译成C时。

这是

b = (foo)(a->i)

如果我对 C 的记忆没有愚弄我。因此,您实际上是在将整数转换为 foo 类型。

--EDIT-- 您可以在结构(派生类型)中拥有许多私有组件,模块的用户看不到,但您可以在模块内使用它们。用户可以使用模块中定义的过程与私有实体进行交互。使用较新的编译器,您甚至可以使用 C++ 中的方法(类型绑定过程)和其他 OOP。

module mod
  type foo
    private
    integer,public :: i
    integer        :: j  !is private!
  end type

end module mod

program p

  use mod

  type(foo) :: a,b

  b%i = 1
  !intrinsic assignment should work, even if you don't see a%j and b%j
  !you can also override the assignment yourself
  a = b

  write(*,*) a%i

end program p
于 2012-09-26T14:04:47.617 回答