Fortran:如何将Type变量传递给Subroutine

时间:2013-07-09 08:28:19

标签: fortran95 derived-types

我想在子程序(或函数)中计算派生数据类型。我如何在子程序参数中引用变量?

到目前为止,我可以通过引用整个对象来实现我的目标,然后在子例程中引用变量。有没有办法在子例程参数中仅引用变量myObj%var?

PROGRAM test

    TYPE obj
        INTEGER :: var
    END TYPE obj

    TYPE (obj) :: myObj
    CALL set(myObj)
    PRINT*, myObj%var

        CONTAINS

    SUBROUTINE set(myObj)
        TYPE (obj) :: myObj
        myObj%var = 5
    END SUBROUTINE set

END PROGRAM test

2 个答案:

答案 0 :(得分:2)

你可以简单地写

SUBROUTINE set(an_int)
    integer, intent(inout) :: an_int
    an_int = 5
END SUBROUTINE set

然后像这样调用子程序:

CALL set(myObj%var)

我认为将组件打包成派生类型然后将它们解压缩以传递给过程是不正常的只是一种意见,你可以自由地忽略它。就个人而言,我会更严格地重写您的代码,如下所示。但请注意,这使用了2003标准中引入的一些功能,尽管这些功能是在最广泛使用的编译器的当前版本中实现的。

MODULE mytype

  IMPLICIT NONE

  TYPE obj
     INTEGER, PRIVATE :: var
   CONTAINS
     PROCEDURE, PASS :: get_var
     PROCEDURE, PASS :: set_var
  END TYPE obj

CONTAINS

  SUBROUTINE set_var(this,an_int)
    CLASS(obj), INTENT(inout) :: this
    INTEGER, INTENT(in) :: an_int
    this%var = an_int
  END SUBROUTINE set_var

  INTEGER FUNCTION get_var(this)
    CLASS(obj), INTENT(inout) :: this
    get_var = this%var
  END FUNCTION get_var

END MODULE mytype


PROGRAM test

  USE mytype
  IMPLICIT NONE 

  TYPE (obj) :: myObj
  CALL myobj%set_var(12)
  PRINT*, myObj%get_var()

END PROGRAM test

答案 1 :(得分:1)

如果你只有一个没有所有2003/2008位的F95编译器,那么就可以这样做。

MODULE ObjMod
  IMPLICIT NONE

  TYPE ObjType
     INTEGER, PRIVATE :: var
  END TYPE ObjType

CONTAINS

  SUBROUTINE ObjCreate(this)
     TYPE(ObjType), POINTER :: this
     allocate(this)
  END SUBROUTINE ObjCreate

  SUBROUTINE ObjDelete(this)
     TYPE(ObjType), POINTER :: this
     deallocate (this)
  END SUBROUTINE ObjDelete

  SUBROUTINE ObjSet(this, value)
     TYPE(ObjType), INTENT(inout) :: this
     INTEGER, INTENT(in) :: value
     this%var = value
  END SUBROUTINE ObjSet

 INTEGER FUNCTION ObjGet(this)
    TYPE(ObjType), INTENT(inout) :: this
    ObjGet = this%var
 END FUNCTION ObjGet

END MODULE ObjMod


PROGRAM test

 USE ObjMod
 IMPLICIT NONE 

 TYPE (ObjType), POINTER :: testObj

 CALL ObjCreate(testObj)
 CALL ObjSet(testObj, 12)
 PRINT*, ObjGet(testObj)
 CALL ObjDelete(testObj)
 STOP
END PROGRAM test

在一个体面的C ++编译器问世之前,我也常常在80年代早期用C代码编写代码。你会发现很多系统在70年代到90年代初使用这种技术。它适用于支持结构和动态内存分配的任何语言。