C语言递归调用main输出不一致及if与for性能对比疑问
问题解答
一、输出结果不一致的原因
你本地运行得到的0 0 0 0才是符合C/C标准的正确输出,课程给出的4 3 2 1是错误结论,和你选择g还是cygwin编译器没有关联,具体逻辑如下:
- 代码中
static int i=5定义的是静态局部变量,整个程序生命周期内只会初始化一次,所有递归调用的main函数共享同一个i实例,存储在静态存储区而非栈帧中。 - 递归执行流程:
- 初始调用
main:i从5减到4,非0,进入if块递归调用main - 第二层
main:i从4减到3,非0,递归调用main - 第三层
main:i从3减到2,非0,递归调用main - 第四层
main:i从2减到1,非0,递归调用main - 第五层
main:i从1减到0,if条件不成立,直接返回,不执行打印
- 初始调用
- 递归回溯流程:
回到第四层main时,共享的i已经是0,执行printf输出0;依次回溯到第三、第二、第一层main,读取的i都是0,最终输出结果就是0 0 0 0。
课程答案错误的可能原因:
- 讲师给出的示例代码和习题代码不一致,比如把
printf放在了main()递归调用之前,此时会先打印当前的i再递归,就会得到4 3 2 1的输出; - 讲师错误认为静态局部变量会在每次递归调用时重新初始化,或者误认为不同递归层级的
i是独立的栈变量。
二、if(--i)和for循环的性能对比
两者不属于同一类语法结构,没有直接对比的意义:
if(--i)是单次条件判断逻辑,单就--i加条件判断的操作本身而言,和for循环头部的自减+条件判断生成的汇编指令完全一致,没有性能差异。- 如果你是想问「用
if+递归实现循环逻辑」和普通for循环的性能差异:for循环性能远优于递归实现。递归会产生额外的函数调用开销,包括栈帧创建、返回地址存储、寄存器上下文保存/恢复,递归深度过高还会触发栈溢出;而for循环是本地跳转逻辑,没有额外开销,现代编译器的循环优化也更加成熟,不管是执行速度还是内存占用都更有优势。
内容的提问来源于stack exchange,提问作者Gendozz
相关产品推荐
相关产品推荐

