有人可以解释这个 C++ program.The 结果很奇怪 :(

Can someone explain this C++ program.The result is weird :(

这是一个测试中的问题。我希望结果是 1:1 但 运行 它并得到答案 1:5,尽管我已经在 Visual C++ 2013 中调试它并看到 'a' 地址的值指向的是 1(1:1 中的最后一个“1”)

#include <iostream>
using namespace std;
int fact(int *a)
{
    if (*a <= 1)
    {
        return a[0];
    }
    else
    {
        return a[0] * fact(&(--*a));
    }
}
int main()
{
    int *a = new int;
    *a = 5;
    cout << fact(a) << ":" << *a;
    return 0;
}

既然可以简单地使用本地值,为什么还需要更改赋予函数的值?

int fact(int a)
{
    if (a < 2)
    {
        return a;
    }
    else
    {
        return a * fact(a-1);
    }
}

这取决于编译器。他们如何处理温度。运算符的值和优先级。 例如:在 solaris CC 上,输出是 24:1。在某些编译器上它将是 120:5 .

正确答案必须是120:1。方法如下

事实要求:5 其他部分。 a[0] : 5 return 值 = 5 * 事实 (4) = 120

事实要求:4 其他部分。 a[0] : 4 return 值 = 4*事实(3) = 4* 6 = 24

事实要求:3 其他部分。 a[0] : 3 return 值 = 3 * 事实 (2) = 3*2 = 6

事实要求:2 其他部分。 a[0] : 2 return 值 = 2*事实(1) = 2*1 = 2

事实要求:1
如果部分。 a[0] = 1 return 值 = 1

您的程序有未定义的行为。所以它无所不能。

你的"full expressions"

a[0] * fact(&(--*a));
cout << fact(a) << ":" << *a;

每个对象的访问(a[0] & *a)和副作用(--*a & fact(a))都没有定义的评估序列.这与标准的 §1.9/15 冲突:

Except where noted,

[运算符 ?:&&||,]

evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.

If a side effect on a scalar object is unsequenced relative to either
(a) another side effect on the same scalar object
or
(b) a value computation using the value of the same scalar object,
the behavior is undefined.

参见 this answer 及其问题。 (我从标准中得到这句话的地方。)

可以猜测可以检测到这种违规的编译器使 fact 只是 return 1 而不会影响 *a,因此 fact(*a) returns 1 和 *a returns 5。但这只是一个猜测,代码可以做任何事情。 (您可以查看汇编代码以了解发生了什么。)

具有您想要的行为的程序涉及更多的临时变量、更简单的语句、更简单的函数规范和更简单的程序结构。编写正确的代码并不难如果你知道什么不该写并检查你没有写它。为您提供帮助:

  • 设置您的编译器选项以报告更多警告和错误并读取其输出(许多未定义的行为可以被编译器静态检测到)
  • 当您读写时明确识别每个函数的输入和输出规范并且(子)expression/statement
  • 继续明确地教育自己关于好的设计
  • 继续明确地学习这门语言