C程序对main()的递归调用,带参数和不带参数
为什么它会给出一个分段错误(内核转储)并且在第一种情况下没有输出?有人能解释程序是如何使用参数递归调用主程序的吗C程序对main()的递归调用,带参数和不带参数,c,recursion,main,C,Recursion,Main,为什么它会给出一个分段错误(内核转储)并且在第一种情况下没有输出?有人能解释程序是如何使用参数递归调用主程序的吗 #include <stdio.h> int main() { static int i = 2; if (i<7) { main(); printf("%d ", i); i++; //main(10); } } #包括 int main() { 静态int i=2;
#include <stdio.h>
int main()
{
static int i = 2;
if (i<7)
{
main();
printf("%d ", i);
i++;
//main(10);
}
}
#包括
int main()
{
静态int i=2;
如果(i您首先调用main()
,然后递增i
if (i<7)
{
main(); // <-- main called when i still 2
printf("%d ", i);
i++; // <-- statement never reached
//main(10);
}
TL;DR堆栈溢出(双关语或非双关语,双关语都适用)
首先:一些重要信息
这种情况与是否将参数传递给main()
无关。实际上,根据最新的C标准,C11
,对于托管环境,main()
的一致性签名是int main(void)
,然后,main(10);
是错误的
现在,说到实际问题
- 在第一种情况下,
i
值的更改发生在调用main()
之后,因此实际上,i
的值永远不会更改,因为控件永远不会到达修改i
的语句。因此,这是一个无限循环,也因为对main()的递归调用
,发生堆栈溢出
- 在后一种情况下,
i
值在调用main()
之前得到更新,因此该值实际上反映了。因此,在某个点上(实际上在4次出现之后),if
条件满足假条件,递归调用结束,堆栈展开
调用main()后的第一种情况是i+,这意味着程序没有机会添加i,并进入无限循环,堆栈溢出!哈哈
但第二种情况是,在调用main之前先减小i。第一种情况:
i++
在调用main
之后被定位。因此i
将始终等于2,因为您永远不会到达代码的这一部分。然后您每次调用main
函数,导致无限递归,从而导致分段错误。这种情况的解决方法是在调用之前增加i这是一个主要的功能
if (i<7)
{
i++; // Increment before calling the main function, so i value is changed
main();
printf("%d ", i);
}
如果(i在第一种情况下:
“i”永远不会递增,因此您在无限循环中运行并获得溢出
在第二种情况下:
在显示“i”的值之前调用递归,在四次调用“i”等于0且递归堆栈展开之后调用递归
在递归调用之前修改您的条件并执行输出。在第一种情况下,i从不递增,因此,main会不断被调用,很快程序就没有可用的堆栈内存
在第二种情况下,i的最后更新值在i的整个生命周期内保持不变。由于i是静态的,程序在所有迭代中引用相同的内存地址。在打印i时,您会看到最后更新的值,即0,作为输出。您希望在每种情况下调用main
多少次?您永远不会调用>i++
在第一种情况下,第一种情况下为6次,第二种情况下为4次@DavidSchwartz@FedericoklezCulloca考虑到I
的值从未改变,我很想听听你对为什么在第一种情况下调用main
6次的解释。你为什么要用main
玩这样的游戏。你的问题与n无关函数的名称或main
是特殊的事实。您只是很难理解递归是如何工作的。@好吧,答案中已经解释了。您也可以在第二次调用中调用main()。
if (i<7)
{
i++;
main();
printf("%d ", i);
//main(10);
}
if (i<7)
{
i++; // Increment before calling the main function, so i value is changed
main();
printf("%d ", i);
}