【问题标题】:Use of reference variables in C++ [duplicate]在 C++ 中使用引用变量 [重复]
【发布时间】:2021-09-11 14:40:34
【问题描述】:

我遇到了以下问题:

#include <stdio.h>

int f(int &x, int c)
{
    c  = c - 1;
    if (c == 0) return 1;
    x = x + 1;
    return f(x, c) * x;
}
int main()
{
    int p = 5;
    printf("%d", f(p, p));
}

据我所知,递归调用应该可以工作,并且每次递归调用时, c 的值应该减少 1 , x 的值应该增加 1 。但是,如果我这样计算,结果是 3024。但是,在执行时,输出结果是 6561。我不确定这个答案是怎么来的。

我有指向提出这个问题的文章的链接,但我不明白 x 将如何保持不变,如以下链接所述:https://www.geeksforgeeks.org/c-references-question-1/

有人可以帮我处理这段代码背后的工作吗?

【问题讨论】:

  • 尝试使用调试器单步执行,或添加输出语句 (ideone.com/uoO3Ak) 以观察每个递归函数调用的 cx 的值。
  • 返回值不取决于f(x, c) 还是xreturn f(x, c) * x 中首先被评估?
  • 这是未定义的行为,因为 x 在乘法的一个操作数中被修改并在另一个操作数中读取。
  • 这个问题之前stackoverflow.com/questions/38933101/…已经回答过
  • @MathiasJ 从计算隐式括号的位置而言,这是运算符优先级,它不会告诉您操作数的求值顺序。

标签: c++ recursion reference pass-by-reference


【解决方案1】:

由于Undefined behavior,可能有任何结果。

由于 x 是通过引用传递的,所以最后的分配很重要。因此,我们有:

9*9*9*9*1=6561

我们延迟了对f(x, c) * x 的评估,所有后续递归调用都可以访问x。我们以这种方式递增x,直到c 等于0,这意味着我们将x 递增到9

当我们遇到基本情况(c == 0)时,当前调用返回1,而x 已经是9

然后我们计算乘法1 * x * x * x * x,其中x 等于9。因此,6561.

完美的解释? 没那么多

有趣的是在 C++ 中没有从左到右或从右到左求值的概念

任何表达式的任何部分的求值顺序,包括 未指定函数参数的评估(有一些例外 下面列出)。编译器可以评估操作数和其他 子表达式以任何顺序排列,并且当 再次计算相同的表达式。

意思是,虽然这个逻辑这次通过了,但下一次对我来说可能不会这样,或者如果你自己运行它。

【讨论】:

  • UB 应该更醒目。如果我们开始复制他们的代码而不调用 UB...
  • @Jeffrey 担心“设置和妙语”行不通。等一下。
  • 爱大胆!好多了。
  • 当副本进入时,我不认为这实际上是 undefined 行为,但操作数的评估是不确定的,因此它可以返回多个可能的值。 “它可以返回指数级的许多可能性”和“实际上任何程序行为都是可以接受的”之间仍然存在很大差异。
  • @NathanPierson 是的,如果可以遵循逻辑,它倾向于成为所谓的未指定行为
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-21
  • 1970-01-01
  • 1970-01-01
  • 2020-09-22
  • 1970-01-01
  • 2020-08-22
相关资源
最近更新 更多