指向包含可分配数组

时间:2016-08-11 05:01:21

标签: pointers fortran derived-types allocatable-array

一般来说,我想重命名派生类型中可通过子例程参数传递的可分配变量。使用'derived%type_xx'编写所有内容并不是那么令人愉快。此外,我不想花费额外的内存来将派生类型的值复制到一个新的变量,这需要花费新的分配内存。此外,我知道可分配数组比指针更受欢迎,原因有很多。我尝试定义指向可分配变量的指针,但失败了。我试过这个,因为我想简化我的代码,既可读也不太长。我想知道是否有办法实现目标?感谢。

以下是演示代码:

Module module_type
IMPLICIT NONE
    TYPE type_1
        REAL,ALLOCATABLE                  ::      longname_1(:), longname_2(:)
    END TYPE
END MODULE

!------------------------------------------------------------------------------------------
SUBROUTINE TEST(input)
    USE MODULE module_type
IMPLICIT NONE
    TYPE(type_1)                          ::      input
    input%longname_1 = input%longname_1 + input%longname_2   ! Use one line to show what I mean
END SUBROUTINE

这就是失败的原因:

Module module_type
IMPLICIT NONE
    TYPE type_1
        REAL,ALLOCATABLE                  ::      longname_1(:), longname_2(:)
    END TYPE
END MODULE

!------------------------------------------------------------------------------------------
SUBROUTINE TEST(input)
    USE MODULE module_type
IMPLICIT NONE
    TYPE(type_1),TARGET                    ::      input

    REAL,POINTER                           ::      a => input%longname_1 &
                                                 & b => input%longname_2

    a = a + b   ! much better for reading
END SUBROUTINE

这似乎是一个小问题,但我希望将来能够轻松阅读我的代码。那么什么是最好的选择?非常感谢。

2 个答案:

答案 0 :(得分:5)

您可以使用ASSOCIATE构造将简单名称与更复杂的指示符或表达式相关联。

您还可以使用派生类型的子对象作为执行该操作的过程的实际参数。

您的指针方法失败,因为您的排名不匹配 - 您试图将标量指针与数组目标关联起来。如果您的过程的显式接口在调用范围中不可用,您可能也遇到了问题。具有TARGET属性的伪参数的过程需要显式接口。

使用指针进行此类简单名称别名可能会降低编译器优化代码的能力。应该首选像ASSOCIATE这样的东西。

答案 1 :(得分:4)

更新: @IanH发表评论后,我又回去检查:我的代码失败的原因完全错误了。正如他在回答中指出的那样,主要问题是指针和目标必须具有相同的等级,因此您必须将ab声明为:

real, pointer :: a(:), b(:)

其次,在您实际将这些指针指向目标之前,必须分配目标。这是一个有效的例子:

program allocatable_target

    implicit none
    type :: my_type
        integer, allocatable :: my_array(:)
    end type my_type
    type(my_type), target :: dummy
    integer, pointer :: a(:)

    allocate(dummy%my_array(10))
    a => dummy%my_array
    a = 10
    print *, dummy%my_array

end program allocatable_target

如果您有与Fortran 2003兼容的编译器,则可以使用associate - 这是专门针对此类问题的。这是一个例子:

program associate_example

    implicit none
    type :: my_type
        integer, allocatable :: long_name_1(:), long_name_2(:)
    end type my_type

    type(my_type) :: input

    integer :: i
    allocate(input%long_name_1(100), input%long_name_2(100))

    associate (a=>input%long_name_1, b=>input%long_name_2)
        a = (/ (i, i = 1, 100, 1) /)
        b = (/ (2*i+4, i = 1, 100, 1) /)
        a = a + b
    end associate

    print *, input%long_name_1

end program associate_example

associate块中,您可以使用ab作为声明的较长命名变量的缩写形式。

但除此之外,我建议你得到一个编辑器,正确的代码完成,然后长变量名称不再是一个问题。目前我正在尝试Atom并对此感到非常满意。但是我长期使用vim进行适当的扩展。