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


    1、C语言中的宏定义

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

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

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

    2、定义宏常量

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

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

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

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

    3、实例分析 

    宏定义分析     21-1.c

     1 #define ERROR -1  
     2 #define PATH1 "D:	est	est.c"  
     3 #define PATH2 D:	est	est.c  
     4 #define PATH3 D:	est  
     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
    ", s1);  
    20     printf("s2 = %d
    ", s2);  
    21     printf("m = %d
    ", m);  
    22     printf("d = %d
    ", 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
    ", PI);  
    19     printf("d = 5; a = %f
    ", 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 
    ", __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
    ", p[x]);  
    29     END  
    30       
    31     FREE(p);  
    32       
    33     LOG("End");  
    34       
    35     return 0;  
    36 }  

    11、小结

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

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

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

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

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

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

  • 相关阅读:
    【LeetCode】-- 73. Set Matrix Zeroes
    (第三场) A PACM Team 【dp,五维背包】
    POJ 1745 【0/1 背包】
    (第三场) H Diff-prime Pairs 【数论-素数线性筛法+YY】
    POJ 2299 【树状数组 离散化】
    树状数组 && 线段树应用 -- 求逆序数
    HDU 1698 【线段树,区间修改 + 维护区间和】
    HDU 1166 【线段树 || 树状数组,单点修改 维护区间和】
    (第二场)D Money 【dp贪心】
    (第二场)A Run 【动态规划】
  • 原文地址:https://www.cnblogs.com/lemaden/p/10127756.html
Copyright © 2020-2023  润新知