第21课 - 宏定义与使用分析

时间:2022-08-30 07:59:50

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. }  


                第21课 - 宏定义与使用分析

                第21课 - 宏定义与使用分析


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


                第21课 - 宏定义与使用分析

                                        宏定义正确,不代表编译就正确

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. }  


                第21课 - 宏定义与使用分析


分析test.i

                第21课 - 宏定义与使用分析


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

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

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

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

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

#define _SUM_(n) ((n > 0)? (_SUM_(n-1) + n): 0) 

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.  }   
  11.   
  12.    
  13.   
  14.    


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. }  

                第21课 - 宏定义与使用分析

                第21课 - 宏定义与使用分析

                                没有类型和作用域概念


9、强大的内置宏

                    第21课 - 宏定义与使用分析

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(int, 5);  
  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. }  


                第21课 - 宏定义与使用分析

                            宏的强大之处,这些宏都是无法用函数替代的


11、小结

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

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

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

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

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

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