C语言系列之——(6)C语言中的控制语句

📅 2026/8/14 13:40:19
C语言系列之——(6)C语言中的控制语句
c语言中的控制语句1.条件判断语句1.1 ifa if……else……b 嵌套ifb.1悬空else问题1.2 switch2.循环执行语句2.1 do while2.2 while2.3 fora. for的多表达式问题b. for的无表达式问题3.转向语句3.1 break 和 continue3.2 goto3.3 returna.return的使用规范控制语句用于控制程序的执行流程以实现程序的各种结构方式C语言有三种结构方式顺序结构、选择结构和循环结构他们由特定语句的定义符组成而控制语句则有九种这九种可分为以下三类条件判断语句/分支语句if , switch循环执行语句do while , while , for转向语句break goto continue return1.条件判断语句1.1 ifif语句的语法形式如下if(表达式)语句表达式为真成立语句执行反之则不执行if默认只包含紧跟的第一条语句若有多条待执行语句需要用大括号{}将语句包含在内if(表达式){语句1语句2……}上面的条件判断只能实现一种情况下的行为执行但实际中我们常常想实现多种情况的对应行为执行如不下雨就不带伞下雨就带伞如果bob爱吃辣就给他辣条如果爱吃酸就给他柠檬如果……这时只用if一个一个情况识别显然不太可取实际上if可以“升级”为下面的几种形式a if……else……对于 “不下雨就不带伞下雨就带伞” 这种仅有两种对立即只有a成立和a不成立的情况可以使用if else语句形式如下if(表达式1)语句1else语句2表达式1为真就执行语句1为假就执行语句2,相当于:如果(表达式1为真)就(执行语句1)否则 就(执行语句2)if else区分的两种情况是对立关系即这两种情况互斥且这两种情况组合起来就是全集全部情况b 嵌套if而在将一个全集分成多个部分有大于等于三种互斥情况时可以用嵌套if核心是如果……否则……的嵌套条件判断如下if(表达式1)语句1else{if(表达式2)语句2else{……}}上面的else里又有if可以简化成下面这种形式if(表达式1)语句1elseif(表达式2)语句2elseif(表达式3)语句3elseif(……)……else语句n上面代码的嵌套逻辑可用下图表示当然if里也可以嵌套if(表达式1){if(表达式2)语句1else//表示满足表达式1情况下不满足表达式2{……}}else{……}嵌套if重在如果……否则……的层层逻辑判断在逻辑满足下if的嵌套是灵活多变的b.1悬空else问题请看下面代码#includestdio.hintmain(){inta0;intb2;if(a1)if(b2)printf(hehe\n);elseprintf(haha\n);return0;}上面代码中的else并不是和if(a 1)匹配而是和if(b 2)匹配,相当于#includestdio.hintmain(){inta0;intb2;if(a1){if(b2)printf(hehe\n);elseprintf(haha\n);}return0;}C语言并不是和python一样靠缩进来划分代码块而是只会按语法符号{}划分代码块作用域else总是跟自己所在作用域内离它最近、尚未配对的 if匹配要让else和if(a 1)匹配代码应改为#includestdio.hintmain(){inta0;intb2;if(a1){if(b2)printf(hehe\n);}elseprintf(haha\n);return0;}1.2 switchswitch是一种特殊形式的 if else 结构用于判断表达式条件有多个结果的情况语法形式如下switch(表达式){case整型常量表达式1://case后必须是一个整型的常量不能是1.0这种小数也不能是k这种变量语句1case整型常量表达式2:语句2……}switch的逻辑是先计算表达式的结果然后从和结果匹配的case处开始依次执行后续语句请看下面代码#includestdio.hintmain(){inta1;intb;switch(a){case1:b1;case2:b2;case3:b3;}printf(%d,b);return0;}上面的代码展现出了使用switch语句的一个大坑就是switch语句只会根据表达式不同的值从不同的case处开始并不会局限于只实现一个case区域里的代码而是从开始位置一直执行到尾所以上面代码最后打印结果为3而不是1要想只执行一个分支的语句需要在语句后加上breakswitch(表达式){case整型常量表达式1:语句1break;case整型常量表达式2:语句2break;……}换句话说case决定了分支的入口break决定了分支的出口在使用 switch 语句的时候我们经常可能遇到一种情况比如 switch 后的表达式中的值无法匹配代码中的 case 语句的时候这时候要不就不做处理要不就得在 switch 语句中加入default子句switch(表达式){case整型常量表达式1:语句1break;case整型常量表达式2:语句2break;……default:语句nbreak;}default其实就相当于另一个有自己特殊对应值的case入口这个入口的条件是表达式的值和其他case的值都不匹配所以default和case的顺序没有一定的规定default可以不放在末尾甚至可以放在开头因为它其实也就是一个条件特殊的入口不过通常还是放在末尾2.循环执行语句2.1 do while循环语句中do while的使用频率较低其语法形式如下do循环语句while(表达式);它的执行逻辑为开始先执行循环语句再判断表达式真假若表达式为真则重复上诉操作若为假则停止执行循环语句也就是说do while的循环语句至少会被执行一次注意do while默认只包含do紧跟的第一条语句若有多条待执行语句需要用大括号{}将语句包含在内下面用打印1~10的数字来演示do while的使用#includestdio.hintmain(){inti1;do{printf(%d ,i);i;}while(i11);return0;}2.2 whilewhile语句的语法结构和if很相似while(表达式)循环语句它的执行逻辑为开始先判断表达式真假若表达式为真执行循环语句每执行完都会重新判断表达式真假为真则重复上述步骤若为假则停止执行循环语句同样的while也默认只包含紧跟的第一条语句若有多条待执行语句需要用大括号{}将语句包含在内下面用打印1~10的数字来演示while的使用#includestdio.hintmain(){inti1;while(i11){printf(%d ,i);i;}return0;}2.3 forfor循环的使用频率较高其复杂程度也比前两种更高其语法形式如下for(表达式1;表达式2;表达式3)循环语句其中表达式1用于循环变量的初始化表达式2用于循环结束条件的判断表达式3用于循环变量的调整它的执行可用下图表示for 循环最先执行一次表达式 1 完成变量初始化随后进入循环判断逻辑先运行表达式 2 做条件判定若条件为假循环直接结束若条件为真则执行循环语句。执行循环语句时如果碰到 break会直接终止整个循环如果碰到 continue会立刻停止当前循环剩下的代码跳到表达式 3 执行变量调整。正常走完循环语句后同样会执行表达式 3 更新变量之后再次回到表达式 2 重新判断条件不断重复该流程直到表达式 2 判定为假退出循环。【表达式1只在开始时执行这一次后续就不会再执行表达式1】同样的while也默认只包含紧跟的第一条语句若有多条待执行语句需要用大括号{}将语句包含在内下面用打印1~10的数字来演示for的使用#includestdio.hintmain(){for(inti1;i11;i)printf(%d ,i);return0;}a. for的多表达式问题for在表达式1中可同时初始化多个同类型变量多个变量使用逗号分隔如for(inti1,g3,……;表达式2;表达式3)循环语句for在表达式2和表达式3中同样也可以利用逗号运算符书写多段语句,但需要注意的是将多个表达式用逗号分隔组成多段语句实际上构成了逗号表达式执行时会依次执行每个表达式最终将最后一个表达式的值作为整个逗号表达式的值而这对靠判断真假来决定循环的终止或执行的表达式2来说是个大坑请看下面代码#includestdio.hintmain(){for(inti1,e1;i11,e5;i,e)printf(%d%d ,i,e);return0;}上面的代码表达式2的位置判断的是整个逗号表达式的真假而该逗号表达式的值就是e 5的值与i 11无关所以即使i 11,循环依旧进行如果想实现多表达式作用的真假判断可以借助逻辑运算符下面代码用将两个表达式用并且关系关联起来使循环开始即结束#includestdio.hintmain(){for(inti1,e1;(i11)(e5);i,e)printf(%d%d ,i,e);return0;}b. for的无表达式问题for 循环允许省略任意一个、两个甚至全部三个表达式但底层执行逻辑不会改变。程序运行到被省略的表达式位置时等价于执行一条空语句。特别注意如果省略表达式 2条件判断部分该位置默认判定为恒真循环会持续运行形成死循环这种情况下想要退出循环只能依靠循环体内的break语句否则循环永远不会终止。3.转向语句在程序运行时我们时常需要改变代码默认的顺序执行流程循环里提前退出、跳过本轮代码、直接跳转到指定位置、结束函数等场景都十分常见。C 语言提供了四类转向语句break、continue、goto、return用来灵活调整程序执行流向。下面我们逐一讲解它们的作用与使用规范。3.1 break 和 continuebreak直接永久终止当前循环代码执行到 break 时会立刻跳出当前循环运行循环外部后续代码continue放弃本次循环剩下尚未执行的代码直接开启下一轮循环下面我们直接通过实际代码感受这两个转向语句#includestdio.hintmain(){printf( break 演示 \n);for(inti1;i10;i){if(i5){break;// 直接终止整个循环}printf(%d ,i);}printf(\nbreak演示结束\n);printf( continue 演示 \n);for(inti1;i10;i){if(i5){continue;// 跳过本次循环剩余代码直接进入下一轮}printf(%d ,i);}printf(\ncontinue演示结束\n);return0;}运行结果 break 演示 1 2 3 4break演示结束 continue 演示 1 2 3 4 6 7 8 9 10continue演示结束3.2 gotogoto语句实际包括goto和跳转标号 是一种比较特殊的语法其形式如下goto跳转标号;//和取变量名一样给跳转标号取名跳转标号:程序执行到goto语句时会直接跳转到 跳转标号: 的这个位置执行后续代码在想要跳出多层循环时如果用break,每层循环都要有break语句而用goto就会方便很多#includestdio.hintmain(){// 双层循环for(inti1;i3;i){for(intj1;j3;j){printf(i%d,j%d\n,i,j);if(i2j2){gotoend_loop;}}}end_loop:// 跳转标号名称自定义末尾带冒号printf(已经跳出双层循环\n);return0;}3.3 returnreturn 用于终止当前所在函数将程序执行流程返回函数调用处如果函数有返回值还可以附带返回数据。在main函数中执行return代表直接结束整个程序一旦执行return函数内return之后的所有代码都不会运行return 不受循环约束在循环体内执行 return会直接退出整个函数注意区分break只跳出循环不能退出函数return直接退出整个函数请看下面代码#includestdio.hvoidtest(){printf(函数开始运行\n);return;// 直接终止函数下方printf不会执行printf(这段代码永远无法执行\n);}intmain(){printf(main函数开始\n);test();printf(main函数继续执行\n);return0;// 结束main函数程序退出}运行结果main 函数开始函数开始运行main 函数继续执行a.return的使用规范1.返回类型为void的函数可不写return当然也可以写return但不能附带返回数值只能按return ;这样书写返回空语句2.带有返回值的函数正常应当使用return 数据;的形式返回匹配类型的值。因为普通有返回值函数如果代码执行结束仍没有执行return 值;程序会触发未定义行为然而有一个特例main函数允许省略末尾的 return编译器会自动补充 return 0;其他函数不享受该规则