控制结构掌握C语言的控制流程编写具有逻辑判断和循环能力的程序The computer is incredibly fast, accurate, and stupid. Man is unbelievably slow, inaccurate, and brilliant. The marriage of the two is a force beyond calculation.— Leo Cherne计算机极快、精确且愚蠢。人类极慢、不精确且聪明。两者的结合是一种超乎计算的力量。First solve the problem, then write the code.— John Johnson先解决问题再写代码。 不积跬步无以至千里不积小流无以成江海。控制结构是程序的骨架掌握好每一步才能构建复杂的程序逻辑。通俗理解 - 控制结构就像交通信号灯if-else就像十字路口的红绿灯——条件满足就走不满足就停switch就像多岔路口的指示牌——根据不同的方向走不同的路for循环就像跑步时的计圈器——从第1圈跑到第N圈while循环就像等公交——没等到就一直等等到为止break就像紧急刹车——立即停止循环continue就像跳过广告——跳过本次循环的剩余部分抽象理解 - 控制流的本质顺序执行CPU默认的执行方式一条指令接一条指令分支跳转根据条件改变程序计数器PC的指向循环条件跳转的循环形式通过回跳实现重复执行控制结构本质是有条件的goto编译器将其转化为条件跳转指令前置知识运算符与表达式后续内容函数本章导读控制结构是编程语言的核心它决定了程序的执行流程。C语言提供了多种控制结构条件判断if/switch、循环for/while/do-while以及跳转break/continue/goto。掌握这些控制结构是编写复杂程序的基础。目录1. if-else语句2. switch语句3. while循环4. do-while循环5. for循环6. break与continue7. goto语句1. if-else语句#includestdio.hintmain(void){intscore85;/* 基本的if语句 */if(score60){printf(及格\n);}/* if-else语句 */if(score60){printf(及格\n);}else{printf(不及格\n);}/* 多分支if-else if-else语句 */if(score90){printf(优秀\n);}elseif(score80){/* else if 可以有多个 */printf(良好\n);}elseif(score60){printf(及格\n);}else{printf(不及格\n);/* 以上条件都不满足时执行 */}return0;}1. if语句的注意事项#includestdio.hintmain(void){/* 陷阱1 和 混淆 */intx0;if(x5){/* 赋值语句x55为真永远成立 */printf(始终输出\n);/* 会输出 */}/* 预防措施将常量放在左边 *//* if (5 x) { 如果写成 if (5 x)编译错误立即发现 } *//* 陷阱2悬空else */inta10,b20,c30;if(ab)if(ac)printf(a最大\n);else/* 这个else属于最近的if (a c)而不是if (a b) */printf(a不大于b\n);/* 结果与预期不同 *//* 正确做法使用花括号明确 */if(ab){if(ac){printf(a最大\n);}}else{printf(a不大于b\n);}return0;}2. switch语句#includestdio.hintmain(void){intday3;switch(day){case1:printf(星期一\n);break;case2:printf(星期二\n);break;case3:printf(星期三\n);break;case4:printf(星期四\n);break;case5:printf(星期五\n);break;case6:case7:/* case 6和7共享同一段代码 */printf(周末\n);break;default:/* 默认情况以上case都不匹配时执行 */printf(无效输入\n);}return0;}1. switch的穿透特性#includestdio.hintmain(void){intn2;/* 故意利用穿透case后没有break时会继续执行下一个case */switch(n){case1:printf(执行case 1\n);case2:printf(执行case 2\n);case3:printf(执行case 3\n);break;default:printf(执行default\n);}return0;}2. switch的限制switch表达式必须是整数类型char, short, int, long 及其无符号类型case标签必须是整数常量表达式不能是变量不能使用浮点数和字符串作为case值3. while循环#includestdio.hintmain(void){inti1;while(i5){printf(%d ,i);i;}printf(\n);return0;}1. 死循环#includestdio.hintmain(void){while(1){/* 无限循环通常配合break退出 */}return0;}4. do-while循环#includestdio.hintmain(void){intnum;do{printf(请输入正数: );scanf(%d,num);}while(num0);printf(你输入的是: %d\n,num);return0;}1. while vs do-while#includestdio.hintmain(void){intx10;while(x5){printf(while: x %d\n,x);x;}x10;do{printf(do-while: x %d\n,x);x;}while(x5);return0;}5. for循环#includestdio.hintmain(void){for(inti1;i5;i){printf(%d ,i);}printf(\n);/* 嵌套循环九九乘法表 */for(inti1;i9;i){for(intj1;ji;j){printf(%d*%d%d ,j,i,i*j);}printf(\n);}return0;}1. for循环的多种写法#includestdio.hintmain(void){for(inti0;i5;i){printf(%d ,i);}printf(\n);inti0;for(;i5;i){printf(%d ,i);}printf(\n);intj0;for(;j5;){printf(%d ,j);j;}printf(\n);for(inta0,b10;ab;a,b--){printf(a%d, b%d\n,a,b);}return0;}6. break与continue#includestdio.hintmain(void){for(inti1;i10;i){if(i5){continue;}if(i8){break;}printf(%d ,i);}printf(\n);return0;}1. break与嵌套循环#includestdio.hintmain(void){for(inti0;i3;i){for(intj0;j3;j){if(i1j1){break;}printf((%d,%d) ,i,j);}printf(\n);}return0;}7. goto语句#includestdio.hintmain(void){printf(开始\n);gotoskip;printf(这行被跳过\n);skip:printf(跳转到这里\n);return0;}1. goto的典型使用场景#includestdio.h#includestdlib.hintmain(void){int*data1NULL;int*data2NULL;int*data3NULL;data1(int*)malloc(100*sizeof(int));if(!data1)gotocleanup;data2(int*)malloc(200*sizeof(int));if(!data2)gotocleanup;data3(int*)malloc(300*sizeof(int));if(!data3)gotocleanup;printf(所有资源申请成功\n);gotosuccess;cleanup:printf(发生错误释放资源\n);free(data1);free(data2);free(data3);success:printf(程序结束\n);return0;}#includestdio.hintmain(void){intmatrix[3][3]{{1,2,3},{4,5,6},{7,8,9}};inttarget5;intfound0;for(inti0;i3;i){for(intj0;j3;j){if(matrix[i][j]target){found1;printf(找到 %d 在位置 (%d,%d)\n,target,i,j);gotofound_exit;}}}found_exit:if(!found){printf(未找到\n);}return0;}2. goto的使用建议场景推荐替代方案多层循环跳出✅ 合理使用标志变量代码更复杂统一错误处理✅ 合理使用嵌套if代码更深随意跳转❌ 不推荐使用函数、循环、条件判断8. 本章小结1. 核心知识点类别要点if-else条件判断注意悬空else和与的混淆switch多分支选择注意break和穿透特性while先判断后执行适用于不确定次数的循环do-while先执行后判断至少执行一次for最常用的循环结构初始化和更新集中在头部break跳出整个循环continue跳过本次循环剩余部分继续下一次goto无条件跳转仅用于错误处理和跳出多层循环2. 常见陷阱陷阱说明死循环忘记更新循环变量导致条件永远为真悬空elseelse匹配最近的if需使用花括号明确switch忘记break导致case穿透有时也是故意利用break只跳一层嵌套循环中break只跳出最内层循环goto滥用导致代码难以阅读和维护3. 练习编写程序输入一个年份判断是否为闰年使用循环实现1到100的累加输出九九乘法表编写一个简单的猜数字游戏随机生成1-100的数字用户猜测使用switch实现一个简单的计算器加减乘除上一章第2章运算符与表达式下一章第4章函数4. 相关章节什么是goto — goto的使用场景与争议循环遍历与递归 — 循环与递归的对比
控制结构_
控制结构掌握C语言的控制流程编写具有逻辑判断和循环能力的程序The computer is incredibly fast, accurate, and stupid. Man is unbelievably slow, inaccurate, and brilliant. The marriage of the two is a force beyond calculation.— Leo Cherne计算机极快、精确且愚蠢。人类极慢、不精确且聪明。两者的结合是一种超乎计算的力量。First solve the problem, then write the code.— John Johnson先解决问题再写代码。 不积跬步无以至千里不积小流无以成江海。控制结构是程序的骨架掌握好每一步才能构建复杂的程序逻辑。通俗理解 - 控制结构就像交通信号灯if-else就像十字路口的红绿灯——条件满足就走不满足就停switch就像多岔路口的指示牌——根据不同的方向走不同的路for循环就像跑步时的计圈器——从第1圈跑到第N圈while循环就像等公交——没等到就一直等等到为止break就像紧急刹车——立即停止循环continue就像跳过广告——跳过本次循环的剩余部分抽象理解 - 控制流的本质顺序执行CPU默认的执行方式一条指令接一条指令分支跳转根据条件改变程序计数器PC的指向循环条件跳转的循环形式通过回跳实现重复执行控制结构本质是有条件的goto编译器将其转化为条件跳转指令前置知识运算符与表达式后续内容函数本章导读控制结构是编程语言的核心它决定了程序的执行流程。C语言提供了多种控制结构条件判断if/switch、循环for/while/do-while以及跳转break/continue/goto。掌握这些控制结构是编写复杂程序的基础。目录1. if-else语句2. switch语句3. while循环4. do-while循环5. for循环6. break与continue7. goto语句1. if-else语句#includestdio.hintmain(void){intscore85;/* 基本的if语句 */if(score60){printf(及格\n);}/* if-else语句 */if(score60){printf(及格\n);}else{printf(不及格\n);}/* 多分支if-else if-else语句 */if(score90){printf(优秀\n);}elseif(score80){/* else if 可以有多个 */printf(良好\n);}elseif(score60){printf(及格\n);}else{printf(不及格\n);/* 以上条件都不满足时执行 */}return0;}1. if语句的注意事项#includestdio.hintmain(void){/* 陷阱1 和 混淆 */intx0;if(x5){/* 赋值语句x55为真永远成立 */printf(始终输出\n);/* 会输出 */}/* 预防措施将常量放在左边 *//* if (5 x) { 如果写成 if (5 x)编译错误立即发现 } *//* 陷阱2悬空else */inta10,b20,c30;if(ab)if(ac)printf(a最大\n);else/* 这个else属于最近的if (a c)而不是if (a b) */printf(a不大于b\n);/* 结果与预期不同 *//* 正确做法使用花括号明确 */if(ab){if(ac){printf(a最大\n);}}else{printf(a不大于b\n);}return0;}2. switch语句#includestdio.hintmain(void){intday3;switch(day){case1:printf(星期一\n);break;case2:printf(星期二\n);break;case3:printf(星期三\n);break;case4:printf(星期四\n);break;case5:printf(星期五\n);break;case6:case7:/* case 6和7共享同一段代码 */printf(周末\n);break;default:/* 默认情况以上case都不匹配时执行 */printf(无效输入\n);}return0;}1. switch的穿透特性#includestdio.hintmain(void){intn2;/* 故意利用穿透case后没有break时会继续执行下一个case */switch(n){case1:printf(执行case 1\n);case2:printf(执行case 2\n);case3:printf(执行case 3\n);break;default:printf(执行default\n);}return0;}2. switch的限制switch表达式必须是整数类型char, short, int, long 及其无符号类型case标签必须是整数常量表达式不能是变量不能使用浮点数和字符串作为case值3. while循环#includestdio.hintmain(void){inti1;while(i5){printf(%d ,i);i;}printf(\n);return0;}1. 死循环#includestdio.hintmain(void){while(1){/* 无限循环通常配合break退出 */}return0;}4. do-while循环#includestdio.hintmain(void){intnum;do{printf(请输入正数: );scanf(%d,num);}while(num0);printf(你输入的是: %d\n,num);return0;}1. while vs do-while#includestdio.hintmain(void){intx10;while(x5){printf(while: x %d\n,x);x;}x10;do{printf(do-while: x %d\n,x);x;}while(x5);return0;}5. for循环#includestdio.hintmain(void){for(inti1;i5;i){printf(%d ,i);}printf(\n);/* 嵌套循环九九乘法表 */for(inti1;i9;i){for(intj1;ji;j){printf(%d*%d%d ,j,i,i*j);}printf(\n);}return0;}1. for循环的多种写法#includestdio.hintmain(void){for(inti0;i5;i){printf(%d ,i);}printf(\n);inti0;for(;i5;i){printf(%d ,i);}printf(\n);intj0;for(;j5;){printf(%d ,j);j;}printf(\n);for(inta0,b10;ab;a,b--){printf(a%d, b%d\n,a,b);}return0;}6. break与continue#includestdio.hintmain(void){for(inti1;i10;i){if(i5){continue;}if(i8){break;}printf(%d ,i);}printf(\n);return0;}1. break与嵌套循环#includestdio.hintmain(void){for(inti0;i3;i){for(intj0;j3;j){if(i1j1){break;}printf((%d,%d) ,i,j);}printf(\n);}return0;}7. goto语句#includestdio.hintmain(void){printf(开始\n);gotoskip;printf(这行被跳过\n);skip:printf(跳转到这里\n);return0;}1. goto的典型使用场景#includestdio.h#includestdlib.hintmain(void){int*data1NULL;int*data2NULL;int*data3NULL;data1(int*)malloc(100*sizeof(int));if(!data1)gotocleanup;data2(int*)malloc(200*sizeof(int));if(!data2)gotocleanup;data3(int*)malloc(300*sizeof(int));if(!data3)gotocleanup;printf(所有资源申请成功\n);gotosuccess;cleanup:printf(发生错误释放资源\n);free(data1);free(data2);free(data3);success:printf(程序结束\n);return0;}#includestdio.hintmain(void){intmatrix[3][3]{{1,2,3},{4,5,6},{7,8,9}};inttarget5;intfound0;for(inti0;i3;i){for(intj0;j3;j){if(matrix[i][j]target){found1;printf(找到 %d 在位置 (%d,%d)\n,target,i,j);gotofound_exit;}}}found_exit:if(!found){printf(未找到\n);}return0;}2. goto的使用建议场景推荐替代方案多层循环跳出✅ 合理使用标志变量代码更复杂统一错误处理✅ 合理使用嵌套if代码更深随意跳转❌ 不推荐使用函数、循环、条件判断8. 本章小结1. 核心知识点类别要点if-else条件判断注意悬空else和与的混淆switch多分支选择注意break和穿透特性while先判断后执行适用于不确定次数的循环do-while先执行后判断至少执行一次for最常用的循环结构初始化和更新集中在头部break跳出整个循环continue跳过本次循环剩余部分继续下一次goto无条件跳转仅用于错误处理和跳出多层循环2. 常见陷阱陷阱说明死循环忘记更新循环变量导致条件永远为真悬空elseelse匹配最近的if需使用花括号明确switch忘记break导致case穿透有时也是故意利用break只跳一层嵌套循环中break只跳出最内层循环goto滥用导致代码难以阅读和维护3. 练习编写程序输入一个年份判断是否为闰年使用循环实现1到100的累加输出九九乘法表编写一个简单的猜数字游戏随机生成1-100的数字用户猜测使用switch实现一个简单的计算器加减乘除上一章第2章运算符与表达式下一章第4章函数4. 相关章节什么是goto — goto的使用场景与争议循环遍历与递归 — 循环与递归的对比