第4章 控制语句
条件语句
条件语句用于根据不同的条件执行不同的代码块,是实现程序逻辑分支的基础。
if 语句
if 语句是最基本的条件语句,用于根据条件执行不同的代码块。
基本形式
其中 condition 是一个表达式,其结果为布尔值(0 表示假,非 0 表示真)。
if-else 语句
当需要在条件为假时执行另一段代码时,可以使用 if-else 语句:
1 2 3 4 5 6 7 8
| if (condition) { } else { }
|
if-else if-else 语句
当需要处理多个条件时,可以使用 if-else if-else 语句:
1 2 3 4 5 6 7 8 9 10 11 12 13
| if (condition1) { } else if (condition2) { }
else { }
|
嵌套 if 语句
if 语句可以嵌套使用,即在一个 if 语句内部包含另一个 if 语句:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| if (condition1) { if (condition2) { } else { } } else { }
|
示例:成绩等级判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| int score = 85;
if (score >= 90) { printf("优秀\n"); } else if (score >= 80) { printf("良好\n"); } else if (score >= 60) { printf("及格\n"); } else { printf("不及格\n"); }
|
示例:嵌套 if 语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| int age = 25; bool has_license = true;
if (age >= 18) { if (has_license) { printf("可以开车\n"); } else { printf("成年但没有驾照,不能开车\n"); } } else { printf("未成年,不能开车\n"); }
|
条件运算符与 if 语句的比较
对于简单的条件判断,可以使用条件运算符(三元运算符)代替 if-else 语句:
1 2 3 4 5 6 7 8 9 10 11 12 13
| int max; if (a > b) { max = a; } else { max = b; }
int max = (a > b) ? a : b;
|
最佳实践
- 条件表达式的可读性:复杂的条件表达式应该拆分为多个简单的表达式,或使用辅助变量提高可读性
- 代码缩进:使用一致的缩进风格,使代码结构清晰
- 大括号的使用:即使只有一条语句,也建议使用大括号包围,避免后续修改时引入错误
- 条件顺序:将最可能为真的条件放在前面,减少条件判断的次数
- 避免深度嵌套:深度嵌套的 if 语句会降低代码可读性,考虑使用早期返回或重构为函数
switch 语句
switch 语句用于根据表达式的值选择执行不同的代码块,适合处理多个固定值的情况。
基本形式
1 2 3 4 5 6 7 8 9 10 11 12 13
| switch (expression) { case value1: break; case value2: break; default: break; }
|
示例:成绩等级判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| char grade = 'B';
switch (grade) { case 'A': printf("优秀\n"); break; case 'B': printf("良好\n"); break; case 'C': printf("及格\n"); break; case 'D': case 'F': printf("不及格\n"); break; default: printf("无效成绩\n"); break; }
|
示例:月份天数判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| int month = 2; int days;
switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: days = 31; break; case 4: case 6: case 9: case 11: days = 30; break; case 2: days = 28; break; default: days = 0; printf("无效月份\n"); break; }
printf("%d月有%d天\n", month, days);
|
注意事项
- 表达式类型:
expression 必须是整型、字符型或枚举类型,不能是浮点型或字符串 - case 标签:
case 标签必须是常量表达式,不能是变量 - break 语句:每个
case 分支通常需要使用 break 语句结束,否则会继续执行下一个 case 分支(称为”穿透”) - default 分支:
default 分支是可选的,用于处理所有未匹配的情况 - case 标签的顺序:
case 标签的顺序不影响执行结果,但通常将最常见的情况放在前面 - 空 case 分支:可以有多个
case 标签对应同一个代码块,如示例中的 ‘D’ 和 ‘F’ 都对应”不及格”的处理
switch 语句与 if-else 语句的比较
| 特性 | switch 语句 | if-else 语句 |
|---|
| 适用场景 | 多个固定值的判断 | 任意条件的判断 |
| 执行速度 | 通常更快(使用跳转表) | 可能较慢(顺序判断) |
| 代码可读性 | 多个固定值时更清晰 | 复杂条件时更灵活 |
| 表达能力 | 仅限于等值比较 | 支持任意逻辑表达式 |
高级用法:使用枚举类型
switch 语句与枚举类型配合使用可以提高代码的可读性和安全性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| enum Weekday { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY };
void print_weekday(enum Weekday day) { switch (day) { case MONDAY: printf("星期一\n"); break; case TUESDAY: printf("星期二\n"); break; case WEDNESDAY: printf("星期三\n"); break; case THURSDAY: printf("星期四\n"); break; case FRIDAY: printf("星期五\n"); break; case SATURDAY: printf("星期六\n"); break; case SUNDAY: printf("星期日\n"); break; default: printf("无效的星期\n"); break; } }
|
循环语句
循环语句用于重复执行一段代码,是实现重复操作的基础。
while 循环
while 循环在条件为真时重复执行代码块,适合不确定循环次数的情况。
基本形式
示例:打印数字
1 2 3 4 5 6 7
| int i = 1;
while (i <= 5) { printf("%d\n", i); i++; }
|
示例:计算阶乘
1 2 3 4 5 6 7 8 9 10 11
| int n = 5; int factorial = 1; int i = 1;
while (i <= n) { factorial *= i; i++; }
printf("%d的阶乘是%d\n", n, factorial);
|
示例:读取输入直到遇到特定值
1 2 3 4 5 6 7 8 9 10 11 12
| int number; printf("请输入数字(输入0结束):\n");
scanf("%d", &number); while (number != 0) { printf("你输入的是:%d\n", number); printf("请输入下一个数字(输入0结束):\n"); scanf("%d", &number); }
printf("程序结束\n");
|
注意事项
- 循环条件:循环条件必须能够在某个时刻变为假,否则会导致无限循环
- 循环变量的更新:确保在循环体内部更新循环变量,否则可能导致无限循环
- 空循环体:如果循环体为空,需要使用分号表示,如
while (condition); - 条件的计算:循环条件在每次循环开始时都会重新计算
do-while 循环
do-while 循环先执行一次代码块,然后在条件为真时重复执行,适合至少需要执行一次的情况。
基本形式
1 2 3 4
| do { } while (condition);
|
示例:打印数字
1 2 3 4 5 6 7
| int i = 1;
do { printf("%d\n", i); i++; } while (i <= 5);
|
示例:菜单选择
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| int choice;
do { printf("===== 菜单 =====\n"); printf("1. 选项1\n"); printf("2. 选项2\n"); printf("3. 退出\n"); printf("请选择:"); scanf("%d", &choice); switch (choice) { case 1: printf("你选择了选项1\n"); break; case 2: printf("你选择了选项2\n"); break; case 3: printf("退出程序\n"); break; default: printf("无效选择\n"); break; } printf("\n"); } while (choice != 3);
|
do-while 循环与 while 循环的比较
| 特性 | do-while 循环 | while 循环 |
|---|
| 执行次数 | 至少执行一次 | 可能一次也不执行 |
| 条件检查时机 | 循环体执行后 | 循环体执行前 |
| 适用场景 | 至少需要执行一次的操作,如菜单选择 | 不确定是否需要执行的操作 |
| 语法结构 | 以 do 开始,while 结束,分号结尾 | 以 while 开始,条件后直接跟随循环体 |
for 循环
for 循环是一种更结构化的循环形式,适合已知循环次数的情况。
基本形式
1 2 3 4
| for (initialization; condition; update) { }
|
其中:
initialization - 循环开始前执行的初始化语句,通常用于初始化循环变量condition - 每次循环前检查的条件,为真时执行循环体update - 每次循环后执行的更新语句,通常用于更新循环变量
示例:打印数字
1 2 3 4
| for (int i = 1; i <= 5; i++) { printf("%d\n", i); }
|
示例:计算累加和
1 2 3 4 5 6
| int sum = 0; for (int i = 1; i <= 100; i++) { sum += i; } printf("1到100的和是:%d\n", sum);
|
示例:遍历数组
1 2 3 4 5 6 7
| int numbers[] = {1, 2, 3, 4, 5}; int length = sizeof(numbers) / sizeof(numbers[0]);
for (int i = 0; i < length; i++) { printf("numbers[%d] = %d\n", i, numbers[i]); }
|
for 循环的变体
省略初始化语句
如果循环变量已经在外部初始化,可以省略初始化语句:
1 2 3 4 5
| int i = 1; for (; i <= 5; i++) { printf("%d\n", i); }
|
省略条件语句
省略条件语句会导致无限循环,需要在循环体内部使用 break 语句退出:
1 2 3 4 5 6
| for (int i = 1;; i++) { printf("%d\n", i); if (i >= 5) break; }
|
省略更新语句
如果在循环体内部更新循环变量,可以省略更新语句:
1 2 3 4 5
| for (int i = 1; i <= 5;) { printf("%d\n", i); i++; }
|
省略所有部分
省略所有三个部分会导致无限循环:
1 2 3 4 5
| for (;;) { printf("无限循环\n"); }
|
多个循环变量
可以在初始化语句中声明多个循环变量,在更新语句中更新多个循环变量:
1 2 3 4
| for (int i = 1, j = 10; i <= j; i++, j--) { printf("i = %d, j = %d\n", i, j); }
|
使用逗号表达式
可以在初始化和更新语句中使用逗号表达式执行多个操作:
1 2 3 4 5 6
| int sum = 0; for (int i = 1, j = 1; i <= 10; sum += i, i++, j++) { printf("i = %d, j = %d, sum = %d\n", i, j, sum); } printf("最终 sum = %d\n", sum);
|
注意事项
- 循环变量的作用域:在 for 循环的初始化语句中声明的变量,其作用域仅限于循环体内部
- 循环条件的计算:循环条件在每次循环开始时都会重新计算
- 无限循环:如果省略条件语句或条件永远为真,会导致无限循环
- 嵌套 for 循环:for 循环可以嵌套使用,实现更复杂的逻辑
嵌套循环
循环可以嵌套使用,即在一个循环内部包含另一个循环,用于处理多维数据或实现复杂的算法。
示例:打印乘法表
1 2 3 4 5 6 7 8 9
| for (int i = 1; i <= 9; i++) { for (int j = 1; j <= i; j++) { printf("%d × %d = %d\t", j, i, i * j); } printf("\n"); }
|
示例:打印二维数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int matrix[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { printf("%d ", matrix[i][j]); } printf("\n"); }
|
示例:打印菱形
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| int n = 5;
for (int i = 1; i <= n; i++) { for (int j = 1; j <= n - i; j++) { printf(" "); } for (int j = 1; j <= 2 * i - 1; j++) { printf("*"); } printf("\n"); }
for (int i = n - 1; i >= 1; i--) { for (int j = 1; j <= n - i; j++) { printf(" "); } for (int j = 1; j <= 2 * i - 1; j++) { printf("*"); } printf("\n"); }
|
嵌套循环的性能考虑
- 循环顺序:对于多维数组的遍历,应按照内存布局的顺序访问,以提高缓存命中率
- 循环深度:尽量减少循环的嵌套深度,深度过大会降低代码可读性和性能
- 循环展开:对于内层循环,可以考虑循环展开以减少循环开销
- 并行处理:对于独立的循环迭代,可以考虑使用并行处理技术
循环控制
循环的选择
| 循环类型 | 适用场景 | 优点 | 缺点 |
|---|
| while | 不确定循环次数,条件可能在循环体外部变化 | 结构简单,条件检查灵活 | 循环变量的初始化和更新分散在循环外部 |
| do-while | 至少需要执行一次的操作 | 确保循环体至少执行一次 | 语法相对复杂 |
| for | 已知循环次数,或循环变量有明确的范围 | 结构紧凑,初始化、条件检查和更新集中在一起 | 对于复杂的循环条件可能不够灵活 |
循环的优化
- 减少循环内的计算:将循环不变的计算移到循环外部
- 使用合适的数据结构:选择适合操作的数据结构,如使用数组代替链表进行随机访问
- 避免不必要的函数调用:尽量减少循环内的函数调用,或使用内联函数
- 循环展开:对于小循环,可以手动展开以减少循环开销
- 使用编译器优化:开启编译器的优化选项,如
-O2 或 -O3
跳转语句
跳转语句用于改变程序的执行流程,包括 break、continue 和 goto 语句。
break 语句
break 语句用于跳出当前循环或 switch 语句,执行循环或 switch 语句之后的代码。
基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| while (condition) { if (some_condition) break; }
switch (expression) { case value: break; }
|
示例:跳出 for 循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| int numbers[] = {5, 8, 12, 3, 7}; int length = sizeof(numbers) / sizeof(numbers[0]); int found = -1;
for (int i = 0; i < length; i++) { if (numbers[i] > 10) { found = i; break; } }
if (found != -1) { printf("第一个大于 10 的元素是 numbers[%d] = %d\n", found, numbers[found]); } else { printf("没有找到大于 10 的元素\n"); }
|
示例:跳出嵌套循环
break 语句只能跳出当前层的循环,要跳出多层循环需要使用标签或其他方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int i, j; for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { if (i * j > 20) { goto end_loop; } printf("i = %d, j = %d\n", i, j); } } end_loop: printf("跳出循环,i = %d, j = %d\n", i, j);
|
continue 语句
continue 语句用于跳过当前循环的剩余部分,直接进入下一次循环的条件检查。
基本用法
1 2 3 4 5 6
| while (condition) { if (some_condition) continue; }
|
示例:跳过偶数
1 2 3 4 5 6 7
| for (int i = 1; i <= 10; i++) { if (i % 2 == 0) continue; printf("%d\n", i); }
|
示例:处理有效输入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| int count = 0; int number;
while (count < 5) { printf("请输入一个正整数:"); scanf("%d", &number); if (number <= 0) { printf("无效输入,请重新输入\n"); continue; } printf("你输入的是:%d\n", number); count++; }
printf("已输入 5 个正整数\n");
|
goto 语句
goto 语句用于跳转到函数内的指定标签位置,改变程序的执行流程。
基本形式
其中 label 是一个标识符,后面跟着冒号。
示例:使用 goto 实现循环
1 2 3 4 5 6
| int i = 1; loop: printf("%d\n", i); i++; if (i <= 5) goto loop;
|
示例:错误处理
goto 语句在错误处理中非常有用,可以集中处理资源释放:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| void process_file(const char* filename) { FILE* file = NULL; char* buffer = NULL; file = fopen(filename, "r"); if (file == NULL) { perror("无法打开文件"); goto cleanup; } buffer = malloc(1024); if (buffer == NULL) { perror("无法分配内存"); goto cleanup; } cleanup: if (buffer != NULL) free(buffer); if (file != NULL) fclose(file); }
|
注意事项
- 代码可读性:过度使用
goto 语句会使代码结构变得混乱,降低可读性 - 作用域:
goto 语句只能在同一个函数内跳转,不能跨函数跳转 - 跳转方向:虽然
goto 语句可以向前或向后跳转,但向后跳转可能导致无限循环 - 变量初始化:跳转到标签处时,需要确保所有使用的变量都已正确初始化
- 合理使用:
goto 语句在以下场景中是合理的:
goto 语句的替代方案
在许多情况下,可以使用其他控制语句替代 goto 语句:
- 使用函数:将代码块提取为函数,使用
return 语句退出 - 使用循环:使用循环替代向后跳转
- 使用条件语句:使用条件语句替代简单的跳转
- 使用状态变量:使用状态变量控制程序的执行流程
控制语句的应用
示例 1:猜数字游戏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include <stdio.h> #include <stdlib.h> #include <time.h>
int main(void) { int number, guess, attempts = 0; srand(time(NULL)); number = rand() % 100 + 1; printf("猜数字游戏!\n"); printf("我想了一个 1-100 之间的数字,你能猜对吗?\n"); do { printf("请输入你的猜测:"); scanf("%d", &guess); attempts++; if (guess > number) { printf("太大了!\n"); } else if (guess < number) { printf("太小了!\n"); } else { printf("恭喜你猜对了!\n"); printf("你用了 %d 次尝试。\n", attempts); } } while (guess != number); return 0; }
|
示例 2:打印金字塔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <stdio.h>
int main(void) { int rows, i, j, spaces; printf("请输入金字塔的行数:"); scanf("%d", &rows); for (i = 1; i <= rows; i++) { for (spaces = 1; spaces <= rows - i; spaces++) { printf(" "); } for (j = 1; j <= 2 * i - 1; j++) { printf("*"); } printf("\n"); } return 0; }
|
示例 3:判断素数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| #include <stdio.h>
int main(void) { int number, i, is_prime = 1; printf("请输入一个正整数:"); scanf("%d", &number); if (number <= 1) { is_prime = 0; } else { for (i = 2; i <= number / 2; i++) { if (number % i == 0) { is_prime = 0; break; } } } if (is_prime) { printf("%d 是素数。\n", number); } else { printf("%d 不是素数。\n", number); } return 0; }
|
示例 4:冒泡排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| #include <stdio.h>
void bubble_sort(int arr[], int n) { int i, j, temp; int swapped; for (i = 0; i < n - 1; i++) { swapped = 0; for (j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; swapped = 1; } } if (swapped == 0) break; } }
void print_array(int arr[], int n) { for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } printf("\n"); }
int main(void) { int arr[] = {64, 34, 25, 12, 22, 11, 90}; int n = sizeof(arr) / sizeof(arr[0]); printf("排序前:"); print_array(arr, n); bubble_sort(arr, n); printf("排序后:"); print_array(arr, n); return 0; }
|
示例 5:状态机实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include <stdio.h>
enum State { STATE_IDLE, STATE_READING, STATE_PROCESSING, STATE_WRITING, STATE_ERROR };
int main(void) { enum State current_state = STATE_IDLE; int input; while (1) { switch (current_state) { case STATE_IDLE: printf("当前状态:空闲\n"); printf("请输入命令 (1=开始读取, 2=退出):"); scanf("%d", &input); if (input == 1) { current_state = STATE_READING; } else if (input == 2) { goto exit_program; } else { printf("无效命令\n"); } break; case STATE_READING: printf("当前状态:读取数据\n"); printf("正在读取数据...\n"); current_state = STATE_PROCESSING; break; case STATE_PROCESSING: printf("当前状态:处理数据\n"); printf("正在处理数据...\n"); current_state = STATE_WRITING; break; case STATE_WRITING: printf("当前状态:写入数据\n"); printf("正在写入数据...\n"); current_state = STATE_IDLE; break; case STATE_ERROR: printf("当前状态:错误\n"); printf("正在处理错误...\n"); current_state = STATE_IDLE; break; default: printf("无效状态\n"); current_state = STATE_IDLE; break; } printf("\n"); } exit_program: printf("程序退出\n"); return 0; }
|
控制语句的性能优化
条件分支预测
现代处理器使用分支预测器来预测条件分支的执行方向,提高执行效率。为了帮助处理器正确预测分支,可以:
- 保持分支的一致性:尽量使条件分支的执行方向保持一致
- 将最常见的情况放在前面:在 if-else 语句中,将最可能发生的情况放在前面
- 避免复杂的条件表达式:复杂的条件表达式会降低分支预测的准确性
- 使用查表代替条件分支:对于多个固定值的判断,可以使用查表代替 switch 或 if-else 语句
循环优化
- 减少循环次数:通过数学方法减少循环的总次数
- 循环不变量外提:将循环中不变的计算移到循环外部
- 循环展开:手动展开循环以减少循环开销
- 向量化:使用 SIMD 指令并行处理循环中的数据
- 减少内存访问:尽量使用寄存器变量,减少内存访问次数
跳转表的使用
对于多个固定值的判断,使用跳转表可以比 switch 语句更高效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| void handle_case_0(void) { printf("处理情况 0\n"); }
void handle_case_1(void) { printf("处理情况 1\n"); }
void handle_case_2(void) { printf("处理情况 2\n"); }
void handle_default(void) { printf("处理默认情况\n"); }
void (*jump_table[])(void) = { handle_case_0, handle_case_1, handle_case_2 };
#define TABLE_SIZE (sizeof(jump_table) / sizeof(jump_table[0]))
void process_case(int case_num) { if (case_num >= 0 && case_num < TABLE_SIZE) { jump_table[case_num](); } else { handle_default(); } }
|
代码风格和最佳实践
代码缩进和格式
- 缩进:使用 4 个空格或 1 个制表符进行缩进,保持一致
- 大括号:使用 K&R 风格或 Allman 风格,保持一致
- 行长度:每行代码不超过 80-100 个字符
- 空格:在运算符前后、逗号后使用空格,提高代码可读性
- 空行:在逻辑块之间使用空行,提高代码的可读性
注释的使用
- 函数注释:在函数定义前添加注释,说明函数的功能、参数、返回值
- 复杂代码:在复杂的代码段前添加注释,说明代码的逻辑
- 变量注释:对于重要的变量,添加注释说明其用途
- 避免过度注释:不要注释显而易见的代码
常见错误和避免方法
- 无限循环:确保循环条件能够在某个时刻变为假
- 缺少 break 语句:在 switch 语句中,确保每个 case 分支都有适当的 break 语句
- 空悬 else:使用大括号明确 else 的归属
- 整数溢出:注意循环变量的范围,避免整数溢出
- 缓冲区溢出:在处理数组和字符串时,注意边界检查
- 未初始化的变量:确保在使用变量前对其进行初始化
- 逻辑错误:仔细检查条件表达式的逻辑,避免逻辑错误
- 资源泄漏:在使用完资源后,确保正确释放
调试技巧
- 打印调试:在关键位置添加打印语句,输出变量的值
- 使用调试器:使用 gdb、lldb 等调试器进行调试
- 断言:使用 assert 宏检查程序的假设
- 单元测试:为关键功能编写单元测试
- 代码审查:通过代码审查发现潜在的问题
小结
本章详细介绍了 C 语言的控制语句,包括:
- 条件语句:
if 语句、switch 语句及其变体和最佳实践 - 循环语句:
while 循环、do-while 循环、for 循环及其嵌套和优化 - 跳转语句:
break 语句、continue 语句、goto 语句的使用场景和注意事项 - 控制语句的应用:实际应用示例、算法实现、状态机设计
- 控制语句的性能优化:分支预测、循环优化、跳转表的使用
- 代码风格和最佳实践:缩进、注释、常见错误和避免方法
控制语句是 C 语言编程的核心,掌握这些语句的使用方法和技巧对于编写高效、可靠的程序至关重要。通过合理使用控制语句,你可以实现各种复杂的算法和逻辑,解决实际问题。
在后续章节中,我们将学习函数、数组和指针等高级概念,这些概念将与控制语句结合使用,帮助你编写更加结构化、模块化和高效的代码。