2017-03-01 48 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 –

相關問題