我希望达到以下目标:
使用自定义类型数据(例如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的其余部分。这是一种封装。用户可以从"%“类型中解脱出来。
发布于 2012-09-26 13:44:23
我不确定您是否理解transfer函数的功能。声明
b = transfer(ai, b)获取在位置ai中找到的数据,并使用b的类型(以及相关的类型)创建它的副本。因此,transfer被用来允许程序,例如,将实数的位当作整数的位。您的语句所做的是将在ai中找到的数据作为一个整数,并将其更改为type(foo)的值,并将其赋值给b。
我认为您很幸运,因为编译器没有抱怨ai的值没有为transfer提供足够的位来填充b。我并不感到惊讶,因为transfer本质上是规避Fortran严格打字的一种方法。当然,像b = 1这样的直接赋值会导致编译错误,因为lhs和rhs没有兼容的类型。
我认为当您写出b%j值时,您没有任何权利期望它具有任何特定的值。根据我的快速调查,b%j的值根本没有被您的程序修改,在您的情况下,它被初始化为0,也没有被修改。
但我认为真正的问题是,您正在尝试执行Fortran程序员不会做的事情,即使用指向结构的第一个元素的指针作为对整个结构的引用。闻起来有C和它的表兄弟的味道。
在Fortran中,更自然的做法是声明ai为type(foo), pointer,然后编写如下语句
ai => a
...
b = ai你到底想做什么?如果答案是“使用Fortran编译器在C中编程”,那么祝你好运,享受在收费公路上的痛苦世界。
发布于 2012-09-26 14:04:47
我想补充的是,
ai => a%i
b = transfer(ai, b)意思是翻译成C.
它是
b = (foo)(a->i)如果我对C的记忆没有欺骗我。因此,您实际上是在将整数转换为foo类型。
--编辑--您可以在一个结构(派生类型)中有许多私有组件,模块的用户看不到这些组件,但是您可以在模块中使用它们。用户可以使用模块中定义的过程与私有实体交互。使用较新的编译器,您甚至可以拥有方法(类型绑定过程)和其他OOP (如C++ )。
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 phttps://stackoverflow.com/questions/12602519
复制相似问题