作为作业的一部分,我获得了FORTRAN程序的(旧)代码。我只有C ++(和Oberon)的经验以及我对Fortran的知识,我通过各种(部分)教程获得,这些教程并不总是彼此一致。然而,尽管我的基本知识,这个代码因缺乏优雅或一致性而伤害了我的眼睛。但更令人不安的是:它似乎只是充满了编程的弊端。
我想问的代码的特定部分看起来类似于这个例子:
PROGRAM Foo
IMPLICIT NONE
CALL Bar(0.0,-1)
END PROGRAM Foo
SUBROUTINE Bar(t,i)
DIMENSION(5) :: R = 0.5
REAL :: s = 0.5
DO k = 1, 5
R(k) = k * i
END DO
CALL Random(s) ! Random is a well-behaved pseudorandom number generator
! on the interval ]0,1[ implemented elsewhere.
k = 1 + (s * 5)
t = R(k)
END SUBROUTINE Bar
我会解释我认为这个想法是什么。 Random(s)
在s
中存储介于0.0和1.0之间的值。这意味着1 + (s * 5)
将产生1到5之间的实数(对pRNG的一些测试显示其最大值导致~5.992,最小值为~1.0016)。如果左侧是整数,则会发生右侧的自动类型转换,并且尾数将被切断,在区间[1,5]上留下整数值。但k
未在任何地方声明为INTEGER
。相反,k
已初始化为DO
- 循环的循环计数器。当然这意味着它必须是一个整数,但我认为这是不好的做法。我对吗?另外,我会对数组R
的声明不满意,因为没有明确的类型说明符。我已经明确表示它将通过初始化数组来存储REALs
,但这不是在实际代码中完成的......
当然我调整了实际代码而不仅仅是初始化,希望能够遵循更高的标准。 (想象一下IMPLICIT
变量,不一致的大写和goto
到处都是。)另外,也许我也可以问这个问题:结束程序,子程序的现代标准和语法END <PROGRAM/SUBROUTINE/FUNCTION> Name
的函数?在我给出的代码中,他们只使用了END
。我一直在假设我提到的正确的现代语法,但我不确定。就像我不确定程序的名称等是否应该没有资本化。 (在我给出的代码中,它们是全部大写的)
答案 0 :(得分:2)
你所写的内容在很大程度上是正确的,但有些事情值得注意。
R
和k
(以及t
和i
)是implicit typing的受害者,但应该注意的是,它绝不是因为他们如何使用或初始化。具体而言,无论R
是什么,=0.5
都是真实的。
此外,在Fortran 95之前,循环变量不必是整数。像do a=1,5
这样的东西不会强制隐式类型a
是一个整数(但Fortran 95 +会不正确)。
你肯定是正确的,现代品味是在每个范围单元中都有implicit none
- 强制一切都要明确输入。
但是,我会对“正确的现代语法”采取例外处理:没有任何不正确的关于仅使用END
结束子程序,但我更喜欢并使用更长的形式。
需要注意的另外两个小问题:显式初始化意味着save
属性(在此示例中没有实际效果); Random
不是标准内在函数,如果它不能返回0
,那么它的行为与标准random_number
不同。