1. 预定义符号
- C语言定义了一些预定义符号,可直接使用,预定义符号也是在预处理阶段处理的
__FILE__
__LINE__
__DATE__
__TIME__
__STDC__

2. #define定义常量

- #define定义标识符时需要在末尾加分号
;
吗???

3. #define定义宏
- C语言允许将参数替换到文本中,通常称为宏,定义如下:
#define name(parament-list) stuff
- 其中name是宏名,parament-list是宏的参数,stuff是宏体
- 其中参数列表左边的括号必须与宏名紧挨着,中间不允许有空格
- 简单举个例子


- 因此为了避免出现优先级的问题,通常会为宏体的每个参数加上括号


- 因此我们不仅要为宏的每个参数加上括号,同时还需要为整个宏体加上括号

4. 带有副作用的宏参数
- 当宏参数在宏定义时出现次数超过一次时,如果参数有副作用,那么使用宏就会出错


5. 宏替换的原则
- 调用宏时,主要是对
#define
定义的标识符替换成对应的宏体 - 宏参数和#define定义中可以出现其他#define定义的符号,但是宏不能递归
6. 宏和函数的对比

- 和函数相比,宏的劣势:
- 第一点就是宏用于简单的计算比函数有优势,执行复杂的程序时使用宏会出错
- 第二点就是宏没有类型的要求,这就使得其并不严谨,因此这也是宏的优点
- 第三点就是宏无法调式,同时因为优先级的问题,经常导致其出错


属性 | #define定义宏 | 函数 |
---|
代码长度 | 可用于长度小的代码中 | 代码长,复杂度高直接使用函数(√) |
执行速度 | 更快(√) | 存在函数调用和返回参数的额外操作,导致执行速度变慢 |
操作符优先级 | 为了不出错,使用宏时尽可能多写括号 | 容易预测(√) |
带有副作用的参数 | 不容易预测 | 容易预测(√) |
参数类型 | 无限制 | 限制 |
调试 | 不可调试 | 可调试(√) |
递归 | 不可递归 | 可递归(√) |
7. #运算符和##运算符
7.1 #运算符


7.2 ##运算符


8. 命名约定
9. #undef
- 它通常用来移除一个宏定义

10. 条件编译
- #if 常量表达式 …… #endif

- #ifdef 符号或语句 …… #endif

- 多个分支的条件编译
- #if 常量表达式 ……#elif 常量表达式……#else……#endif

- #if defined ……#ifdef……#ifndef……#endif

- 嵌套使用
