【问题标题】:Can someone explain output of this C program? [duplicate]有人可以解释这个 C 程序的输出吗? [复制]
【发布时间】:2018-07-16 19:50:00
【问题描述】:
#include <stdio.h>

int main()
{
    static int i = 5;

    if (--i)
    {
        main();
        printf("%d\n", i); // will this line executes ?
    }

    return 0;
} 

输出:

0
0
0
0

在 main() 下执行代码;每次主递归调用发生并从该程序终止时执行时,都会将 printf 语句指令放入堆栈?

【问题讨论】:

  • 这是基本递归。我建议您阅读它以及 static 的工作原理。
  • 欢迎来到 SO。请始终展示您当前的努力并告诉我们您究竟在哪里遇到问题。如果输出不是您所期望的,请告诉我们您的期望。
  • @DevSolar 该网站应该建立一个可搜索的知识库,其他人可以将其用作参考网站......不可能有一个标题为“有人可以解释这个程序的输出”的问题除了代码没有其他文字,将永远帮助其他人
  • @M.M:这个网站也应该帮助用户解决他们的问题;我们是否因为给他们一个更好的标题需要OP 没有关于该问题的知识而对问题投反对票?如果他知道所有关于 static 和递归的知识,他就不必问了
  • 事实上,对于完全相同的程序,这个问题已经被问过至少 5 次了。我将其作为我找到的最旧的副本关闭。

标签: c


【解决方案1】:

i 通过对main 的连续调用而减少,直到达到零。

然后 printf 被调用每个级别的递归。

(请注意,从自身调用 main 的行为是明确定义的,尽管在 C 中是不明智的,但在 C++ 中该行为是未定义。)

【讨论】:

  • 调用 main() 在 C++ 中不是未定义的。禁止使用。
  • @Peter:你是什么?编译器不必发出诊断。
  • @Bathesba - 1998 C++ 标准中的实际措辞是“函数main() 不得在程序中使用(3.2)”。在 3.2 节中,如果函数或对象的名称出现在可能求值的表达式中,则称其为已使用。在任何讨论中都没有提到“不需要诊断”或未定义的行为——这意味着(第 1.4 节)这是一个可诊断的规则。
  • @peter 我想你应该问一个关于 c++ 标签的问题。
【解决方案2】:
if (--i)

这将在第一次评估为真 (--i == 4)。代码递归到main()。 (Recursion:一个函数调用自己。)

由于istatic,它将保留其值4(与自动变量相反,它将再次初始化为5)。 if (--i) 在此第二次 执行main() 中将再次为真(评估为3),并将再次调用main()(用于函数的第三次执行)。

--i == 2--i == 1 相同,总共有四次执行 main()(包括第一个非递归的)将 if 条件评估为真。

下一次递归会将if 条件评估为--i == 0,因此为假。跳过if 子句,函数调用将返回。 i 在这一点上为零,并且 -- 是 static,即对于所有 main() 实例只有一个持久的i -- 将保持该值。

main() 调用堆栈的上一层 - 评估 --i == 1,然后调用 main() 并等待它返回的那个 - 现在将在调用 main() 之后继续执行语句, 和printf() i... 的 当前 值...即0

同样的情况又发生了 3 次(总共 4 次),直到最上面的 main() 返回。你得到的当前值是i 的四倍,即0


请注意,在 C 中允许从您的程序调用 main(),但在 C++ 中则不允许。这专门用于递归调用main();对于其他功能,允许使用任何一种语言。

【讨论】:

    【解决方案3】:

    (--i) 会在第一次调用时将 i 的值减为 4 并继续减 i 直到 (i==0) 由于递归。 由于您已使用 static 关键字声明变量 i ,因此为其分配了一个内存,并且所有更改都反映回它

    【讨论】:

    • 如果OP去掉static,就会无限循环,没有输出。
    • printf 语句将在哪个阶段执行..?这些指令会在堆栈中并在从整个程序中弹出时执行吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-18
    • 2021-07-22
    • 2020-07-15
    • 2013-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多