1、C语言中的宏定义
#define是预处理器处理的单元实体之—
#define定义的宏可以出现在程序的任意位置
#define定义之后的代码都可以使用这个宏
2、定义宏常量
#define定义的宏常量可以直接使用
#define定义的宏常量本质为字面量下面的宏常量定义正确吗?
- #define ERROR -1
- #define PATHl "D:\test\test.c"
- #define PATH2 D:\test\test.c
- #define PATH3 D:\test\
- test.c
3、实例分析
宏定义分析 21-1.c
- #define ERROR -1
- #define PATH1 "D:\test\test.c"
- #define PATH2 D:\test\test.c
- #define PATH3 D:\test\
- test.c
- int main()
- {
- int err = ERROR;
- char* p1 = PATH1;
- char* p2 = PATH2;
- char* p3 = PATH3;
- }
预处理器不会进行语法检查只是简单的文本替换,即这些宏定义都正确
宏定义正确,不代表编译就正确
4、宏定义表达式
#define表达式的使用类似函数调用
#define表达式可以比函数更强大
#define表达式比函数更容易出错
下面的宏表达式定义正确吗?
- #define _SUM_(a, b) (a) + (b)
- #define _MIN_(a, b) ((a) < (b) ? (a) : (b))
- #define _DIM_(a) sizeof(a)/sizeof(*a)
5、实例分析
宏表达式分析 21-2.c
- #include <stdio.h>
- #define _SUM_(a, b) (a) + (b)
- #define _MIN_(a, b) ((a) < (b) ? (a) : (b))
- #define _DIM_(a) sizeof(a)/sizeof(*a)
- int main()
- {
- int a = 1;
- int b = 2;
- int c[4] = {0};
- int s1 = _SUM_(a, b);
- int s2 = _SUM_(a, b) * _SUM_(a, b);
- int m = _MIN_(a++, b);
- int d = _DIM_(c);
- printf("s1 = %d\n", s1);
- printf("s2 = %d\n", s2);
- printf("m = %d\n", m);
- printf("d = %d\n", d);
- return 0;
- }
分析test.i
6、宏表达式与函数的对比
宏表达式被预处理器处理,编译器不知道宏表达式的存在
宏表达式用“实参“完全替代形参,不进行任何运算
宏表达式没有任何的“调用”开销
宏表达式中不能出现递归定义#define _SUM_(n) ((n > 0)? (_SUM_(n-1) + n): 0)
int s = _SUM_(10);
7、有趣的问题
宏定义的常量或表达式是否有作用域限制?
下面的程序合法吗?
- void def()
- {
- #define PI 3.1415926
- #define AREA(r) r*r*PI
- }
- double area(double r)
- {
- return AREA(r);
- }
8、实例分析
宏的作用域分析 21-3.c
- #include <stdio.h>
- void def()
- {
- #define PI 3.1415926
- #define AREA(r) r * r * PI
- }
- double area(double r)
- {
- return AREA(r);
- }
- int main()
- {
- double r = area(5);
- printf("PI = %f\n", PI);
- printf("d = 5; a = %f\n", r);
- return 0;
- }
没有类型和作用域概念
9、强大的内置宏
10、实例分析
宏使用综合示例 21-4.c
- #include <stdio.h>
- #include <malloc.h>
- #define MALLOC(type, x) (type*)malloc(sizeof(type)*x)
- #define FREE(p) (free(p), p=NULL)
- #define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s)
- #define FOREACH(i, m) for(i=0; i<m; i++)
- #define BEGIN {
- #define END }
- int main()
- {
- int x = 0;
- int* p = MALLOC(int, 5);
- LOG("Begin to run main code...");
- FOREACH(x, 5)
- BEGIN
- p[x] = x;
- END
- FOREACH(x, 5)
- BEGIN
- printf("%d\n", p[x]);
- END
- FREE(p);
- LOG("End");
- return 0;
- }
宏的强大之处,这些宏都是无法用函数替代的
11、小结
预处理器直接对宏进行文本替换
宏使用时的参数不会进行求值和运算
预处理器不会对宏定义进行语法检查
宏定义时出现的语法错误只能被编译器检测
宏定义的效率高于函数调用
宏的使用会带来—定的副作用