为何C语言for循环在条件未全部满足时仍执行增量操作?
关于K&R中getline函数的执行流程疑问解答
先明确for循环的执行顺序,这是你理解偏差的核心:for(初始化语句; 条件判断; 增量语句) { 循环体 }
执行步骤是:
- 执行初始化语句
- 判断条件:
- 若成立:执行循环体 → 执行增量语句 → 回到步骤2
- 若不成立:直接退出循环,不会执行增量语句
现在拿你输入的"Hi\n"(字符'H'、'i'、'\n')来一步步走流程(假设lim足够大,比如大于3):
- 初始化
i = 0 - 第一次条件判断:
i < lim-1成立,调用getchar()读到'H',c != EOF和c != '\n'都成立 → 进入循环体- 执行
s[0] = 'H' - 执行增量
++i,此时i = 1
- 执行
- 第二次条件判断:
i < lim-1成立,调用getchar()读到'i',两个判断都成立 → 进入循环体- 执行
s[1] = 'i' - 执行增量
++i,此时i = 2
- 执行
- 第三次条件判断:
i < lim-1成立,调用getchar()读到'\n',此时c != '\n'不成立 → 条件链中断,直接退出循环,不会执行增量语句,此时i还是2 - 进入
if(c == '\n')分支:- 执行
s[2] = '\n' - 执行
++i,此时i = 3
- 执行
- 执行
s[3] = '\0',返回i = 3
如果你的测试结果是返回i=2,那大概率是lim设置得太小(比如lim=3),此时第三次条件判断i=2 < lim-1(即2 < 2)不成立,循环直接退出,不会调用getchar()读取换行符,所以c的值不是'\n',if分支不会执行,直接执行s[2] = '\0',返回i=2——这时候你以为程序读到了换行符,但实际上因为缓冲区的限制,换行符还留在输入缓冲区里,没被读取。
你提到“仅满足三个条件中的两个时,i仍会被自增”,其实不存在这种情况:只有当三个条件全部满足时,才会执行循环体,之后才会执行++i。只要有一个条件不满足,循环就会退出,不会执行增量操作。你之前的误解,本质是没搞清楚for循环的执行顺序,以及逻辑与&&的短路求值特性——一旦前面的条件不成立,后面的表达式就不会执行。
另外你切换前置/后置自增的测试,其实在这里不影响结果:不管是++i还是i++,都是在循环体执行完之后才会执行,最终对i的数值影响是一样的,只是返回值不同,但这里我们不使用增量语句的返回值,所以结果没有区别。
内容的提问来源于stack exchange,提问作者mpriv8
相关产品推荐
相关产品推荐

