流程控制

流程控制
苏丙榅1. 流程结构概述
程序流程结构是指编程中用于组织和控制代码执行顺序的结构。通过流程结构,可以按照特定的逻辑和条件来控制代码的执行路径,从而实现不同的功能和逻辑控制。以下是常见的程序流程结构:
顺序结构(Sequence Structure):按照代码编写顺序从上到下一行接一行地依次执行。1
2
3
4
5
6
7
8
9
10
11
int main()
{
bool flag = true;
flag = !flag;
printf("flag = %d\n", flag);
flag = !flag;
printf("flag = %d\n", flag);
return 0;
}通过上面的示例代码可以看到,顺序结构的逻辑非常简单,下文就不再进行赘述。
选择结构(Selection/Decision Structure):根据给定的条件选择性地执行不同的代码块。循环结构(Iteration/Loop Structure):循环执行一段代码,直到满足特定的条件为止。跳转结构(Jump Structure):用于在代码执行过程中跳转到特定的位置,改变代码执行的流程。
这些程序流程结构可以根据实际需求嵌套和组合使用,以实现复杂的逻辑控制和算法实现。编程语言提供了对应的语法和关键字来支持这些流程结构的使用。具体的语法和用法可能会因编程语言而异,因此在编写代码时应参考相应的语言文档和规范。
2. 选择结构
2.1 if 语句
if语句是一种常见的选择结构,用于根据给定的条件选择性地执行不同的代码块。if语句根据条件的真假来确定执行哪个代码块。
if 语句的一般语法结构如下:
1 | if (condition) |
其中,condition是一个布尔表达式,当条件为真时,执行大括号{}内的代码块。如果条件为假,则跳过整个代码块,继续执行后续的代码。
示例程序如下:
1 |
|
布尔表达式age1 > age2不成立,所以第 8 行的输出是不会执行的。
2.2 if…else 语句
if 语句也可以与 else 结合使用,来处理条件为假时的情况,即执行不同的代码块。下面是if-else语句的语法示例:
1 | if (condition) |
示例程序如下:
1 |
|
上面的代码要求我们通过键盘输入一个年龄,程序根据我们的输入就能判断这个年龄属于成年人还是未成年人:
1 | // 第一次执行 |
我们在程序中输入了不同的数据,程序对布尔表达式的结果继续了判断,最终执行了不同的代码分支。
2.3 if…else if…else 语句
在C语言中,如果想要进行两个及以上的条件判断,使用if-else结构是无法满足需求的,此时可使用if-else if-else,该结构的语法如下:
1 | if (condition1) |
在C语言中,if和else if后面的条件表达式用圆括号括起来,并以大括号包围代码块:每个条件之间使用else if进行连接,else if的数量可以是 N 个,最后的else如果不需要可以忽略。
在使用以上语法进行条件判断的时候务必注意一个问题:这些条件语句之间是互斥关系,如果其中一个条件判断为真,就不会再对其他条件进行判断了。
1 | // 版本1 |
在上面的示例程序中接收一个分数输入,然后根据制定的规则对分数进行等级划分,执行的结果如下:
1 | 请输入你考试成绩: |
如果对上面的条件判断稍微做一些手脚,那么得到的结果就完全不一样了:
1 | // 版本2 |
执行程序,输入相同的数据,得到的结果如下:
1 | 请输入你考试成绩: |
在上面两段程序中,使用同样的等级判断标准,同样的分数,但是得到的等级却不一样,原因就在于我们在程序中的判断方式发生了变化,第二段程序的判断逻辑是有问题的。
if...else if...else...if...else这是一个完整的结构,结构中的所有条件都是互斥的,一个条件为真之后,不会再对其他条件进行判断if、if...else、if...else if...else这是三个独立的判断结构,独立的判断结构之间是不互斥的- 在版本1中,判断结构只有一组,而在版本2中判断结构就变成多组了
- 版本2中会先执行第 15 行代码,再执行第 19 行,发生了数据覆盖
2.4 三目运算符
三目运算符(也称为条件运算符)是一种简洁的条件表达式。它可以在一行代码中根据条件的真假返回不同的值。
一般来说,三目运算符的语法如下:
1 | condition ? expression1 : expression2 |
其中,condition是一个布尔表达式,如果为真,则返回expression1的值;如果为假,则返回expression2的值。
以下是一个示例:
1 |
|
上面代码中通过两种方式对连个整数进行比较,并求出最大值,结果如下:
1 | max = 20 |
由此可见,使用三目运算符能够使程序更加精简,但可读性也会有所降低。
2.5 switch 语句
switch语句是一种多分支选择结构,用于根据不同的条件值选择性地执行不同的代码块。它提供了一种比使用多个if...else if...else语句更清晰和简洁的方法。
一般来说,switch语句的语法结构如下:
1 | switch (expression) |
在这个结构中,expression是一个表达式,它的值将与每个case语句后的value进行比较。如果expression的值与某个value相等,就执行对应的代码块,并在代码块结束后使用break语句跳出switch语句。如果没有匹配到任何的case,就会执行default后的代码块。
以下是一个示例:
1 |
|
对程序进行测试会得到以下输出:
1 | 请输入数字: |
根据day的值,选择不同的代码块进行执行。如果day的值为6,打印出的就是 “周末”。
需要注意的是,如果某个case的代码块执行完毕后没有使用break语句,将会继续执行后面的代码块(即”穿透”到下一个case)。这可以用来处理某些具有共同逻辑的情况,如上述示例中的周末情况。
另外,在C语言中,switch语句的条件有以下几个要求:
条件表达式必须是一个整型值,可以是整数、字符或枚举类型。在C语言中,浮点数、字符串或其他数据类型不能作为 switch 语句的条件。case后面的值必须是一个常量表达式,不能使用变量或其他表达式。- 每个 case 语句结束后必须使用
break语句来跳出整个 switch 语句块,否则将会”穿透”到后续的 case 执行。
3. 循环结构
3.1 for 语句
在C语言中,for语句是一种循环语句,用于重复执行一段代码块,直到指定的循环条件不再满足。for语句通常在已知循环次数的情况下使用。
一般来说,for语句的语法结构如下:
1 | for (initialization; condition; increment/decrement) |
initialization:在循环开始前执行的初始化代码,通常用于初始化循环变量;condition:循环条件,只有当条件满足时循环会继续执行;increment/decrement:在每次循环迭代完成后执行的增量/减量操作,用于更新循环变量的值;
以下是一个示例:
1 |
|
代码输出的信息如下:
1 | 循环变量的值为:1 |
在上述示例中,for语句将循环变量i初始化为1,然后检查条件i <= 5是否满足。如果条件为真,则执行代码块,并在每次循环迭代完成后将i的值增加1。当i的值为6时,不再满足条件,循环终止。
for语句的循环条件可以是任何能够产生布尔值(真或假)的表达式。例如,可以使用比较运算符(如 <、>、<=、>=、==、!=)来判断条件,也可以使用逻辑运算符(如&&、||)进行复合条件判断。
需要注意的是,for循环中的初始化、条件和增量/减量操作都是可选的。如果省略了初始化或增量/减量操作,可以在循环外部定义和更新循环变量。如果省略了条件,则被认为永远为真,从而变成一个无限循环(死循环)。
在循环体内部,可以使用break语句跳出循环,提前结束循环的执行,或使用continue语句跳过当前迭代,继续下一次循环迭代。
for语句在C语言中经常用于迭代数组、列表和其他数据结构中的元素,以及执行指定次数的重复操作。
3.2 while 语句
在C语言中,while语句是一种循环语句,用于重复执行一段代码块,直到指定的循环条件不再满足。while语句通常用于未知循环次数的情况下。
一般来说,while语句的语法结构如下:
1 | while (condition) |
condition是循环条件,只有当条件满足时,循环会继续执行对应的代码块。
以下是一个示例:
1 |
|
程序输出的结果如下:
1 | 循环变量的值为:1 |
在上述示例中,while语句首先检查条件i <= 5是否满足。如果条件为真,则执行代码块中的语句,并在每次循环迭代完成后将i的值增加1。当i的值为6时,不再满足条件,循环终止。
需要注意的是,循环体内的代码块应该包含导致循环条件最终为假的操作,否则会导致无限循环。在循环体内部,可以使用break语句跳出循环,提前结束循环的执行,或使用continue语句跳过当前迭代,继续下一次循环迭代。
while语句适用于任何循环次数未知的情况,例如在读取数据时,可以使用while语句循环读取,直到满足某个终止条件为止。
3.3 do…while 语句
在C语言中,do...while语句是一种循环语句,用于至少执行一次代码块,并在每次执行后检查循环条件,如果条件满足,则继续执行循环。与while语句不同,do...while语句先执行代码块,再判断条件。
一般来说,do...while语句的语法结构如下:
1 | do |
condition 是循环条件,当条件满足时,循环会继续执行对应的代码块。在每次执行代码块后,会检查condition的值。
以下是一个示例:
1 |
|
程序输出的信息如下:
1 | 循环变量的值为:1 |
在上述示例中,do语句先执行代码块中的语句,然后再进行条件判断,即使条件不满足,也会至少执行一次代码块。condition的值为真时,继续执行代码块,直到条件为假时,循环终止。
需要注意的是,与while和for循环不同,do...while循环中的代码块至少会执行一次,无论条件是否满足。如果在循环体内使用break语句提前结束循环,也会在第一次执行后跳出循环。
do...while语句适用于需要至少执行一次循环体的情况,然后根据条件决定是否继续执行循环。
3.4 嵌套循环
在C语言中,嵌套循环是指在一个循环内部再嵌套一个或多个循环。通过嵌套循环,可以实现对多维数据结构的遍历、组合问题的解决以及一些复杂的算法。嵌套循环的语法结构如下,此处使用 for 来给大家举例:
1 | for (初始化语句1; 条件表达式1; 增量/减量操作1) |
也可以使用while或do...while来实现嵌套循环,只需将相应的语法结构放置在另一个循环体中。
以下是一个示例,展示了一个简单的嵌套循环:
1 |
|
在上述示例中,外层循环执行3次,内层循环每次外层循环执行时都会执行3次。因此,总共会输出9对数字。程序输出的结果如下:
1 | i = 1, j = 1 |
在嵌套循环中,内层循环的每次迭代都会完全执行完毕,然后外层循环再进行下一次迭代。可以根据具体问题的需求,在嵌套循环中进行条件判断、嵌套层级的控制、循环变量的更新等操作。
需要注意的是,嵌套循环的层数过多,循环次数过大可能会导致性能问题,因此在编写嵌套循环时应考虑算法的效率和优化。
关于嵌套循环,不仅仅局限于for和for之间的嵌套,for、while、do…while之间都可以相互嵌套或者自我嵌套,大家举一反三,此处不再举例。
4. 跳转结构
在C语言中,跳转结构(Jump Statements)用于控制程序在特定条件下跳转到代码的其他位置。主要有以下几种跳转结构:
break语句:用于跳出当前循环或switch语句。continue语句:用于结束当前迭代,跳到下一次迭代。goto语句:用于无条件跳转到程序中的指定标记处。
4.1 break
当break语句被执行时,程序将跳出最内层的循环或switch语句的执行,并继续执行后续的代码。
1 |
|
- 第 13 行:跳出 while 循环,程序开始执行第 16 行
- 第 27 行:跳出第 21 行的内层 for 循环,程序开始执行第 30 行
- 第 32 行:跳出第 18 行的外层 for 循环,程序开始执行第 35 行
4.2 continue
当continue语句被执行时,程序将跳过当前迭代中剩余的代码,然后继续下一次迭代。
1 |
|
程序输出的结果为:
1 | sum = 25 |
很显然上面的程序是想求出10以内的奇数之和,即1+3+5+7+9=25,通过continue 完美跳过了所有的i为偶数的情况。
4.3 goto
goto语句是C语言中的一种跳转语句,它允许无条件地将程序控制转移到程序中的指定位置。goto语句的语法如下:
1 | goto label; |
其中,label是一个用户定义的标识符,它通常表示要跳转到的位置。标识符通常位于goto语句之后,并且位于冒号(:)之前。需要注意以下几点:
label必须是在当前函数内定义的标签。标签的命名规则与变量的命名规则相同,由字母、数字和下划线组成,但标签不能与C语言的关键字冲突。goto语句通常用于跳转到同一函数内的某个位置,但也可以跳转到同一文件中的其他函数内的标签(不推荐)。goto语句应慎用,因为过多或滥用goto语句可能会导致代码逻辑混乱、难以维护和阅读。通常情况下,可以使用循环或条件语句等结构化的控制流语句来代替goto语句。
以下是一个简单的示例,展示了goto语句的用法:
1 |
|
程序输出的结果如下:
1 | 当前的数字是 1 |
在上述示例中,使用goto语句创建了一个简单的循环,循环打印数字1到5,并在最后输出”结束”。
但请注意,以上程序仅作为示例。通常情况下,可以使用更结构化的控制流语句(例如for循环或while循环)来实现类似的功能,不要使用goto,不要使用goto,不要使用goto。




















