目录
一、前言
我们都知道#define语句可以定义常量,在编译器预处理时会全部将名字替换为常量。与此同时,#define也允许把参数替换到文本中,这就是本文要重点介绍的宏定义。
二、宏的相关语法
2.1 #define
//语法定义
#define name( parament-list ) stuff
//使用举例
#define DOUBLE(x) (x) + (x)
int main()
{
int a = DOUBLE(2);
return 0;
}
2.2 #undef
//用于移除已定义的宏
#undef NAME
2.3 #运算符
- 功能:#运算符将宏的⼀个参数转换为字符串字⾯量
- 引入:字符串中的n没有被替换
#define PRINT(n,format) printf("the value of n is "format"\n",n) int main() { int a = 8; PRINT(a,"%d"); int b = 69; PRINT(b,"%d"); float c = 6.6f; PRINT(c,"%f"); return 0; }
- 修改:
#include <stdio.h> #define PRINT(n,format) printf("the value of "#n " ""is "format"\n",n) int main() { int a = 8; PRINT(a,"%d"); int b = 69; PRINT(b,"%d"); float c = 6.6f; PRINT(c,"%f"); return 0; }
2.4 ##运算符
- 功能:##可以把位于它两边的符号合成⼀个符号
- 代码示例:
#define GENERATED_MAX(type) \ type type##_max(type x , type y) \ { \ return x>y?x:y; \ } //定义函数 GENERATED_MAX(int); GENERATED_MAX(float); int main() { int a = int_max(3, 5); printf("%d\n", a); float b = float_max(3.5, 6.7); printf("%.2f\n", b); return 0; }
三、宏替换的规则
- 在调⽤宏时,⾸先对参数进⾏检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。
- 替换⽂本随后被插⼊到程序中原来文本的位置。对于宏,参数名被他们的值所替换。
- 最后,再次对结果⽂件进⾏扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上 述处理过程。
- 注意:宏仅仅做替换,不会影响运算优先级
#define SQUARE(x) x*x int main() { int a = 2; printf("%d\n", a + 1 * a + 1); //替换为 2+1*2+1 = 5 return 0; }
四、宏与函数
为了区分二者约定俗成:把宏名全部大写 函数名全部小写
由上文可见,有的时候宏定义可以充当函数的功能,那么它们二者究竟有哪些区别呢?
函数 | 宏定义 | |
---|---|---|
调试 | 方便逐语句调试 | 不方便调试 |
递归 | 可以递归 | 不可以递归 |
代码长度 | 长 | 短 |
执行速度 | 相对较慢 | 相对较快 |
参数类型 | 必须是确认的类型 | 不限类型 |