Loading... # 语句与控制流 **C语言语句分为以下五类**: 1. 表达式语句 2. 函数调用语句 3. 控制语句 4. 复合语句 5. 空语句 其中控制语句用于控制程序的执行流程,以实现程序的各种结构方式,它们由特定的语句定义符组成,C语言有**九种控制语句**。 **分为三类**: 1. 条件判断语句也叫分支语句:if语句、switch语句; 2. 循环执行语句:do while语句、while语句、for语句; 3. 转向语句:break语句、goto语句、continue语句、return语句 ## 语句与程序块 **表达式**(Expression)和**语句**(Statement)的概念在C语言中并没有明确的定义: - 表达式可以看做一个计算的公式,往往由数据、变量、运算符等组成,例如`3*4+5`、`a=c=d`等,表达式的结果必定是一个值; - 语句的范围更加广泛,不一定是计算,不一定有值,可以是某个操作、某个函数、选择结构、循环等。 1.**空语句** C语言最简单的就是空语句,本身只包含一个分号,空语句本身不执行任何任务,纯粹消耗cpu时间,起到延时的作用。 2.**表达式语句** C并不存在专门的“赋值语句“,那么它的赋值就是一种操作,和加法减法一样,在表达式内部进行 ```c x = y + 3; ch = getchar(); ``` 这实际上是表达式语句,不是赋值语句! 3.**程序块** 代码块就是位于一对花括号之内的可选的声明和语句列表 ```c { declatations; statements; } ``` 代码块可以用于要求出现语句的地方,它允许你在语法要求只出现一条语句的地方使用多条语句。代码块还允许你把数据的声明非常靠近它所使用的地方 **重点**: - 表达式必须有一个执行结果,这个结果必须是一个值,例如`3*4+5`的结果 17,`a=c=d=10`的结果是 10,`printf("hello")`的结果是 5(`printf` 的返回值是成功打印的字符的个数)。 - 以分号`;`结束的往往称为语句,而不是表达式,例如`3*4+5;`、`a=c=d;`等。 # 分支语句(选择结构) ## if else语句 if 语句的形式为: ```c if(判断条件){ 语句块 } ``` **多个if else语句** 形式如下: ```c f(判断条件1){ 语句块1 } else if(判断条件2){ 语句块2 }else if(判断条件3){ 语句块3 }else if(判断条件m){ 语句块m }else{ 语句块n } ``` 一旦遇到能够成立的判断条件,则不再执行其他的语句块,所以最终只能有一个语句块被执行 **if语句的嵌套** if 语句也可以嵌套使用,例如: ```c #include <stdio.h> int main() { int a, b; printf("Input two numbers:"); scanf("%d %d", &a, &b); if (a != b) { //!=表示不等于 if (a > b) printf("a>b\n"); else printf("a<b\n"); } else { printf("a=b\n"); } return 0; } ``` > 运行结果: ``` c Input two numbers:12 68 a<b ``` if 语句嵌套时,**C语言规定,else 总是与它前面最近的 if 配对** > 例如: ```c if(a!=b) // ① if(a>b) printf("a>b\n"); // ② else printf("a<b\n"); // ③ ``` ③和②配对,而不是和①配对。 ## switch语句 switch 是另外一种选择结构的语句,用来代替简单的、拥有多个分枝的 if else 语句,基本格式如下: ```c switch(表达式){ case 整型数值1: 语句 1; case 整型数值2: 语句 2; ...... case 整型数值n: 语句 n; default: 语句 n+1; } ``` **执行过程是**: 1. 首先计算“表达式”的值,假设为 m。 2. 从第一个 case 开始,比较“整型数值1”和 m,如果它们相等,就执行冒号后面的所有语句,也就是从“语句1”一直执行到“语句n+1”,而不管后面的 case 是否匹配成功。 3. 如果“整型数值1”和 m 不相等,就跳过冒号后面的“语句1”,继续比较第二个 case、第三个 case……一旦发现和某个整型数值相等了,就会执行后面所有的语句。假设 m 和“整型数值5”相等,那么就会从“语句5”一直执行到“语句n+1”。 4. 如果直到最后一个“整型数值n”都没有找到相等的值,那么就执行 default 后的“语句 n+1”。 **switch** 语句必须遵循下面的规则: - **switch** 语句中的 **expression** 必须是一个整型或枚举类型,或者是一个 class 类型,其中 class 有一个单一的转换函数将其转换为整型或枚举类型。 - 在一个 switch 中可以有任意数量的 case 语句。每个 case 后跟一个要比较的值和一个冒号。 - case 的 **constant-expression** 必须与 switch 中的变量具有相同的数据类型,且必须是一个常量或字面量。 - 当被测试的变量等于 case 中的常量时,case 后跟的语句将被执行,直到遇到 **break** 语句为止。 - 当遇到 **break** 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。 - 不是每一个 case 都需要包含 **break**。如果 case 语句不包含 **break**,控制流将会 *继续* 后续的 case,直到遇到 break 为止。 - 一个 **switch** 语句可以有一个可选的 **default** case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 **break** 语句不是必需的。 > 例子: ```c case 10: printf("..."); break; //正确 case 8+9: printf("..."); break; //正确 case 'A': printf("..."); break; //正确,字符和整数可以相互转换 case 'A'+19: printf("..."); break; //正确,字符和整数可以相互转换 case 9.5: printf("..."); break; //✘,不能为小数 case a: printf("..."); break; //✘,不能包含变量 case a+10: printf("..."); break; //✘,不能包含变量 ``` 总结: 1. case 后面必须是一个整数,或者是结果为整数的表达式,但不能包含任何变量。 2. default 不是必须的。当没有 default 时,如果所有 case 都匹配失败,那么就什么都不执行。 # 循环语句 ## while语句 > 形式为: ```c while(表达式){ 语句块 } ``` ## do-while循环 > 形式为: ```c do{ 语句块 }while(表达式); ``` do-while循环与while循环的不同在于:它会先执行“语句块”,然后再判断表达式是否为真,如果为真则继续循环;如果为假,则终止循环。因此,do-while 循环**至少要执行一次**“语句块”。 ## for 循环 > 形式为: ```c for(表达式1; 表达式2; 表达式3){ 语句块 } ``` 1. **表达式1** 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。 2. 接下来,会判断 **表达式2**。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。 3. 在执行完 for 循环主体后,控制流会跳回上面的**表达式3**语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。 4. 条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,for 循环终止。 **双重循环嵌套执行原理** 重循环的嵌套说白了 就是for套for。 for循环来说,执行原理就是:外层循环表示行数;内层循环表示列数;外层变量换到内层,达到递增递减效果。 # 转向语句(跳转语句) ## goto语句 **goto** 语句是一种无条件流程跳转语句,通常 goto 语句与 if 语句结合使用,当满足一定条件时,程序流程跳转到指定标号处,接着往下执行。 使用 **goto** 语句可能会造成程序层次不清晰,可读性差,故在实际编程中,应尽量少使用或避免使用 `goto` 语句。**一般不使用** ## break语句 当执行到循环体中的 break 语句时,将终止 break 所在该层的循环,从该层循环体之后的语句开始继续执行。 break 的执行流程如下所示。 单重循环情况:选用 while 循环结构示意,do-while 循环、for 循环同样适用。 ```c while (循环判断表达式) { ... if(条件表达式) break; 循环体中break后的语句; } 循环体后的第 1 条语句; 循环体后的第 2 条语句; ... ``` 在循环体中,当满足一定条件执行到 break 语句时,终止 break 所在的该层循环,即“循环体中 break 后的语句”部分将不再被执行,程序执行流程转向从“循环结构后的第 1 条语句”处,开始继续往后执行。 双重循环情况:使用双重 for 循环嵌套结构示意,其他类型的循环嵌套组合同样适用。 ```c for (;循环判断表达式1;) { ... for(;循环判断表达式2;) { ... if(条件表达式) break; 内层循环体中break后的语句; } 内层循环结构后的第1条语句; 内层循环结构后的第2条语句; ... } ``` 在内层循环中,当满足一定条件执行到 break 语句时,仅结束 break 所在内层循环的执行(在本轮外层循环中,“内层循环体中 break 后的语句”部分不再被执行),程序执行流程跳转到“内层循环结构后的第 1 条语句”所在的外层循环体处,开始继续执行。 ## continue语句 在循环体中设置 continue 语句,同样可以改变循环的执行流程,只不过它不像 break 那样结束整个循环体,而是仅结束本次循环体的执行,提前进入下一次循环。 ```c for(初始表达式;循环判断表达式;增量表达式) { ... if(条件表达式) continue; 循环体中continue后的所有语句; } ``` 当在上述 for 循环中执行到 continue 语句时,本次循环体的执行流程将跳过“循环体中 continue 后的所有语句”,接着执行“增量表达式”部分,然后执行“循环判断表达式”,即提前进入下一次循环的准备工作。 最后修改:2022 年 01 月 30 日 © 允许规范转载 打赏 赞赏作者 赞 如果觉得我的文章对你有用,请随意赞赏