|
恭喜, 解決了問題, 一樂也。
三個可以算是 "难以理解"的, 與君同樂
(a) 光看主程式, "WRITE(*,*) 5", write出來說不是"5", 不可能吧!
[Fortran] 纯文本查看 复制代码 PROGRAM test
IMPLICIT NONE
WRITE(*,*) 5
CALL abc(5)
WRITE(*,*) 5
CALL abc(5)
WRITE(*,*) 5
CONTAINS
SUBROUTINE abc(five)
IMPLICIT NONE
INTEGER :: five
five = five + 1
END SUBROUTINE abc
END PROGRAM test
compile-time給wraning或fatal error, 或是run-time出現不知所云error的, 是"嚴謹"的compilers
run-time告訴你"5"不是"5", 不是Fortran的錯, 也不是compiler的錯(compiler太老實了點), 是程式員的錯(logical error)
compile-time沒任何訊息, run-time告訴你"5"就是"5"的compilers, 太自作聰明了
用Fortrn 90"INTENT"attribute, 是一個好習慣, 但是, 請看 (b)
(b) 光看副程式, 兩個"WRITE(*,*) x", 沒理由值不同吧?
[Fortran] 纯文本查看 复制代码 PROGRAM test
IMPLICIT NONE
REAL :: x
x = 5.0
CALL abc(x, x) !---> OK, if: CALL ABC((x), x)
CONTAINS
SUBROUTINE abc(x, y)
IMPLICIT NONE
REAL, INTENT(IN ) :: x
REAL, INTENT( OUT) :: y
WRITE(*,*) 'x=', x
y = x + 1.0
WRITE(*,*) 'x=', x
END SUBROUTINE abc
END PROGRAM test
原因出在主程式 "CALL abc(x, x)"
主/副程式, "語法"都是正確的, 程式員的錯(logical error)
不要以為這是"無聊"的把戲, "x"帶訊息進去責任已了, 能省則省新的訊息由"x"帶出來, 挺合理的
多加一對小括號 "CALL abc((x), x)", 就完全沒問題了
(c) 說一套(syntax defined by language standrad), 做一套(compilation by compiler)
[Fortran] 纯文本查看 复制代码 PROGRAM test
IMPLICIT NONE
REAL :: a, b, c
a=1.0; b=2.0; c=3.0
CALL abc(a, b, c)
WRITE(*,*) c
CONTAINS
SUBROUTINE abc(a, b, c)
IMPLICIT NONE
REAL, INTENT(IN ) :: a
REAL, INTENT(INOUT) :: b
REAL, INTENT( OUT) :: c
b = a + b
!WRITE(*,*) c
END SUBROUTINE abc
END PROGRAM test
! All INTENT(OUT) Dummy Arguments become Undefined on Entry to a Procedure.
! (the intension is that it be used only to pass information out, so it
! becomes undefined on entry to the procedure)
! You cannot use an INTENT(OUT) dummy until it has been defined
(a), (b), (c) compile-time/run-time 會怎樣, compile-time "options" dependent, "compiler" dependent,
甚至會是 compiler "version" dependent, 怎辦? ["SAVE"也是一樣]
不怎辦, 都是程式員的錯 (logical errors)
|
|