2

根据 ISO 帕斯卡标准,我无法找出该程序的正确行为。我尝试阅读 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)​​ 在这一点上与默认设置不符合标准。

4

2 回答 2

2

这里有两个单独的问题:

  1. fact是表示函数的结果,还是递归调用?
  2. 如果它确实表示递归调用,是否24定义了结果或实现?

1.fact是表示函数的结果,还是递归调用?

由于fact不会出现在赋值的左边,它不对应于函数的结果,所以它应该递归地调用函数。编译器在这种情况下处理factfact()不同听起来像一个错误。

标准说:

在激活中,应用的标签或变量标识符,或局部于激活块的过程标识符或函数标识符的出现应分别表示相应的程序点、变量、过程或函数,该激活的;除了赋值语句的函数标识符应在由该函数标识符表示的函数的激活内表示该激活的结果。

2. 如果它确实表示递归调用,是否24定义了结果或实现?

即使您忽略与递归相关的问题,并使用fact(),您仍然不能期望总是得到24结果。

它归结为:“在表达式中首先评估(n+1)或评估?fact()(n + 1) * fact

评估的顺序是在这种情况下定义的实现。这意味着遵循标准的不同实现可能会产生不同的结果,并且您不能期望24所有这些实现。

引用标准:

6.7.2 运算符

6.7.2.1 概述


表 3 | 二元算术运算

...
*乘法
...


因子、项或简单表达式应指定为操作数。二元运算符的操作数的评估顺序应取决于实现。

注意 | 这意味着,例如,操作数可以按文本顺序、逆序或并行进行求值,也可以不同时求值。

于 2012-08-10T09:39:53.803 回答
1

Free Pascal 的 ISO 方言模式非常年轻(1-2 年),因为 FPC 通常是 Borland 而不是面向 ISO 的编译器。

Mac Pascal 模式经过更多测试,通常非常类似于 ISO。在 macpascal 模式下编译将产生没有 () 的“16”答案。

可能 ISO 模式应该做同样的事情,而不是使用 borland/delphi 之类的返回值是一个伪变量。请提交一个错误。

于 2012-08-23T00:47:13.923 回答