首页 文章

派生类型中的可变长度数组

提问于
浏览
3

我主要使用Python进行科学编程,并且没有很多Fortran(90/95)经验 . 对于我的一个项目,我想定义一个派生类型,并为该类型重载一堆运算符 . 关键的是,我想将派生类型的变量之一变为可变长度的数组;至少,我需要在代码的不同部分使用两种不同的长度 . 如何才能最有效地实现这一目标并避免代码重复?

我的第一种方法是使用可分配的数组,但在整个代码中包含多个分配语句,包括重载的运算符 . 在MPI应用程序中使用代码时也会遇到困难 .

我目前的方法是在两个单独的模块中定义一个相同名称的类型,并在代码的不同部分使用一个或另一个 . 可以使用头文件共享重载的运算符(下例中为 mytype_operators.h ) .

module mod1
      type mytype
        real :: x1
        real,dimension(1) :: x2
      end type mytype
#include "mytype_operators.h"
    end module mod1

    module mod2
      type mytype
        real :: x1
        real,dimension(10) :: x2
      end type mytype
#include "mytype_operators.h"
    end module mod2

不幸的是,代码中有一个带有子程序的模块,我想将它们用于这两种类型 . 目前我有两个代码副本;一个带有“ use mod1 ", the other with " use mod2 ” . 我可以改进这一点并避免代码重复吗?

1 回答

  • 1

    您的案例非常适合使用2003年标准中引入的Fortran功能(稍后由编译器采用),名为parameterized derived types . 首先,您应该检查编译器的合规性状态,以了解它是否完全受支持 .

    此功能允许您在声明或构造派生类型时传递自定义参数,因此将相应地调整内部功能 . 它们适用于将不同的行为选择组合在一个类型名称中,可能存在相当大的编码或存储差异 . 有两种类型的参数:

    • kind 参数的行为与内在类型的类型说明符非常相似 . 所有变量的种类参数必须在编译时知道,并且实际上被视为常量值 . 方便的是,您可以通过仅更改声明或构造中的值来轻松地(在代码时间内)更改它 . 这通常用于专门化内在类型的组件 .

    • len 参数的行为与内在字符类型的len说明符非常相似 . 您可以在编译时或运行时定义len参数,并且除非您声明它可分配,否则变量的len参数不能更改 . 此外,您可以在过程中使用假定的len参数参数,并避免代码详细程度 . 这通常用作派生类型的"length"或"dimension"参数,因为您可以在数组边界和字符长度的声明中使用它们 .

    通常,类型参数用于模拟派生类型中内在类型的功能,但您也可以获得“创造性”并将其用于其他事物,例如转换矩阵类型的维度空间;用于自定义“联合类型”(如枚举);作为“测量单位”数据类型中物理量的性质(用“质量”统一标注的实际值与“温度”统一不直接相容,但它们可以在几乎相同的方式处理码);元组类型的“arity”......

    module mod1
      type :: mytype(n)
        integer, len :: n
        real :: x1
        real, dimension(n) :: x2
      end type mytype
    contains
      ! your operations here...
    end module mod1
    

    并像这样使用它:

    program test_pdt
      use mod1
      implicit none
    
      type(mytype(10)) :: mt10
      type(mytype(1)) :: mt1
      integer :: i
    
      mt10%x1 = 40.0
      mt10%x2 = [(0.5 * i, i = 1, 10)]
      mt1 = mytype(1)(20.0, [30.0])
    
      call sub(mt10)
      call sub1(mt1)
    
    contains
      subroutine sub(m)
        ! accepts values with any "n" parameter
        type(mytype(*)) :: m
        ! you can also use them in declarations
        integer, dimension(m%n + 1) :: y
        type(mytype(m%n)) :: w
        print *, m%n, w%n, size(y)
      end
    
      subroutine sub1(m)
        type(mytype(1)) :: m  ! only accepts values with n=1
        print *, m%x1, m%x2, m%n
      end
    end
    

    警告:这是一个功能,尽管多年前已经宣布,最近才被添加到大多数编译器中,你应该知道实现中仍然存在一些错误 . 经常使用你可能会很好,但我经常在某些极端情况下会出现错误的语法错误,有时甚至会出现ICE .

相关问题