switch与while语句中i++行为差异的原因问询
为什么
while(i++)和switch(i++)里的i++表现看起来不同? 其实核心真相是:i++这个后置自增运算符的行为在两种场景下是完全一样的——它都会先返回变量当前的原始值,再对变量执行+1操作。你感觉到的差异,是while和switch这两个语句对这个表达式的使用时机和逻辑不同导致的。
一、先看while(i++ <= 10)的逻辑
while语句的执行流程是:
- 先计算括号内整个条件表达式的值,判断是否为真(非0)
- 如果条件为真,进入循环体执行代码;执行完循环体后,回到步骤1重新判断
- 如果条件为假,直接退出循环
对于i++ <= 10这个表达式:
- 第一步:取
i的当前值,和10比较,得到条件的真假结果 - 第二步:不管条件真假,
i都会立刻自增1
举个你给的例子:
#include <stdio.h> int main() { int age = 20; while (age++ <= 65) { if ((age % 20) == 0) { printf("You are %d years old\n", age); } } return 0; }
这里的执行过程是:
- 初始
age=20,第一次判断20 <=65为真,然后age变成21 - 进入循环体,判断
21%20 ==0?结果是1,不成立,所以不打印 - 回到条件判断:
21 <=65为真,age变成22……以此类推 - 当
age=59时,判断59<=65为真,age变成60,进入循环体,60%20==0成立,打印You are 60 years old - 继续循环,直到
age=65时,判断65<=65为真,age变成66,进入循环体,66%20==6不成立 - 下一次判断
66<=65为假,退出循环
哦对了,你给出的预期输出写的是20、40、60,这其实是个小误区——实际运行这段代码并不会打印20,因为第一次进入循环体时age已经是21了。如果要打印20,你需要把printf里的age改成age-1,或者用前置自增++age调整逻辑。
二、再看switch(i++)的逻辑
switch语句的执行流程是:
- 先计算
switch()括号里表达式的结果,这个结果会作为后续匹配case的依据 - 根据这个结果跳转到对应的
case(或default)开始执行代码 - 遇到
break才会退出switch,否则会继续执行后续所有case的代码
对于switch(i++):
- 第一步:取
i的当前值,作为switch的匹配值 - 第二步:立刻对
i执行自增1操作 - 第三步:用刚才拿到的匹配值去匹配
case,执行对应代码
看你给的switch示例:
#include <stdio.h> int main() { int i = 0; while (i < 3) { switch (i++) { case 0:printf("print 0"); case 1:printf("print 1"); case 2:printf("print 2"); default:printf("Oh no!"); } putchar('\n'); } return 0; }
执行过程拆解:
- 初始
i=0,满足i<3,进入循环 - 计算
switch(i++):先取i=0作为匹配值,然后i变成1 - 匹配
case 0,依次执行所有后续语句,输出print 0print 1print 2Oh no!,换行 - 现在
i=1,满足i<3,进入循环 - 计算
switch(i++):取i=1作为匹配值,i变成2 - 匹配
case1,执行后续语句,输出print 1print 2Oh no!,换行 - 现在
i=2,满足i<3,进入循环 - 计算
switch(i++):取i=2作为匹配值,i变成3 - 匹配
case2,执行后续语句,输出print 2Oh no!,换行 - 现在
i=3,不满足i<3,退出循环
总结一下
两种场景里的i++没有任何行为差异,都是先返回当前值,再自增。你觉得不一样,是因为:
- 在
while里,你关注的是条件判断后i的变化,以及循环体里i的值 - 在
switch里,你关注的是case匹配的依据(是i自增前的值),以及switch块里i已经是自增后的值
本质上都是后置自增运算符的标准行为,只是两个语句的执行逻辑让它看起来“不一样”而已。
内容的提问来源于stack exchange,提问作者Lyrk
相关产品推荐
相关产品推荐

