C语言-宏定义与使用分析

1、C语言中的宏定义

  #define是预处理器处理的单元实体之— 

  #define定义的宏可以出现在程序的任意位置 

  #define定义之后的代码都可以使用这个宏

 

2、定义宏常量

  #define定义的宏常量可以直接使用 

  #define定义的宏常量本质为字面量 

下面的宏常量定义正确吗?

1 #define ERROR -1   
2   
3 #define PATHl "D:\test\test.c"   
4   
5 #define PATH2 D:\test\test.c   
6   
7 #define PATH3 D:\test\   
8 test.c  

3、实例分析 

宏定义分析     21-1.c

 1 #define ERROR -1  
 2 #define PATH1 "D:\test\test.c"  
 3 #define PATH2 D:\test\test.c  
 4 #define PATH3 D:\test\  
 5 test.c  
 6   
 7 int main()  
 8 {  
 9     int err = ERROR;  
10     char* p1 = PATH1;  
11     char* p2 = PATH2;  
12     char* p3 = PATH3;  
13 }  

预处理器不会进行语法检查只是简单的文本替换,即这些宏定义都正确!!但编译器会报错!!

4、宏定义表达式

  #define表达式的使用类似函数调用 

  #define表达式可以比函数更强大 

  #define表达式比函数更容易出错 

下面的宏表达式定义正确吗?

  

1 #define _SUM_(a, b) (a) + (b)   
2   
3 #define _MIN_(a, b) ((a) < (b) ? (a) : (b))   
4   
5 #define _DIM_(a) sizeof(a)/sizeof(*a)  

5、实例分析

宏表达式分析     21-2.c

 1 #include <stdio.h>  
 2   
 3 #define _SUM_(a, b) (a) + (b)  
 4 #define _MIN_(a, b) ((a) < (b) ? (a) : (b))  
 5 #define _DIM_(a) sizeof(a)/sizeof(*a)  
 6   
 7   
 8 int main()  
 9 {  
10     int a = 1;  
11     int b = 2;  
12     int c[4] = {0};  
13   
14     int s1 = _SUM_(a, b);  
15     int s2 = _SUM_(a, b) * _SUM_(a, b);  
16     int m = _MIN_(a++, b);  
17     int d = _DIM_(c);  
18   
19     printf("s1 = %d\n", s1);  
20     printf("s2 = %d\n", s2);  
21     printf("m = %d\n", m);  
22     printf("d = %d\n", d);  
23   
24     return 0;  
25 }  

6、宏表达式与函数的对比

  宏表达式被预处理器处理,编译器不知道宏表达式的存在 

  宏表达式用“实参“完全替代形参,不进行任何运算 

  宏表达式没有任何的“调用”开销 

  宏表达式中不能出现递归定义

1 #define _SUM_(n) ((n > 0) ? (_SUM_(n-1) + n): 0) //error
2  
3 int s = _SUM_(10);

7、有趣的问题

宏定义的常量或表达式是否有作用域限制? 

下面的程序合法吗?

 1 void def()   
 2 {  
 3     #define PI 3.1415926   
 4     #define AREA(r) r*r*PI  
 5 }  
 6   
 7 double area(double r)   
 8 {  
 9     return AREA(r);  
10 }   

8、实例分析

宏的作用域分析     21-3.c

 1 #include <stdio.h>  
 2   
 3 void def()  
 4 {  
 5     #define PI 3.1415926  
 6     #define AREA(r) r * r * PI  
 7 }  
 8   
 9 double area(double r)  
10 {  
11     return AREA(r);  
12 }  
13   
14 int main()  
15 {  
16     double r = area(5);  
17   
18     printf("PI = %f\n", PI);  
19     printf("d = 5; a = %f\n", r);  
20       
21     return 0;  
22 }  

9、强大的内置宏

  
  __LINE__ 表示当前行号,整型值
  __FILE__ 表示当前文件名,字符串类型
  __DATE__ 编译的日期,字符串类型
  __TIME__ 编译的时间,字符串类型
  __STDC__ 预定义的宏

10、实例分析

宏使用综合示例     21-4.c

 1 #include <stdio.h>  
 2 #include <malloc.h>  
 3   
 4 #define MALLOC(type, x) (type*)malloc(sizeof(type)*x)  
 5   
 6 #define FREE(p) (free(p), p=NULL)  
 7   
 8 #define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s)  
 9   
10 #define FOREACH(i, m) for(i=0; i<m; i++)  
11 #define BEGIN {  
12 #define END   }  
13   
14 int main()  
15 {  
16     int x = 0;  
17     int* p = MALLOC(int5);  
18       
19     LOG("Begin to run main code...");  
20       
21     FOREACH(x, 5)  
22     BEGIN  
23         p[x] = x;  
24     END  
25       
26     FOREACH(x, 5)  
27     BEGIN  
28         printf("%d\n", p[x]);  
29     END  
30       
31     FREE(p);  
32       
33     LOG("End");  
34       
35     return 0;  
36 }  

11、小结

  预处理器直接对宏进行文本替换 

  宏使用时的参数不会进行求值和运算 

  预处理器不会对宏定义进行语法检查 

  宏定义时出现的语法错误只能被编译器检测 

  宏定义的效率高于函数调用 

  宏的使用会带来—定的副作用

posted @ 2018-12-16 19:51  lemaden  阅读(704)  评论(0编辑  收藏  举报