2015-07-20 105 views
1

我有一系列的子程序調用,我需要對各種數據類型名稱進行調用。例如:Fortran宏函數的文字字符串?

print*, 'Now giving information about Matrix1' 
call mysub(Matrix1, size(Matrix1,1), size(Matrix1,2)) 
print*, 'About to do function on Matrix1' 
call dofunction(Matrix1) 
print*, 'Matrix1 is a nice matrix! Huzzah!' 

print*, 'Now giving information about Matrix2' 
call mysub(Matrix2, size(Matrix2,1), size(Matrix2,2)) 
print*, 'About to do function on Matrix2' 
call dofunction(Matrix2) 
print*, 'Matrix2 is a nice matrix! Huzzah!' 

print*, 'Now giving information about OtherMat' 
call mysub(OtherMat, size(OtherMat,1), size(OtherMat,2)) 
print*, 'About to do function on OtherMat' 
call dofunction(OtherMat) 
print*, 'OtherMat is a nice matrix! Huzzah!' 

,我想定義一個宏,將採取#define值,這樣我可以換調用順序。例如,定義一個宏mymacro,我想能夠調用簡單

mymacro(Matrix1) 
mymacro(Matrix2) 
mymacro(OtherMat) 

來完成同樣的事情。這可能嗎?

+2

那你試試這麼遠嗎? –

+0

我曾嘗試google搜索如何做到這一點,並拿出什麼:) – drjrm3

回答

2

我花了一段時間來得到這個工作的gfortran,因爲它不支持#expr

的想法是使用;獲得多個命令成一行。當然,這需要禁用通常的線路限制。通過gfortran,這可以通過-ffree-line-length-0來實現。

然後,gfortran的預處理器使用"x"而不是#s(與其他編譯器一樣)。 下面是結果:它正在ifortgfortran

#ifdef __GFORTRAN__ 

#define mymacro(x) print *, "Now giving information about ", "x" ; \ 
        call mysub(x, size(x,1), size(x,2)) ; \ 
        print *, "About to do function on ", "x"; \ 
        call dofunction(x) ; \ 
        print *, "x"," is a nice matrix! Huzzah!" 

#else 

#define mymacro(x) print *, "Now giving information about ", #x ; \ 
        call mysub(x, size(x,1), size(x,2)) ; \ 
        print *, "About to do function on ", #x; \ 
        call dofunction(x) ; \ 
        print *, #x," is a nice matrix! Huzzah!" 

#endif 

program main 

implicit none 
integer :: i(2,2) 

i = 123 

mymacro(i) 

contains 

subroutine mysub(ii, N, M) 
    integer,intent(in) :: ii(:,:), N, M 
    print *,'in mysub:', ii(1,1) 
end subroutine 

subroutine dofunction(ii) 
    integer,intent(in) :: ii(:,:) 
    print *,'in dofunction:', ii(1,1) 
end subroutine 
end program main 
2

怎樣編寫一個子程序是這樣的:

subroutine mymacro(matrix, matrixName) 
    ! declare matrix, precision should be declare somewhere as a constant 
    real(precision), dimension(:,:) :: matrix 
    character(*), intent(in) :: matrixname 

    print*, 'Now giving information about '//matrixname 
    call mysub(matrix, size(matrix,1), size(matrix,2)) 
    print*, 'About to do function on '//matrixname 
    call dofunction(matrix) 
    print*, matrixname//' is a nice matrix! Huzzah!' 
end subroutine mymacro 

這是不完全的,將讓你的矩陣你,但足夠接近的名字的事情。

mymacro(matrix) 

成爲

call mymacro(matrix,'matrix') 

差別不大,你不覺得?

+0

不幸的是,我試過,但我需要一個宏,因爲'size'沒有被正確調用。 – drjrm3

+1

這個大小的問題有點奇怪。到底發生了什麼事? – innoSPG

+0

我現在不願意解決'size'的問題,因爲這不會回答我原來的問題的意圖。我正在尋找一個預處理宏/指令。 – drjrm3

0

宏本身並不是Fortran語言的一部分。大部分(如果不是全部)編譯器通過重用C預處理器來實現它們。我從這裏瞭解到: https://gcc.gnu.org/onlinedocs/cpp/Macros.html

這可能做的伎倆:(未測試!)

#define MYSUB(m) write(*,*) "Now giving information about ", #m; \ 
       call mysub(m, size(m,1), size(m,2)); \ 
       write(*,*) "About to do function on ",#m; \ 
       call dofunction(m) ; \ 
       write(*,*) #m , "is a nice matrix! Huzzah!" ; 

注意,您必須使用適當的編譯器標誌,可以讓編譯運行的預處理器。

+0

不幸的是,這不適用'gfortran',因爲它不支持'#m'。我花了相當長的一段時間才弄清楚 - 請參閱下面的答案... –