C语言 - 流程控制
1. 流程结构概述
#include <stdio.h>
#include <stdbool.h>
int main()
{
bool flag = true;
flag = !flag;
printf("flag = %d\n", flag);
flag = !flag;
printf("flag = %d\n", flag);
return 0;
}
2. 选择结构
2.1 if 语句
if语句是一种常见的选择结构,用于根据给定的条件选择性地执行不同的代码块。if语句根据条件的真假来确定执行哪个代码块。
if 语句的一般语法结构如下:
if (condition)
{
// 当条件满足时执行的代码块
}

#include <stdio.h>
int main()
{
int age1 = 11;
int age2 = 19;
if (age1 > age2)
{
printf("age1 的年龄比较大, age1 = %d\n", age1);
}
return 0;
}
2.2 if…else 语句
if (condition)
{
// 当条件满足时执行的代码块
}
else
{
// 当条件不满足时执行的代码块
}

示例程序如下:
#include <stdio.h>
int main()
{
int age1;
int age2 = 18;
printf("请输入你的年龄:\n");
scanf("%d", &age1);
if (age1 >= age2)
{
printf("brother, 你是一个成年人, age1 = %d\n", age1);
}
else
{
printf("baby, 你是一个未成年人, age1 = %d\n", age1);
}
return 0;
}
// 第一次执行
请输入你的年龄:
33
brother, 你是一个成年人, age1 = 33
// 第二处执行
请输入你的年龄:
10
baby, 你是一个未成年人, age1 = 10
我们在程序中输入了不同的数据,程序对布尔表达式的结果继续了判断,最终执行了不同的代码分支。
2.3 if…else if…else 语句
在C语言中,如果想要进行两个及以上的条件判断,使用if-else结构是无法满足需求的,此时可使用if-else if-else,该结构的语法如下:
if (condition1)
{
// 当条件1为真时执行的代码块
}
else if (condition2)
{
// 当条件2为真时执行的代码块
}
else if (condition3)
{
// 当条件3为真时执行的代码块
}
...
else
{
// 当所有条件都不满足时执行的代码块
}

在C语言中,if和else if后面的条件表达式用圆括号括起来,并以大括号包围代码块:每个条件之间使用else if进行连接,else if的数量可以是 N 个,最后的else如果不需要可以忽略。
在使用以上语法进行条件判断的时候务必注意一个问题:这些条件语句之间是互斥关系,如果其中一个条件判断为真,就不会再对其他条件进行判断了。
// 版本1
#include <stdio.h>
int main()
{
int score;
char grade;
printf("请输入你考试成绩:\n");
scanf("%d", &score);
if (score >= 90)
{
grade = 'A';
}
else if (score >= 80)
{
grade = 'B';
}
else if (score >= 70)
{
grade = 'C';
}
else
{
grade = 'D';
}
printf("你的成绩等级是:%c\n", grade);
return 0;
}
请输入你考试成绩:
88
你的成绩等级是:B
// 版本2
#include <stdio.h>
int main()
{
int score;
char grade;
printf("请输入你考试成绩:\n");
scanf("%d", &score);
if (score >= 90)
{
grade = 'A';
}
if (score >= 80)
{
grade = 'B';
}
if (score >= 70)
{
grade = 'C';
}
else
{
grade = 'D';
}
printf("你的成绩等级是:%c\n", grade);
return 0;
}
执行程序,输入相同的数据,得到的结果如下:
请输入你考试成绩:
88
你的成绩等级是:C
在上面两段程序中,使用同样的等级判断标准,同样的分数,但是得到的等级却不一样,原因就在于我们在程序中的判断方式发生了变化,第二段程序的判断逻辑是有问题的。
- if...else if...else...if...else 这是一个完整的结构,结构中的所有条件都是互斥的,一个条件为真之后,不会再对其他条件进行判断
- if、if...else、if...else if...else 这是三个独立的判断结构,独立的判断结构之间是不互斥的
- 在版本1中,判断结构只有一组,而在版本2中判断结构就变成多组了
- 版本2中会先执行第 15 行代码,再执行第 19 行,发生了数据覆盖
2.4 三目运算符
三目运算符(也称为条件运算符)是一种简洁的条件表达式。它可以在一行代码中根据条件的真假返回不同的值。
一般来说,三目运算符的语法如下:
condition ? expression1 : expression2
其中,condition是一个布尔表达式,如果为真,则返回expression1的值;如果为假,则返回expression2的值。
以下是一个示例:
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int max;
// 方式1
if (a > b)
{
max = a;
}
else
{
max = b;
}
printf("max = %d\n", max);
// 方式2
a = 789;
b = 345;
max = a > b ? a : b;
printf("max = %d\n", max);
return 0;
}
上面代码中通过两种方式对连个整数进行比较,并求出最大值,结果如下:
max = 20
max = 789
由此可见,使用三目运算符能够使程序更加精简,但可读性也会有所降低。
2.5 switch 语句
switch语句是一种多分支选择结构,用于根据不同的条件值选择性地执行不同的代码块。它提供了一种比使用多个if...else if...else语句更清晰和简洁的方法。
一般来说,switch语句的语法结构如下:
switch (expression)
{
case value1:
// 当expression的值等于value1时执行的代码块
break;
case value2:
// 当expression的值等于value2时执行的代码块
break;
case value3:
// 当expression的值等于value3时执行的代码块
break;
...
default:
// 当expression的值与所有case都不匹配时执行的代码块
break;
}
在这个结构中,expression是一个表达式,它的值将与每个case语句后的value进行比较。如果expression的值与某个value相等,就执行对应的代码块,并在代码块结束后使用break语句跳出switch语句。如果没有匹配到任何的case,就会执行default后的代码块。
以下是一个示例:
#include <stdio.h>
int main()
{
int day;
printf("请输入数字: \n");
scanf("%d", &day);
switch (day)
{
case 1:
printf("星期一\n");
break;
case 2:
printf("星期二\n");
break;
case 3:
printf("星期三\n");
break;
case 4:
printf("星期四\n");
break;
case 5:
printf("星期五\n");
break;
case 6:
case 7:
printf("周末\n");
break;
default:
printf("无效的日期\n");
break;
}
return 0;
}
对程序进行测试会得到以下输出:
请输入数字:
6
周末
根据day的值,选择不同的代码块进行执行。如果day的值为6,打印出的就是 “周末”。
需要注意的是,如果某个case的代码块执行完毕后没有使用break语句,将会继续执行后面的代码块(即”穿透”到下一个case)。这可以用来处理某些具有共同逻辑的情况,如上述示例中的周末情况。
另外,在C语言中,switch语句的条件有以下几个要求:
- 条件表达式必须是一个整型值,可以是整数、字符或枚举类型。在C语言中,浮点数、字符串或其他数据类型不能作为 switch 语句的条件。
- case后面的值必须是一个常量表达式,不能使用变量或其他表达式。
- 每个 case 语句结束后必须使用break语句来跳出整个 switch 语句块,否则将会”穿透”到后续的 case 执行。
3. 循环结构
3.1 for 语句
在C语言中,for语句是一种循环语句,用于重复执行一段代码块,直到指定的循环条件不再满足。for语句通常在已知循环次数的情况下使用。
一般来说,for语句的语法结构如下:
for (initialization; condition; increment/decrement)
{
// 循环执行的代码块
}
- initialization:在循环开始前执行的初始化代码,通常用于初始化循环变量;
- condition:循环条件,只有当条件满足时循环会继续执行;
- increment/decrement:在每次循环迭代完成后执行的增量/减量操作,用于更新循环变量的值;。
for 语法:
for (表达式1; 表达式2; 表达式3) {
循环体语句;
}
执行for语句时,程序首先计算第一个表达式的值,接着计算第二个表达式的值。如果第二个表达式的值为真(true), 程序就执行循环体的内容,并计算表达式3;然后检验表达式2,执行循环,如此反复,直到表达式2的值为假(false),退出循环。

#include <stdio.h>
int main()
{
for (int i = 1; i <= 5; i++)
{
printf("循环变量的值为:%d\n", i);
}
return 0;
}
循环变量的值为:1
循环变量的值为:2
循环变量的值为:3
循环变量的值为:4
循环变量的值为:5
在上述示例中,for语句将循环变量i初始化为1,然后检查条件i <= 5是否满足。如果条件为真,则执行代码块,并在每次循环迭代完成后将i的值增加1。当i的值为6时,不再满足条件,循环终止。
for语句的循环条件可以是任何能够产生布尔值(真或假)的表达式。例如,可以使用比较运算符(如 <、>、<=、>=、==、!=)来判断条件,也可以使用逻辑运算符(如&&、||)进行复合条件判断。
需要注意的是,for循环中的初始化、条件和增量/减量操作都是可选的。如果省略了初始化或增量/减量操作,可以在循环外部定义和更新循环变量。如果省略了条件,则被认为永远为真,从而变成一个无限循环(死循环)。
在循环体内部,可以使用break语句跳出循环,提前结束循环的执行,或使用continue语句跳过当前迭代,继续下一次循环迭代。
for语句在C语言中经常用于迭代数组、列表和其他数据结构中的元素,以及执行指定次数的重复操作。
3.2 while 语句
在C语言中,while语句是一种循环语句,用于重复执行一段代码块,直到指定的循环条件不再满足。while语句通常用于未知循环次数的情况下。
一般来说,while语句的语法结构如下:
while (condition)
{
// 循环执行的代码块
}

#include <stdio.h>
int main()
{
int i = 1;
while (i <= 5)
{
printf("循环变量的值为:%d\n", i);
i++;
}
return 0;
}
循环变量的值为:1
循环变量的值为:2
循环变量的值为:3
循环变量的值为:4
循环变量的值为:5
在上述示例中,while语句首先检查条件i <= 5是否满足。如果条件为真,则执行代码块中的语句,并在每次循环迭代完成后将i的值增加1。当i的值为6时,不再满足条件,循环终止。
需要注意的是,循环体内的代码块应该包含导致循环条件最终为假的操作,否则会导致无限循环。在循环体内部,可以使用break语句跳出循环,提前结束循环的执行,或使用continue语句跳过当前迭代,继续下一次循环迭代。
while语句适用于任何循环次数未知的情况,例如在读取数据时,可以使用while语句循环读取,直到满足某个终止条件为止。
3.3 do…while 语句
在C语言中,do...while语句是一种循环语句,用于至少执行一次代码块,并在每次执行后检查循环条件,如果条件满足,则继续执行循环。与while语句不同,do...while语句先执行代码块,再判断条件。
一般来说,do...while语句的语法结构如下:
do
{
// 循环执行的代码块
} while (condition);

#include <stdio.h>
int main()
{
int i = 1;
do
{
printf("循环变量的值为:%d\n", i);
i++;
} while (i <= 5);
return 0;
}
循环变量的值为:1
循环变量的值为:2
循环变量的值为:3
循环变量的值为:4
循环变量的值为:5
在上述示例中,do语句先执行代码块中的语句,然后再进行条件判断,即使条件不满足,也会至少执行一次代码块。condition的值为真时,继续执行代码块,直到条件为假时,循环终止。
需要注意的是,与while和for循环不同,do...while循环中的代码块至少会执行一次,无论条件是否满足。如果在循环体内使用break语句提前结束循环,也会在第一次执行后跳出循环。
do...while语句适用于需要至少执行一次循环体的情况,然后根据条件决定是否继续执行循环。
3.4 嵌套循环
在C语言中,嵌套循环是指在一个循环内部再嵌套一个或多个循环。通过嵌套循环,可以实现对多维数据结构的遍历、组合问题的解决以及一些复杂的算法。嵌套循环的语法结构如下,此处使用 for 来给大家举例:
for (初始化语句1; 条件表达式1; 增量/减量操作1)
{
for (初始化语句2; 条件表达式2; 增量/减量操作2)
{
// 嵌套循环体代码
}
// 外层循环体代码
}
也可以使用while或do...while来实现嵌套循环,只需将相应的语法结构放置在另一个循环体中。
以下是一个示例,展示了一个简单的嵌套循环:
#include <stdio.h>
int main()
{
// 外层循环
for (int i = 1; i <= 3; i++)
{
// 内层循环
for (int j = 1; j <= 3; j++)
{
printf("i = %d, j = %d\n", i, j);
}
}
return 0;
}
i = 1, j = 1
i = 1, j = 2
i = 1, j = 3
i = 2, j = 1
i = 2, j = 2
i = 2, j = 3
i = 3, j = 1
i = 3, j = 2
i = 3, j = 3
在嵌套循环中,内层循环的每次迭代都会完全执行完毕,然后外层循环再进行下一次迭代。可以根据具体问题的需求,在嵌套循环中进行条件判断、嵌套层级的控制、循环变量的更新等操作。
需要注意的是,嵌套循环的层数过多,循环次数过大可能会导致性能问题,因此在编写嵌套循环时应考虑算法的效率和优化。
关于嵌套循环,不仅仅局限于for和for之间的嵌套,for、while、do…while之间都可以相互嵌套或者自我嵌套,大家举一反三,此处不再举例。
4. 跳转结构
在C语言中,跳转结构(Jump Statements)用于控制程序在特定条件下跳转到代码的其他位置。主要有以下几种跳转结构:
break语句:用于跳出当前循环或switch语句。
continue语句:用于结束当前迭代,跳到下一次迭代。
goto语句:用于无条件跳转到程序中的指定标记处。
4.1 break
当break语句被执行时,程序将跳出最内层的循环或switch语句的执行,并继续执行后续的代码。
#include <stdio.h>
#include <stdbool.h>
int main()
{
int i = 0;
while (1)
{
i++;
printf("i = %d\n", i);
if (i == 3)
{
break;
}
}
printf("======================\n");
bool flag = false;
for (int m = 0; m < 10; m++)
{
printf("外层 m = %d\n", m);
for (int n = 0; n < 10; n++)
{
printf("内层 n = %d\n", n);
if (n == 5)
{
flag = true;
break;
}
}
if (flag == true)
{
break;
}
}
return 0;
}
第 13 行:跳出 while 循环,程序开始执行第 16 行
第 27 行:跳出第 21 行的内层 for 循环,程序开始执行第 30 行
第 32 行:跳出第 18 行的外层 for 循环,程序开始执行第 35 行
4.2 continue
#include<stdio.h>
int main()
{
int sum = 0;
for (int i = 1; i <= 10; i++)
{
if (i % 2 == 0)
{
continue;
}
sum += i;
}
printf("sum = %d\n", sum);
return 0;
}
程序输出的结果为:
sum = 25
很显然上面的程序是想求出10以内的奇数之和,即1+3+5+7+9=25,通过continue 完美跳过了所有的i为偶数的情况。
4.3 goto
goto语句是C语言中的一种跳转语句,它允许无条件地将程序控制转移到程序中的指定位置。goto语句的语法如下:
goto label;
其中,label是一个用户定义的标识符,它通常表示要跳转到的位置。标识符通常位于goto语句之后,并且位于冒号(:)之前。需要注意以下几点:
- label必须是在当前函数内定义的标签。标签的命名规则与变量的命名规则相同,由字母、数字和下划线组成,但标签不能与C语言的关键字冲突。
- goto语句通常用于跳转到同一函数内的某个位置,但也可以跳转到同一文件中的其他函数内的标签(不推荐)。
- goto语句应慎用,因为过多或滥用goto语句可能会导致代码逻辑混乱、难以维护和阅读。通常情况下,可以使用循环或条件语句等结构化的控制流语句来代替goto语句。
以下是一个简单的示例,展示了goto语句的用法:
#include <stdio.h>
int main() {
int num = 1;
start:
printf("当前的数字是 %d\n", num);
num++;
if (num <= 5) {
goto start;
}
printf("结束");
return 0;
}
当前的数字是 1
当前的数字是 2
当前的数字是 3
当前的数字是 4
当前的数字是 5
结束
在上述示例中,使用goto语句创建了一个简单的循环,循环打印数字1到5,并在最后输出”结束”。
注意:以上程序仅作为示例。通常情况下,可以使用更结构化的控制流语句(例如for循环或while循环)来实现类似的功能,不要使用goto,不要使用goto,不要使用goto。
-----------------------------------------------------------------------------
作者: 苏丙榅
链接: https://subingwen.cn/c/LlowControl/
来源: 爱编程的大丙
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?