2017-03-01 53 views
2

我可以使用可分配数组作为数据类型来定义用户定义的数据类型。传递用户定义的数据类型可分配数组

当我们仍处于同一子程序中时,分配完美地工作。 但我不知道如何将这种类型的用户定义数据类型作为子例程参数传递。

英特尔编译器显示了错误# 6530

"Error 1 error #6530: The array spec for this component must be of explicit shape and each bound must be an initialization expression." 

的代码已经下面共享,以显示该错误。它是用FORTRAN 77编写的。我在FORTRAN 77中工作,因为我将不得不在ABAQUS的用户子程序中附加这个代码,它只接受FORTRAN 77文件。


PROGRAM DERIVED_DATA_TYPE_CHECK 

    IMPLICIT NONE 

    INTEGER :: I,J,A,B 
    TYPE SS 
     SEQUENCE 
     DOUBLE PRECISION, DIMENSION(:,:), ALLOCATABLE :: S1 
    END TYPE SS 

    TYPE (SS),DIMENSION(:,:),ALLOCATABLE :: SS_ 

    A=10 
    B=10 

    ALLOCATE (SS_(A,B)) 
    ! ALLOCATING THE VARIABLE S1 DIMENSIONS 
    ! EVERY ALLOCATABLE VARIABLE HAS THE SAME SIZE AS 
    ! THE TOTAL NUMBER OF STRUCTURE (TYPE) 
    DO I = 1,A 
     DO J = 1,B 
      ALLOCATE(SS_(I,J)%S1(A,B)) 
     ENDDO 
    ENDDO 

    CALL PASS_ARG(SS_,A,B) 

    END 


    SUBROUTINE PASS_ARG(SS_,A,B) 

    IMPLICIT NONE 

    INTEGER :: A,B 

    TYPE SS 
     SEQUENCE 
     DOUBLE PRECISION, DIMENSION(A,B) :: S1 
    END TYPE SS 

    TYPE (SS), DIMENSION (A,B) :: SS_ 

    END 

在编译程序给出了错误,如下图所示:

---------- 
Error 2 error #6530: The array spec for this component must be of explicit shape and each bound must be an initialization expression. [S1] 
---------- 

必须有解决这个问题的一种方式。我想远离公共块或模块。无论如何,我不能在Fortran中使用模块。

为了避免这个错误,我在主程序和子程序中使用了可分配的变量。程序然后被编译,但是在执行时,它显示错误“该分配已经完成了多次”。我想我将不得不使用一些全局常量.....我想。

+1

您的代码是** NOT ** FORTRAN 77.甚至没有关闭。它与FORTRAN 77绝对不兼容。在FORTRAN 77中没有什么像'allocatable'或'::'或'type'。 –

+0

ok .................. –

+0

ok ..................所以你可以编译你的更正程序中的程序....并发布你的建议...........我不关心......直到这个特定的小程序运行在f90或f77 ........... –

回答

1

可以做你想做的,而不模块做的,但是,这并不意味着你应该。但首先,让我们看看编译器在抱怨的事情。

考虑派生类型定义

type t 
    real x(i) 
end type 

这种类型有一个阵列部件x(与结合i);它是一个明确的形状数组。在这种情况下,绑定的i必须是规范表达式。在这里,这基本上意味着i必须是一个常数。

在问题的子程序pass_arg中,组件的边界不是常量,而是虚拟参数。这就是编译器抱怨的原因。

要解决这个问题,您应该再次使子程序可分配类型中的组件。您甚至不需要通过ab:从数组的分配状态开始可以使用边界。


现在,你说你想不使用模块来做到这一点。通过上述修正,您可以做到这一点。然而,我强烈建议你不要这样做,因为派生类型是一个序列类型。使用序列类型是有限制且容易出错的:

  • 序列类型在它们的组件中可能是有限的,并且不能有类型绑定过程;
  • 您必须重复确切地说它在每个地方被使用的类型的定义;
  • 你不能在类型中有私人组件。

更好地创建一个模块并定义一次派生类型(并使其成为非序列类型)。


的问题的一个例子的第二个选择是使用一个参数派生类型:

type ss(a,b) 
    type, len :: a, b 
    ! Not a sequence type, define once in a module 
    double precision, dimension(a,b) :: s1 
end type 

在此可以像(为了清楚起见使用命名常量)

可以使用主程序
use mod_with_type_ss 
implicit none 
integer, parameter :: a=10, b=10 
type(ss(a,b)) ss_(a,b) 
call pass_arg(ss) 
end 

然后子程序也能像

subroutine pass_arg(ss_) 
    use mod_with_type_ss 
    type(ss(*,*)), intent(in) :: ss_ ! The type parameters are assumed 
    ... 
end subroutine 
+0

感谢FRACESCALUS –

相关问题