【问题标题】:Fortran: How to pass Type variables to SubroutineFortran:如何将类型变量传递给子例程
【发布时间】:2013-07-09 08:28:19
【问题描述】:

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

到目前为止,我可以通过引用整个对象,然后在子例程中引用变量来实现我的目标。有没有办法在子程序参数中只引用变量 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

【问题讨论】:

    标签: fortran95 derived-types


    【解决方案1】:

    你可以简单地写

    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
    

    【讨论】:

    • 我同意我不会创建一个对象只是为了用函数初始化它的变量。我正在尝试测试版本。最终,我将使用来自不同对象的不同变量进行计算。
    【解决方案2】:

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

    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
    

    在 80 年代初,在一个像样的 C++ 编译器问世之前,我也曾经用 C 编写过类似的代码。您会发现,在 70 年代至 90 年代初编写的许多系统都使用这种技术。它适用于任何支持结构和动态内存分配的语言。

    【讨论】:

      猜你喜欢
      • 2015-01-09
      • 1970-01-01
      • 2018-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多