C++ 为什么这个代码返回我6561?

C++ 为什么这个代码返回我6561?,c++,function,recursion,C++,Function,Recursion,我正在学习通过引用调用函数和通过值调用函数,我在发现为什么返回6561时遇到了问题 在我的主函数中,我调用了一个函数f(p,p),其中p在调用之前被初始化为5 我将函数f定义为: int f(int &x, int c) { c = c - 1; if (c == 0) return 1; x = x + 1; return f(x,c)*x; } 为什么此代码返回6561?要了解引用,此函数相当复杂,因为要理解作为引用传递的第一个参数的

我正在学习通过引用调用函数和通过值调用函数,我在发现为什么返回6561时遇到了问题

在我的主函数中,我调用了一个函数
f(p,p)
,其中p在调用之前被初始化为5

我将函数f定义为:

int f(int &x, int c)
{
    c = c - 1;
    if (c == 0)
        return 1;
    x = x + 1;
    return f(x,c)*x;
}

为什么此代码返回
6561

要了解引用,此函数相当复杂,因为要理解作为引用传递的第一个参数的含义,首先需要了解递归的性质

让我重复你的代码:

int f(int &x, int c)
{
    c = c - 1;
    if (c == 0)
        return 1;
    x = x + 1;
    return f(x,c)*x;
}
显然,还有另一个函数包含如下代码:

int p = 5;
result = f(p, p);
首先要注意的是,它正在递归地调用自己。 参数c用作计数器,以限制递归调用的数量。它在
f()
的第一行中递减,当它减少到
0
时,递归停止(只返回
1

由于
p
被初始化为5,递归将在5次调用后终止

f()
的第4行中,参数x递增

最后,在最后一行中,递归调用通过x的引用和递减的c进行

显然,函数返回6561作为结果,即9*9*9*9(相当于9*9*9*9*1)。这是这里发生的事情的一个暗示

让我们通过递归跟踪数据:

#0:条目:x=5,c=5,就在最后一行之前:x=6,x=4
#1:条目:x=6,c=4,就在最后一行之前:x=7,x=3
#2:条目:x=7,c=3,就在最后一行之前:x=8,x=2
#3:条目:x=8,c=2,就在最后一行之前:x=9,x=1
#4:条目:x=9,c=1,就在第3行之前:x=9,x=0(在第3行返回,返回1;)

使用
return 1
不会再进行递归调用。现在我们通过递归返回:

#3:x=9=>返回1*9;(计算结果为9)
#2:x=9=>返回9*9;(计算结果为81)
#1:x=9=>返回81*9;(计算结果为729)
#0:x=9=>返回729*9;(估计为6561人)

为什么在所有四个递归级别中x=9?因为它是作为引用而不是值传递的。这意味着对于所有对
f()
的递归调用,x基本上是内存中相同的变量(实际上所有x都是p的别名)。不仅在从第一个递归级别返回之前x=9,而且在
f()返回之后p将是9

尽管两个参数都要传递p,但x在所有递归级别上都是相同的,而x不是(按值传递)。这应该可以解释这种差异


如果你还不明白这一点,你应该仔细阅读参考资料。如前所述,此函数对于学习引用是一个相当复杂的函数,它似乎不是很有用。

我认为函数的最后一行调用了未定义/依赖于编译器的行为,由于变量x作为乘数可以是函数调用前的x,也可以是函数调用后的x,这取决于编译器计算因子f(x,c)和x in的顺序。@JamesMcLeod很抱歉,我不明白你刚才说的。。。请详细说明…thanxOkay,让我们尝试其他方法-第一次调用函数f时,乘数x的值是多少?是6点吗?是10点吗?这取决于编译器如何处理该行。标准没有说明如何处理这个问题,因为x是通过引用传递的,在f()的内部更改x会在f()的外部更改x(简化)。James所说的是:对f()的递归调用所乘以的x可能会被对f()的递归调用所改变。现在的问题是,f(x,c)是与“原始”x相乘,还是与调用所改变的x相乘。这个计算(9*9*9*9)在不同的编译器上可能会有不同的结果。这就是詹姆斯所说的“未定义的行为”。