首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Fortran传递函数从源数据中得到不同的值。

Fortran传递函数从源数据中得到不同的值。
EN

Stack Overflow用户
提问于 2012-09-26 13:10:19
回答 2查看 2.4K关注 0票数 1

我希望达到以下目标:

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

我创建了以下代码原型:

代码语言:javascript
复制
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相等,但我在我的计算机中得到的结果如下

代码语言:javascript
复制
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的其余部分。这是一种封装。用户可以从"%“类型中解脱出来。

EN

回答 2

Stack Overflow用户

发布于 2012-09-26 13:44:23

我不确定您是否理解transfer函数的功能。声明

代码语言:javascript
复制
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中,更自然的做法是声明aitype(foo), pointer,然后编写如下语句

代码语言:javascript
复制
ai => a
...
b = ai

你到底想做什么?如果答案是“使用Fortran编译器在C中编程”,那么祝你好运,享受在收费公路上的痛苦世界。

票数 4
EN

Stack Overflow用户

发布于 2012-09-26 14:04:47

我想补充的是,

代码语言:javascript
复制
ai => a%i
b = transfer(ai, b)

意思是翻译成C.

它是

代码语言:javascript
复制
b = (foo)(a->i)

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

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

代码语言:javascript
复制
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
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12602519

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档