在C语言的世界里,也并不是一帆风顺的走直线,其代码运行往往需要判断或是循环,才能达到程序想要的结果。分支语句和循环语句就是实现这些功能必不可少的工具。今天,我将结合我的学习过程,谈谈自己的理解。
一、分支语句让程序“做选择”。
分支语句的作用是 “根据条件判断,执行不同代码块”,在我们生活中,我们会根据不同的情况,做出不同的选择和规划,分支语句在C语言中也是如此。C 语言中常用的分支语句有两种:if语句和switch语句。
1.1 if 语句:最灵活的条件判断
if语句是 C 语言中最基础的分支语句,它能处理从简单到复杂的各种条件判断。其基本语法分为三种形式,我举例讨论其形式与用法。
(1)单分支:满足条件才执行
当我们只需要 “满足条件就做某事,不满足就跳过” 时,使用单分支if语句。
语法格式:
if (条件表达式)
{
// 条件为真(非0)时执行的代码块
}
// 条件为假(0)时,直接执行此处代码
注意:if后的括号()不可省略,括号内的 “条件表达式” 结果为 “真(非 0)” 或 “假(0)”。如果代码块只有 1 行,大括号{}可以省略,但为了代码可读性,建议始终加上。
实例:判断一个数是否为正数:
#include <stdio.h>
int main()
{
int num = 10;
if (num > 0) // 条件:num大于0
{
printf("%d是正数\n", num); // 条件为真,执行此句
}
printf("判断结束\n"); // 无论条件真假,都会执行此句
return 0;
}
// 运行结果:10是正数 → 判断结束
(2)双分支:二选一的判断
当需要 “满足条件做 A,不满足做 B” 时,使用if-else双分支语句。
语法格式:
if (条件表达式) {
// 条件为真时执行的代码块A
} else {
// 条件为假时执行的代码块B
实例:判断是否为闰年:
#include<stdio.h>
int main()
{
int i = 0;
scanf("%d", &i);
if ((i % 4 == 0 && i % 100 != 0) || (i % 400 == 0))
printf("Yes");#(条件满足,执行此语句)
else
printf("No");#(不满足条件,就执行此语句)
return 0;
#闰年的判断方式:闰年的判断方式:1. 能被 4 整除,但不能被 100 整除;2. 能被 400 整除。
1.&&(逻辑与):相当于生活中的 “并且”,要求两个条件同时为真,整体结果才为真;只要有一个条件为假,整体结果就为假。
2.||(逻辑或):相当于生活中的 “或者”,要求两个条件至少有一个为真,整体结果就为真;只有两个条件都为假时,整体结果才为假。
(3)多分支:多种情况的判断
当需要处理 “多个条件,对应不同执行逻辑” 时,使用if-else if-else多分支语句。
语法格式:
if (条件1) {
// 条件1为真时执行
} else if (条件2) {
// 条件1为假、条件2为真时执行
} else if (条件3) {
// 前两个条件为假、条件3为真时执行
} else {
// 所有条件都为假时执行(可选)
}
关键规则:程序会从 “条件 1” 开始依次判断,只要遇到第一个为真的条件,就执行对应的代码块,后续条件不再判断。
实例:根据分数划分等级(90 + 为 A,80-89 为 B,70-79 为 C,否则为 D):
#include <stdio.h>
int main()
{
int score = 85;
if (score >= 90) {
printf("等级:A\n");
} else if (score >= 80) { // 隐含条件:score < 90
printf("等级:B\n"); // 85满足此条件,执行此句
} else if (score >= 70) { // 隐含条件:score < 80
printf("等级:C\n");
} else {
printf("等级:D\n");
}
return 0;
} // 运行结果:等级:B
(4)if 语句的 “坑”:悬空 else 问题
在嵌套if语句时,容易出现 “悬空 else” 问题 ——else会默认与最近的未匹配 if结合,而非我们主观认为的外层 if。
反例(错误示范):
#include <stdio.h>
int main() {
int a = 1, b = 2;
if (a == 0) // 外层if,条件为假
if (b == 2) // 内层if,条件为真
printf("b=2\n");
else // 悬空else:实际与内层if结合,而非外层if
printf("a≠0\n");
return 0;
}
// 预期:a≠0 → 实际运行结果:无输出(因为内层if条件为真,执行printf后,else不执行)
解决方法:既然默认最近的if与else匹配,若想打破这种局面,只能“强扭这个瓜了”,把不想与else匹配的if给括起来,即始终使用大括号{}明确代码块范围,避免歧义:
#include <stdio.h>
int main() {
int a = 1, b = 2;
if (a == 0)
{ // 外层if用大括号明确范围
if (b == 2)
{
printf("b=2\n");
}
} else { // 此时else明确与外层if结合
printf("a≠0\n"); // 执行此句
}
return 0;
}
// 运行结果:a≠0
1.2 switch 语句:多值匹配的 “快捷方式”
当需要根据一个变量的 “多个固定值” 进行判断时(比如根据月份判断季节、根据菜单选项执行操作),switch语句比if-else if更简洁、易读。
(1)基本语法
switch (表达式) { // 表达式结果必须是整数类型(int、char等)
case 常量1:
// 表达式值 == 常量1时执行的代码
break; // 跳出switch语句(关键!)
case 常量2:
// 表达式值 == 常量2时执行的代码
break;
// ... 更多case
default:
// 表达式值与所有case常量不匹配时执行的代码(可选)
break;
}
核心规则:
- switch后的 “表达式” 必须是整数类型(不能是 float、double 等);
- case后的 “常量” 必须是字面量(如 1、'A')或宏定义,不能是变量;
- break语句的作用是 “执行完当前 case 后,跳出 switch”,如果省略,会发生 “case 穿透”(继续执行下一个 case 的代码);
- default可放在任意位置(通常放最后),当所有 case 都不匹配时执行,没有匹配项且无 default 时,switch 不执行任何代码。
(2)实例:根据月份判断季节
#include <stdio.h>
int main() {
int month = 3;
switch (month) {
case 3:
case 4:
case 5: // 3、4、5月均为春季(利用case穿透)
printf("春季\n");
break; // 跳出switch
case 6:
case 7:
case 8:
printf("夏季\n");
break;
case 9:
case 10:
case 11:
printf("秋季\n");
break;
case 12:
case 1:
case 2:
printf("冬季\n");
break;
default:
printf("无效月份\n");
break;
}
return 0;
} // 运行结果:春季
(3)switch vs if-else if:该怎么选?
- 用switch:当判断条件是 “变量等于多个固定整数” 时(如菜单选项、月份、等级),代码更简洁;
- 用if-else if:当判断条件是 “范围”(如 score >= 90)或 “复杂逻辑”(如 a > b && c != 0)时,更灵活。
二、循环语句:让程序学会 “重复做”
循环语句的核心作用是 “让一段代码重复执行,直到满足终止条件”,比如计算 1 到 100 的和、打印 10 次 “Hello World”。C 语言中常用的循环语句有三种:while、for、do-while。
2.1 while 循环:先判断,再执行
while循环是最基础的循环结构,逻辑是 “先判断条件,条件为真则执行循环体,否则终止循环”。
(1)基本语法
while (条件表达式) {
// 循环体:条件为真时重复执行的代码
// (通常需要有“更新条件”的语句,避免死循环)
}
关键注意:循环体中必须有 “更新条件” 的语句(如i++、num -= 2),否则条件永远为真,会导致 “死循环”(程序一直执行循环体,无法退出)。
(2)实例 1:打印 1 到 5 的数字
#include <stdio.h>
int main()
{
int i = 1; // 初始化循环变量
while (i <= 5) // 条件:i不大于5
{
printf("%d ", i); // 循环体:打印i
i++; // 更新条件:i自增1(避免死循环)
}
return 0;
}
// 运行结果:1 2 3 4 5
(3)实例 2:计算 1 到 100 的和
#include <stdio.h>
int main()
{
int sum = 0; // 存储总和,初始化为0
int i = 1; // 循环变量,从1开始
while (i <= 100)
{
sum += i; // 等价于sum = sum + i
i++; // i自增,向100靠近
}
printf("1到100的和:%d\n", sum);
return 0;
}
// 运行结果:1到100的和:5050
(4)实例 3:打印100 到 200 的素数
#include <stdio.h>
int main()
{
int i = 100; // 初始化循环变量(从100开始)
int b = 2;
int c = 0;
int d = 0;
// 外层while循环:控制100~200的数字
while (i <= 200)
{
c = 0;
d = i - 1;
b = 2; // 内层循环变量重置
// 内层while循环:判断当前i是否为素数
while (b < d)
{
if (i % b == 0)
{
c = 1;
break;
}
b++; // 内层循环变量更新
}
if (c == 0)
printf("%d ", i);
i++; // 外层循环变量更新
}
return 0;
}
运行结果:101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199。
2.2 for 循环:更优雅的 “计数循环”
for循环是 C 语言中最常用的循环结构,尤其适合 “已知循环次数” 的场景(如从 1 循环到 100)。它将 “初始化循环变量”“判断条件”“更新条件” 三个步骤整合在一行,结构更紧凑。
(1)基本语法
for (初始化表达式; 条件表达式; 更新表达式) {
// 循环体:条件为真时执行的代码
}
执行流程:
- 执行 “初始化表达式”(仅执行 1 次,用于初始化循环变量);
- 判断 “条件表达式”:
- 若为真:执行循环体 → 执行 “更新表达式” → 回到步骤 2;
- 若为假:终止循环,执行 for 循环后的代码。
(2)实例 1:用 for 循环打印 1 到 5
#include <stdio.h>
int main() {
// 初始化i=1;条件i<=5;更新i++
for (int i = 1; i <= 5; i++) {
printf("%d ", i);
}
return 0;
}
// 运行结果:1 2 3 4 5
(3)实例 2:用 for 循环计算 1 到 100 的偶数和
#include <stdio.h>
int main() {
int sum_even = 0;
// 初始化i=2(第一个偶数);条件i<=100;更新i+=2(每次加2,保持偶数)
for (int i = 2; i <= 100; i += 2) {
sum_even += i;
}
printf("1到100的偶数和:%d\n", sum_even);
return 0;
}
// 运行结果:1到100的偶数和:2550
2.3 do-while 循环:先执行,再判断
do-while循环的逻辑是 “先执行一次循环体,再判断条件”—— 这意味着循环体至少会执行一次,适合 “需要先做一次,再判断是否继续” 的场景(如密码验证、菜单交互)。
(1)基本语法
do {
// 循环体:至少执行一次
// (同样需要更新条件,避免死循环)
} while (条件表达式); // 注意:末尾有分号
(2)实例:密码验证(至少输入一次密码,直到输入正确)
#include <stdio.h>
#include <string.h> // 用于strcmp函数(比较字符串)
int main() {
char password[20]; // 存储用户输入的密码
do {
printf("请输入密码:");
scanf("%s", password); // 输入密码(假设正确密码是"123456")
// strcmp:比较两个字符串,相等返回0,不相等返回非0
}
while (strcmp(password, "123456") != 0); // 密码不正确则继续循环
printf("密码正确,欢迎进入!\n");
return 0;
}
// 运行示例:
// 请输入密码:abc123 → 请输入密码:123456 → 密码正确,欢迎进入!
当然也能用for循环打印100—200的素数
#include <stdio.h>
int main()
{
int i = 0;
int b = 2;
int c = 0;#作为判断是否为素数的标记
int d = 0;
for (i = 100; i <= 200; i++)
{
c = 0;
d = i - 1;
for(b = 2;b < d;b++)
{
if (i % b == 0)
{
c = 1;
break;
}
}
if (c == 0)
printf("%d ", i);
}
return 0;
}
运行结果:

2.4 循环控制:break 和 continue
一、在循环中,我们有时需要 “提前终止循环” 或 “跳过当前轮次,直接进入下一轮”,这就需要break和continue语句。
(1)break:彻底终止循环
break的作用是 “立即跳出当前所在的循环(while/for/do-while)或 switch 语句”,后续循环不再执行。
实例:找到 1 到 10 中第一个能被 3 整除的数,找到后终止循环:
#include <stdio.h>
int main()
{
for (int i = 1; i <= 10; i++)
{
if (i % 3 == 0) // 若i能被3整除
{
printf("找到第一个能被3整除的数:%d\n", i);
break; // 终止for循环,后续i=4~10不再执行
}
}
return 0;
}
// 运行结果:找到第一个能被3整除的数:3
(2)continue:跳过当前轮次,进入下一轮
continue的作用是 “跳过当前轮次的循环体剩余代码,直接进入下一轮循环的条件判断”(不会终止循环)。
实例:打印 1 到 10 中的奇数(跳过偶数):
#include <stdio.h>
int main() {
// 打印1到10中的奇数(用continue跳过偶数)
for (int i = 1; i <= 10; i++) {
// 如果是偶数,跳过本轮后续代码,直接进入下一轮
if (i % 2 == 0) {
continue; // 关键:跳过本轮的printf,直接执行i++进入下一轮
}
// 只有奇数才会执行下面的打印
printf("奇数:%d\n", i);
}
return 0;
}
运行结果:
奇数:1
奇数:3
奇数:5
奇数:7
奇数:9
代码解析:
- 循环变量
i从 1 递增到 10 - 当
i是偶数(i%2 == 0)时,执行continue: (1)立即跳过当前轮次中continue后面的printf语句 (2)直接进入下一轮循环(执行i++后重新判断条件) - 当
i是奇数时,不执行continue,正常执行printf打印。
2.4.1 for循环中的 break 和 continue。
1. for 循环中的 break(终止整个循环)
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
break; // 当i=3时,终止整个for循环
}
printf("i = %d\n", i);
}
printf("循环结束\n");
return 0;
}
运行结果:
i = 1
i = 2
循环结束
解析:当i=3时,break触发,直接终止整个for循环,后续的i=4、5不再执行。
2. for 循环中的 continue(跳过当前轮次,进入下一轮)
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue; // 当i=3时,跳过本轮剩余代码
}
printf("i = %d\n", i);
}
printf("循环结束\n");
return 0;
}
运行结果:
i = 1
i = 2
i = 4
i = 5
循环结束
解析:当i=3时,continue触发,跳过当前轮次的printf,直接执行i++进入下一轮(i=4)。
2.4.2while 循环中的 break 和 continue
1. while 循环中的 break(终止整个循环)
#include <stdio.h>
int main() {
int i = 1;
while (i <= 5) {
if (i == 3) {
break; // 当i=3时,终止整个while循环
}
printf("i = %d\n", i);
i++;
}
printf("循环结束\n");
return 0;
}
运行结果:
i = 1
i = 2
循环结束
解析:当i=3时,break触发,直接终止while循环,i不再递增。
2. while 循环中的 continue(跳过当前轮次,进入下一轮)
#include <stdio.h>
int main() {
int i = 1;
while (i <= 5) {
if (i == 3) {
i++; // 注意:while中使用continue前需手动更新循环变量
continue; // 跳过本轮剩余代码
}
printf("i = %d\n", i);
i++;
}
printf("循环结束\n");
return 0;
}
运行结果:
i = 1
i = 2
i = 4
i = 5
循环结束
3.注意事项:
其在使用时逻辑正确,否则可能出错,以下例子:
#include <stdio.h>
int main()
{
int i = 1;
while(i <= 10)
{
if(5 == i)
break; // break使用不当的点
printf("%d",i);
i ++;
}
return 0;
}
break 使用不当的错误分析:假设开发者的原本意图是「跳过数字 5,继续输出后面的数字」,但错误地使用了 break:
break的作用是立即终止整个循环,而不是跳过当前迭代- 当
i=5时,执行break会直接退出while循环,导致后面的6~10完全无法输出 - 最终结果只输出
1234,与「跳过 5 继续输出」的预期完全不符
正确做法:如果需要跳过当前迭代(保留后续循环),应使用 continue 而非 break,同时注意更新循环变量:
#include <stdio.h>
int main()
{
int i = 1;
while(i <= 10)
{
if(5 == i)
{
i++; // 必须手动更新i,否则会陷入死循环
continue; // 仅跳过当前迭代,继续下一次循环
}
printf("%d",i);
i ++;
}
return 0;
}
所以要灵活使用break和continue。
2.5 goto语句
在 C 语言中,goto 语句用于无条件跳转到函数内的指定标签位置,其语法格式如下:
goto 标签名;
...
标签名: 语句; // 标签名后必须跟冒号,且标签需在函数内有效
1.基本用法示例
#include <stdio.h>
int main() {
int i = 1;
loop_start: // 定义标签
if (i > 5) {
goto loop_end; // 跳转到结束标签
}
printf("%d ", i);
i++;
goto loop_start; // 跳转到开始标签,形成循环
loop_end: // 结束标签
printf("\n循环结束");
return 0;
}
输出结果:1 2 3 4 5 循环结束
2.特点与争议
优点:
- 可简化多层循环的退出逻辑(避免嵌套
break的繁琐) - 在出错处理时,可快速跳转到统一的资源释放位置
缺点:
- 过度使用会导致代码流程混乱(俗称「面条代码」),降低可读性和可维护性
- 可能破坏结构化程序设计的逻辑,增加调试难度
典型合理用法:多层循环退出
#include <stdio.h>
int main() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
goto exit_loop; // 直接退出所有循环
}
printf("(%d,%d) ", i, j);
}
}
exit_loop: // 退出标签
printf("\n已退出循环");
return 0;
}
输出结果:(0,0) (0,1) (0,2) (1,0) 已退出循环
3.使用建议
- 尽量避免使用
goto,优先通过函数封装、循环条件控制等结构化方式实现逻辑 - 若必须使用,应遵循:
- 只在同一函数内跳转
- 标签名需清晰表达跳转意图(如
error_handler、exit_loop) - 避免向前跳转(可能导致变量初始化等逻辑被跳过)
三.最后,向大家分享一下运用本节知识以及随机数做的猜数字小游戏,有空会分享写游戏的感悟,谢谢大家支持!
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
{
int N = 0;
int M = 0;
while (M == 0) {
printf(" * * * * \n");
printf(" * * * * * * * * \n");
printf(" * 1:10次 * * 2:8次 * \n");
printf(" * 3:5次 * * 4:3次 * \n");
printf(" * * * * * * * * * \n");
printf(" * HAPPY TIME * \n");
printf(" * * * * * \n");
printf(" * * * \n");
printf(" * \n");
scanf("%d", &N);
if (N == 1) {
M = 1;
return 10;
}
else if (N == 2) {
M = 1;
return 8;
}
else if (N == 3) {
return 5;
}
else if (N == 4) {
M = 1;
return 3;
}
else {
printf("数字无效,请重新输入\n");
}
}
return 0;
}
void game()
{
int r = rand() % 100 + 1;
int guess = 0;
printf("请选择你要猜的次数\n");
int left_times = change();
while (left_times > 0)
{
printf("您还有%d次机会,加油!\n", left_times);
printf("请输入你猜的数字\n");
scanf("%d", &guess);
if (guess > r)
{
printf("你猜大了\n");
}
else if (guess < r)
{
printf("你猜小了\n");
}
else
{
printf("你猜对了,太棒了!\n");
break;
}
left_times--; // 正确:剩余次数减1
}
if (left_times == 0)
{
printf("你失败了,正确值是:%d\n", r);
}
}
// menu()无错误,保持不变
void menu()
{
printf(" * * * * \n");
printf(" * * * * * * * * \n");
printf(" * * * * * * * * * * * \n");
printf(" * play:1 break:0 * \n");
printf(" * * * * * * * * * \n");
printf(" * * * * * * * \n");
printf(" * * * * * \n");
printf(" * * * \n");
printf(" * \n");
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("Welcome,请输入0或者1\n");
scanf("%d", &input);
switch (input)
{
case 0:
printf("游戏结束\n");
break;
case 1:
game();
break;
default:
printf("请输入正确的数字(0或1)\n");
}
} while (input != 0);
return 0;
}
:分支和循环——让C语言有自己的选择&spm=1001.2101.3001.5002&articleId=153331746&d=1&t=3&u=37abebce24f54f05aecb6b089107e1e4)
447

被折叠的 条评论
为什么被折叠?



