一、选择结构 & 条件判断
1. if
if(值为真或假的表达式){语句}
else if(){...}
else {...}
2. switch
switch (整型&字符型表达式) {
case 常量1:
语句1;
break; // 跳出 switch 结构
case 常量2:
语句2;
break;
case 常量3:
语句3;
// 如果这里不写 break,程序会继续"穿透"向下执行 case 4
case 常量4:
语句4;
break;
default:
语句N; // 当以上 case 都不匹配时执行(可选)
break;
}
P.S.
break的作用是执行完当前分支后立即跳出switch结构,因此可利用贯穿特性
3. 条件编译
编译:把 C 语言翻译为二进制指令
宏:编译前的"查找并替换"机制,通过 #define 定义
① 无参数
用于给某个常量或固定文本起一个有意义的名字,提高代码的可读性和可维护性。
#define PI 3.1415926
#define MAX_SIZE 100
int main() {
double area = PI * 5 * 5; // 在编译前,PI 会被直接替换为 3.1415926
int arr[MAX_SIZE]; // MAX_SIZE 被直接替换为 100
return 0;
}
② 有参数
外观看起来像函数,但本质上依然是直接替换代码,不会产生函数调用的开销(如压栈、跳转等)。
#define SQUARE(x) ((x) * (x))
int main() {
int result = SQUARE(5); // 预处理后展开为:((5) * (5))
return 0;
}
作用:在程序编译之前,根据指定的条件来决定"哪些代码需要被编译进最终的可执行文件,哪些代码需要被直接忽略",可以减小程序体积并提升运行效率。
#ifdef / #ifndef:根据宏是否被定义来选择"单选开关"
#include <stdio.h>
#define DEBUG // 定义一个名字叫 DEBUG 的"开关"
int main() {
// 2. 预处理器在这里做判断:DEBUG 被定义了吗?
#ifdef DEBUG
printf("【调试模式】当前变量 x 的值为 100\n"); // 如果贴了 DEBUG 标签,就编译下面这行代码
#else
printf("【发布模式】程序正在运行...\n"); // 如果没有贴 DEBUG 标签,就编译下面这行代码
#endif // 这个判断区域到此结束
return 0;
}
P.S. 用途:节省手动去删掉大项目开发阶段中上百个
printf打印变量调试程序的时间,只需要把最顶上的#define DEBUG这一行删掉或注释掉,全套调试代码就会瞬间全部"消失"。
#if / #elif / #else:根据表达式的常数值选择"多选列表"
e.g. 通过修改数字,来决定让代码去适应哪一个操作系统(Windows、Linux 还是 macOS)
// 1. 设置系统类型:1 代表 Win,2 代表 Linux,3 代表 Mac
#define SYSTEM_TYPE 2
// 2. 预处理器根据 SYSTEM_TYPE 的数值进行多条件判断
#if SYSTEM_TYPE == 1
// 如果是 1,只保留 Windows 专用的头文件
#include <windows.h>
#elif SYSTEM_TYPE == 2
// 如果是 2,只保留 Linux 专用的头文件
#include <unistd.h>
#else
// 如果都不是(比如 3),保留其他系统的代码
// 这里可以写 macOS 或通用代码
#endif // 结束判断
P.S. 不同操作系统,自带的函数库(头文件)不同。
防止头文件重复包含的标准写法(Header Guard)
P.S. 避免重复定义的错误
#pragma once // 告诉编译器:这个文件不管被调用几次,你只许看 1 次!
// 下面正常写你的代码...
typedef struct {
int id;
} Student;
二、循环结构
1. while
先判断,后执行。用于不确定具体要循环多少次,只知道"只要条件满足就一直做"的场景。
while (条件表达式) {
// 循环体代码
}
2. do - while 循环
直到型循环:先无条件执行一次循环体,后判断。用于无论如何都必须至少执行一次的场景(比如菜单显示、用户输入校验)。
do {
// 循环体代码
} while (条件表达式); // 注意:末尾必须有分号 ;
3. for 循环
已知循环次数。
for (初始化表达式; 条件表达式; 循环后更新表达式) {
// 循环体代码
}
4. 循环控制关键字:break 与 continue
break(彻底终止):- 效果:立即强行跳出整个循环,不再执行后续的任何循环迭代。
- 示例:寻找某个数字,找到后立刻用
break结束搜索。
continue(跳过本次):- 效果:结束本次循环的执行,但不退出循环结构。
- 示例:打印 1~10 中的奇数,遇到偶数时用
continue跳过打印。