根据ISO pascal标准,我无法找出该程序的正确行为。我试图阅读ISO 7185标准文档,但没有找到关于此主题的任何内容。结果4或24应该是什么?
program Undetermined;
var
n: Integer;
function fact: Integer;
begin
fact := 1;
if n > 1 then
begin
n := n - 1;
fact := (n + 1) * fact
end
end;
begin
n := 4;
writeln( fact )
end.
编辑:我意识到我的例子中存在第二个问题。所以考虑一下新代码:
program Undefined;
var
n: Integer;
function power2: Integer;
begin
power2 := 1;
if n > 0 then
begin
n := n - 1;
power2 := 2 * power2
end
end;
begin
n := 4;
writeln( power2 )
end.
结果应该是16或2(根据我的编译器)?
编辑:感谢答案,如果他们没有解决我的问题。我终于在另一个论坛上得到了正确的答案:ISO标准指定了我预期的行为,但我使用的编译器(fpc)不符合该点的标准与默认设置。答案 0 :(得分:2)
这里有两个不同的问题:
fact
是表示函数的结果还是递归调用?24
还是实现已定义?fact
表示函数的结果或递归调用吗?由于fact
未出现在赋值的左侧,因此它不对应于函数的结果,因此它应该递归调用该函数。在此上下文中以不同方式处理fact
和fact()
的编译器听起来像一个错误。
标准说:
在激活过程中,标签或变量标识符或激活块本地的过程标识符或函数标识符的应用出现应表示相应的程序点,变量,过程或函数分别是那种激活;除了赋值语句的函数标识符,在该函数标识符表示的函数的激活中,应表示该激活的结果。
24
还是实现定义?即使您忽略了与递归相关的问题,并使用fact()
,您仍然不能指望总是得到24
。
归结为:“(n+1)
或fact()
首先在表达式(n + 1) * fact
中进行评估吗?
评估顺序是在这种情况下定义的实现。这意味着遵循标准的不同实现可以提供不同的结果,并且您不能期望所有这些实现24
。
引用标准:
6.7.2运营商
6.7.2.1一般
表3 |二元算术运算
...
*
乘法
...
要素,术语或简单表达式应指定为操作数。二元运算符的操作数的评估顺序应与实现有关。
注意|这意味着,例如,操作数可以按文本顺序,或以相反顺序,或并行计算,或者它们可能都不会被评估。
答案 1 :(得分:1)
免费Pascal的ISO语言模式非常年轻(1 - 2年),因为FPC通常是Borland而不是面向ISO的编译器。
Mac Pascal模式经过了更多测试,并且通常非常像ISO。在macpascal模式下编译将产生没有()的“16”答案。
可能ISO模式应该这样做而不使用borland / delphi就像返回值是一个伪变量。请提交错误。