控制语句
6. 控制语句
控制语句是 C 语言中用于控制程序执行流程的结构。通过控制语句,可以根据条件执行不同的代码块,或者重复执行某些操作,从而实现复杂的逻辑和功能。掌握控制语句是编写有效和高效 C 程序的关键。
6.1 条件控制
条件控制语句用于根据某些条件来决定程序的执行路径。C 语言提供了多种条件控制结构,包括if语句、else if语句和switch语句。
6.1.1 if语句
if语句用于在条件为真时执行特定的代码块。它是最基本的条件控制语句。
语法:
if (条件) {
// 条件为真时执行的代码
}
示例与详细说明:
#include <stdio.h>
int main() {
int num = 10;
// 使用if语句判断num是否为正数
if (num > 0) {
printf("num 是一个正数。\n");
}
return 0;
}
输出:
num 是一个正数。
详细解释:
-
条件表达式:
num > 0,如果num大于 0,条件为真(1),则执行if块中的代码。 -
执行流程
:
- 计算条件
num > 0。 - 如果条件为真,执行大括号
{}内的代码。 - 如果条件为假,跳过
if块中的代码。
- 计算条件
更多示例:
#include <stdio.h>
int main() {
int age = 18;
// 判断是否成年
if (age >= 18) {
printf("你已成年,可以投票。\n");
}
return 0;
}
输出:
你已成年,可以投票。
6.1.2 else if语句
else if语句用于在第一个if条件不满足时,提供多个条件判断的可能性。它允许在多个条件之间进行选择。
语法:
if (条件1) {
// 条件1为真时执行的代码
} else if (条件2) {
// 条件2为真时执行的代码
} else {
// 所有条件都不满足时执行的代码
}
示例与详细说明:
#include <stdio.h>
int main() {
int score = 85;
// 使用if-else if-else结构判断成绩等级
if (score >= 90) {
printf("成绩等级:A\n");
} else if (score >= 80) {
printf("成绩等级:B\n");
} else if (score >= 70) {
printf("成绩等级:C\n");
} else if (score >= 60) {
printf("成绩等级:D\n");
} else {
printf("成绩等级:F\n");
}
return 0;
}
输出:
成绩等级:B
详细解释:
- 条件判断顺序:
- 判断
score >= 90,如果为真,输出A并跳过后续条件。 - 如果上一个条件为假,判断
score >= 80,如果为真,输出B。 - 依此类推,直到最后的
else块。
- 判断
- 执行流程:
- 依次检查每个
if和else if的条件。 - 当某个条件为真时,执行对应的代码块,并跳过剩余的条件检查。
- 如果所有条件都不满足,执行
else块中的代码。
- 依次检查每个
更多示例:
#include <stdio.h>
int main() {
int temperature = 30;
// 判断天气情况
if (temperature > 30) {
printf("天气非常热,适合游泳。\n");
} else if (temperature > 20) {
printf("天气温暖,适合户外活动。\n");
} else if (temperature > 10) {
printf("天气稍凉,适合散步。\n");
} else {
printf("天气寒冷,建议在室内活动。\n");
}
return 0;
}
输出:
天气温暖,适合户外活动。
6.1.3 switch语句
switch语句用于基于一个变量的不同值来执行不同的代码块。它通常用于替代多个if-else if条件判断,使代码更加简洁和易读。
语法:
switch (表达式) {
case 值1:
// 当表达式等于值1时执行的代码
break;
case 值2:
// 当表达式等于值2时执行的代码
break;
// 可以有任意多个case
default:
// 当表达式不匹配任何case时执行的代码
}
示例与详细说明:
#include <stdio.h>
int main() {
int day = 3;
// 使用switch语句判断星期几
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:
printf("星期六\n");
break;
case 7:
printf("星期日\n");
break;
default:
printf("无效的星期数\n");
}
return 0;
}
输出:
星期三
详细解释:
-
表达式:
day的值为 3。 -
case 匹配
:
- 检查
case 1,不匹配。 - 检查
case 2,不匹配。 - 检查
case 3,匹配,执行printf("星期三\n");,然后遇到break跳出switch语句。
- 检查
-
break语句:用于终止switch语句的执行,防止“贯穿”到下一个case。 -
default语句:当表达式的值不匹配任何case时执行的代码块。
更多示例:
#include <stdio.h>
int main() {
char grade = 'B';
// 使用switch语句判断成绩等级
switch (grade) {
case 'A':
printf("优秀\n");
break;
case 'B':
printf("良好\n");
break;
case 'C':
printf("及格\n");
break;
case 'D':
printf("不及格\n");
break;
default:
printf("无效的成绩等级\n");
}
return 0;
}
输出:
良好
注意事项:
-
break的重要性:如果在case后不使用break,程序会继续执行后续的case,这通常不是期望的行为,称为“贯穿”。示例:
#include <stdio.h> int main() { int num = 2; switch (num) { case 1: printf("一\n"); case 2: printf("二\n"); case 3: printf("三\n"); default: printf("无效的数字\n"); } return 0; }输出:
二 三 无效的数字解释:由于缺少
break,case 2匹配后,继续执行case 3和default中的代码。 -
default的可选性:default块不是必须的,但建议在需要时使用,以处理所有未被case覆盖的情况。 -
表达式类型:
switch语句的表达式必须是整型或枚举类型,不能是浮点型或其他类型。
6.2 循环控制
循环控制语句用于重复执行某段代码,直到满足特定条件。C 语言提供了多种循环结构,包括for循环、while循环和do-while循环。
6.2.1 for循环
for循环是一种计数循环,适用于已知循环次数的场景。它包括初始化、条件判断和迭代表达式三个部分。
语法:
for (初始化; 条件; 迭代) {
// 循环体
}
示例与详细说明:
#include <stdio.h>
int main() {
int i;
// 使用for循环打印1到5
for (i = 1; i <= 5; i++) {
printf("i = %d\n", i);
}
return 0;
}
输出:
i = 1
i = 2
i = 3
i = 4
i = 5
详细解释:
-
初始化:
i = 1,在循环开始前执行一次。 -
条件:
i <= 5,每次循环前检查条件是否为真。 -
迭代:
i++,每次循环结束后执行,通常用于更新循环变量。 -
执行流程
:
- 执行初始化
i = 1。 - 检查条件
i <= 5,如果为真,执行循环体。 - 执行循环体中的代码
printf("i = %d\n", i);。 - 执行迭代
i++,使i递增。 - 重复步骤 2,直到条件为假。
- 执行初始化
更多示例:
#include <stdio.h>
int main() {
int sum = 0;
// 使用for循环计算1到10的和
for (int i = 1; i <= 10; i++) {
sum += i; // sum = sum + i
}
printf("1到10的和是: %d\n", sum);
return 0;
}
输出:
1到10的和是: 55
嵌套 for 循环示例:
#include <stdio.h>
int main() {
int rows = 5;
// 使用嵌套for循环打印星号三角形
for (int i = 1; i <= rows; i++) { // 控制行数
for (int j = 1; j <= i; j++) { // 控制每行的星号数量
printf("* ");
}
printf("\n"); // 换行
}
return 0;
}
输出:
*
* *
* * *
* * * *
* * * * *
注意事项:
-
无限循环:如果循环条件永远为真,
for循环会无限执行。例如:for (;;) { // 无限循环 } -
循环变量作用域:在
for循环中声明的变量,其作用域仅限于循环内部。for (int i = 0; i < 5; i++) { // 使用i } // i在此处不可用
6.2.2 while循环
while循环是一种条件循环,适用于循环次数不确定,直到满足特定条件为止的场景。
语法:
while (条件) {
// 循环体
}
示例与详细说明:
#include <stdio.h>
int main() {
int count = 1;
// 使用while循环打印1到5
while (count <= 5) {
printf("count = %d\n", count);
count++; // 更新循环变量
}
return 0;
}
输出:
count = 1
count = 2
count = 3
count = 4
count = 5
详细解释:
-
条件:
count <= 5,每次循环前检查条件是否为真。 -
执行流程
:
- 检查条件
count <= 5,如果为真,执行循环体。 - 执行循环体中的代码
printf("count = %d\n", count);。 - 执行循环变量更新
count++。 - 重复步骤 1,直到条件为假。
- 检查条件
更多示例:
#include <stdio.h>
int main() {
int number = 10;
int factorial = 1;
// 使用while循环计算10的阶乘
while (number > 1) {
factorial *= number; // factorial = factorial * number
number--;
}
printf("10的阶乘是: %d\n", factorial);
return 0;
}
输出:
10的阶乘是: 3628800
无限循环示例:
#include <stdio.h>
int main() {
int num = 0;
// 无限循环,直到num等于5
while (1) { // 条件永远为真
printf("num = %d\n", num);
if (num == 5) {
break; // 退出循环
}
num++;
}
return 0;
}
输出:
num = 0
num = 1
num = 2
num = 3
num = 4
num = 5
注意事项:
- 循环条件:确保循环条件能够在某个时刻变为假,以避免无限循环。
- 循环变量更新:在循环体中适当更新循环变量,避免条件永远为真。
6.2.3 do-while循环
do-while循环类似于while循环,但它至少会执行一次循环体,因为条件判断在循环体之后进行。
语法:
do {
// 循环体
} while (条件);
示例与详细说明:
#include <stdio.h>
int main() {
int number = 1;
// 使用do-while循环打印1到5
do {
printf("number = %d\n", number);
number++;
} while (number <= 5);
return 0;
}
输出:
number = 1
number = 2
number = 3
number = 4
number = 5
详细解释:
- 执行流程:
- 先执行循环体中的代码。
- 然后检查条件
number <= 5。 - 如果条件为真,继续执行循环体;否则,退出循环。
- 至少执行一次:即使初始条件为假,
do-while循环也会执行一次循环体。
更多示例:
#include <stdio.h>
int main() {
int password;
int correctPassword = 1234;
int attempts = 0;
int maxAttempts = 3;
int accessGranted = 0;
// 使用do-while循环验证密码
do {
printf("请输入密码: ");
scanf("%d", &password);
attempts++;
if (password == correctPassword) {
accessGranted = 1;
printf("密码正确,访问授权。\n");
break;
} else {
printf("密码错误。\n");
}
} while (attempts < maxAttempts);
if (!accessGranted) {
printf("尝试次数过多,访问被拒绝。\n");
}
return 0;
}
示例输出(用户输入错误密码两次,第三次正确):
请输入密码: 1111
密码错误。
请输入密码: 2222
密码错误。
请输入密码: 1234
密码正确,访问授权。
注意事项:
- 至少执行一次:
do-while循环适用于需要至少执行一次的场景,如菜单驱动的程序。 - 循环条件位置:条件判断在循环体之后,因此可以确保循环体至少执行一次。
6.3 跳转语句
跳转语句用于在程序执行过程中改变控制流程,直接跳转到程序的某个部分。这些语句包括break、continue和goto。
6.3.1 break语句
break语句用于立即终止最近的for、while、do-while循环或switch语句,并跳出循环或switch块。
语法:
break;
示例与详细说明:
#include <stdio.h>
int main() {
int i;
// 使用for循环查找第一个偶数并跳出循环
for (i = 1; i <= 10; i++) {
if (i % 2 == 0) {
printf("找到第一个偶数: %d\n", i);
break; // 终止循环
}
}
// 循环结束后继续执行
printf("循环已终止。\n");
return 0;
}
输出:
找到第一个偶数: 2
循环已终止。
详细解释:
-
执行流程
:
- 循环从
i = 1开始,逐步递增。 - 当
i等于 2 时,条件i % 2 == 0为真,执行printf输出,并使用break跳出循环。 - 循环终止,执行
printf("循环已终止。\n");。
- 循环从
更多示例:
#include <stdio.h>
int main() {
int number;
// 使用while循环读取用户输入,遇到负数时跳出循环
while (1) { // 无限循环
printf("请输入一个正整数(输入负数退出): ");
scanf("%d", &number);
if (number < 0) {
printf("收到负数,退出循环。\n");
break; // 终止循环
}
printf("你输入的数是: %d\n", number);
}
return 0;
}
示例输出:
请输入一个正整数(输入负数退出): 5
你输入的数是: 5
请输入一个正整数(输入负数退出): 10
你输入的数是: 10
请输入一个正整数(输入负数退出): -3
收到负数,退出循环。
注意事项:
- 跳出嵌套循环:
break只能终止最近的一个循环或switch语句,无法直接跳出多层嵌套的循环。 - 使用场景:适用于在满足特定条件时提前退出循环,如查找元素、验证输入等。
6.3.2 continue语句
continue语句用于跳过当前循环的剩余部分,立即开始下一次循环迭代。它不终止循环,只是提前进入下一轮循环。
语法:
continue;
示例与详细说明:
#include <stdio.h>
int main() {
int i;
// 使用for循环打印1到10中不等于5的数字
for (i = 1; i <= 10; i++) {
if (i == 5) {
continue; // 跳过数字5
}
printf("i = %d\n", i);
}
return 0;
}
输出:
i = 1
i = 2
i = 3
i = 4
i = 6
i = 7
i = 8
i = 9
i = 10
详细解释:
-
执行流程
:
- 循环从
i = 1开始,逐步递增。 - 当
i等于 5 时,执行continue,跳过当前循环体中剩余的代码,进入下一次循环迭代。 - 其他情况下,执行
printf输出当前的i值。
- 循环从
更多示例:
#include <stdio.h>
int main() {
int num;
// 使用while循环打印1到10中偶数
num = 0;
while (num < 10) {
num++;
if (num % 2 != 0) {
continue; // 如果是奇数,跳过
}
printf("偶数: %d\n", num);
}
return 0;
}
输出:
偶数: 2
偶数: 4
偶数: 6
偶数: 8
偶数: 10
注意事项:
- 跳过循环体:
continue会立即跳过循环体中剩余的代码,进行条件判断和迭代更新。 - 使用场景:适用于需要跳过某些特定条件下的循环体执行,如过滤数据、跳过错误输入等。
6.3.3 goto语句
goto语句用于无条件地跳转到程序中的特定标签。它可以用于实现复杂的控制流程,但滥用goto可能导致“意大利面条代码”(代码结构混乱,难以维护)。
语法:
goto 标签;
...
标签:
// 跳转到此处执行的代码
示例与详细说明:
#include <stdio.h>
int main() {
int num;
printf("请输入一个正整数: ");
scanf("%d", &num);
// 使用goto检查输入
if (num <= 0) {
printf("输入无效,请输入一个正整数。\n");
goto end; // 跳转到标签'end'
}
printf("你输入的数是: %d\n", num);
end:
printf("程序结束。\n");
return 0;
}
示例输出:
请输入一个正整数: -5
输入无效,请输入一个正整数。
程序结束。
详细解释:
-
标签:
end:是一个标签,标识程序中的某个位置。 -
跳转:当条件
num <= 0为真时,执行goto end;,跳转到end标签处执行代码。 -
执行流程
:
- 用户输入一个数,如果该数为正数,程序继续执行
printf("你输入的数是: %d\n", num);。 - 如果输入的数不是正数,程序输出错误信息,并跳转到
end标签处,输出程序结束。。
- 用户输入一个数,如果该数为正数,程序继续执行
更多示例:
#include <stdio.h>
int main() {
int i = 0;
// 使用goto实现循环
loop_start:
if (i >= 5) {
goto loop_end; // 跳出循环
}
printf("i = %d\n", i);
i++;
goto loop_start; // 继续循环
loop_end:
printf("循环结束。\n");
return 0;
}
输出:
i = 0
i = 1
i = 2
i = 3
i = 4
循环结束。
注意事项:
- 代码可读性:过度使用
goto会使代码难以理解和维护,建议尽量避免。 - 替代方案:大多数情况下,
for、while等循环和break、continue等跳转语句可以满足需求,减少对goto的依赖。 - 异常处理:在某些情况下,如深层嵌套的循环或复杂的错误处理,
goto可能提供简洁的解决方案,但应谨慎使用。
6.4 总结
控制语句是 C 语言中用于管理程序执行流程的关键工具。通过合理使用条件控制和循环控制语句,可以实现复杂的逻辑判断和重复操作。同时,跳转语句在特定场景下提供了灵活的控制能力。掌握这些控制语句的使用方法和应用场景,是编写高效、可维护 C 程序的基础。
- 条件控制:
if语句用于基本的条件判断。else if语句用于多条件判断。switch语句用于基于变量值的多分支选择。
- 循环控制:
for循环适用于已知循环次数的场景。while循环适用于循环次数不确定,基于条件的场景。do-while循环保证循环体至少执行一次,适用于需要先执行再判断条件的场景。
- 跳转语句:
break用于终止最近的循环或switch语句。continue用于跳过当前循环的剩余部分,进入下一次循环迭代。goto用于无条件跳转到程序中的特定标签,需谨慎使用以保持代码的可读性和结构清晰。