首页 > 代码库 > C-08宏

C-08宏


 Hightlight

  1. 宏

    1.1 ifdef

    2.2 解决重复引入头文件问题

    2.3 C语言中预先定义好的一些宏

    2.4 带参宏

      2.4.1  宏函数问题1:  参数不带括号情况

      2.4.2  宏函数问题2:  式子不带括号情况

      2.4.3  宏函数问题3:  ++ —— 赋值

      2.4.4  宏函数问题4:  无类型检查

      2.4.5  宏函数里井号的作用


 

 1. 宏

  1.1 ifdef

  #ifndef    H    //如果没定义过H 那就定义H
  例如

 21 #ifdef H 22 #ifndef H 23     #define H "123" 24 #endif 

   NOTE: gcc-E 可以看到预处理之后的效果

 

  2.2 解决重复引入头文件问题

  c语言中头文件定义模板    确保其中的内容不会被定义两次, 插入多份也没关系

#ifndef VX#define VX 1int x=3;#endif

    -->参考stdio.h头文件        /usr/include/stdio.h头文件

  按照这种做法 下面例子编译通过

  1 /* header.h */  2 #ifndef HEADER_H  3 #define HEADER_H 1  4 struct s {};  5 typedef struct s s;  6 #endif //HEADER_H
 1 /* header.c  */  2   3 #include <stdio.h>  4 #include "header.h"  5 #include "header.h"  6 //#include "func.h"  7 //#define Vx 1  8   9 #ifndef VX 10 #define VX 1 11 int x=2; 12 #endif 13  14 #ifndef VX 15 int x=3; 16 #endif 17  18 int main() 19 {    20     s a; 21     printf("%d\n",x); 22     return 0; 23     }

 

   2.3 C语言中预先定义好的一些宏

  1 #include <stdio.h>  2 int main()  3 {  4     __FILE__  5     __LINE__  6     __DATE__  7     __TIME__  8     __STDC__  9     return 0; 10     }

  

 

  2.4 带参宏(宏函数)

   基本的宏函数

  1 #include <stdio.h>  2  3 #define SWAP(T,x,y){T t=x;x=y;y=t;}  4  5 int main()  6 {  7     int a =10,b=20;  8     double c = 12.3, d=45.6;  9     SWAP(int, a,b); 10     SWAP(double, c, d); 11 12     printf("a=%d , b=%d\n",a,b); 13     printf("c=%g,d=%g\n",c,d); 14 15     return 0; 16     }

   预编译后的效果

 int main(){ int a =10,b=20; double c = 12.3, d=45.6; {int t=a;a=b;b=t;}; {double t=c;c=d;d=t;}; printf("a=%d , b=%d\n",a,b); printf("c=%g,d=%g\n",c,d); return 0; }

 
   宏函数问题-----面积计算的结果不对

   1 #include <stdio.h>  2  3 #define SWAP(T,x,y){T t=x;x=y;y=t;}  4 #define MAX(x,y) x<y?y:x  5 #define PI 3.14159  6 #define AREA(r) PI*r*r  7 int main()  8 {  9     int a =10,b=20; 10     double c = 12.3, d=45.6; 11     SWAP(int, a,b); 12     SWAP(double, c, d); 13 14     printf("a=%d , b=%d\n",a,b); 15     printf("c=%g,d=%g\n",c,d); 16 17     printf("%d\n",MAX(a,b)); 18     printf("%g\n",AREA(a+b)); 19     return 0; 20     } 

   面积计算的结果:

  

  查看预编译进行debug

  

  解决办法 带参数的宏永远要对宏的参数加括号!

 6 #define AREA(r) PI*(r)*(r)

  预编译的结果:

   printf("%g\n",3.14159*(a+b)*(a+b));

 

  宏函数问题2-----求和不一样

  1 #include <stdio.h>  2   3 #define SWAP(T,x,y){T t=x;x=y;y=t;}  4 #define MAX(x,y) x<y?y:x  5 #define PI 3.14159  6 #define AREA(r) PI*(r)*(r)  7   8 int main()  9 { 10     int a =10,b=20; 11     double c = 12.3, d=45.6; 12     int e=50, f=60; 13  14     SWAP(int, a,b); 15     SWAP(double, c, d); 16  17     printf("a=%d , b=%d\n",a,b); 18     printf("c=%g,d=%g\n",c,d); 19  20     printf("%d\n",MAX(a,b)+MAX(e,f)); 21     printf("%g\n",AREA(a+b)); 22     return 0; 23     }

  和为50, 预编译debug发现:

printf("%d\n",a<b?b:a+e<f?f:e);

  在写宏函数时候整个式子要用括号括起来避免冲突

 

  宏函数问题3: 带++ ——和赋值的式子 作为宏参数

     printf("%d\n",MAX(++a,++b));执行结果:
22
预编译结果:printf(
"%d\n",(++a<++b?++b:++a));

 

  调用宏函数时候不要使用带++ ——和赋值的式子 作为宏参数

 

  宏函数问题4: 没有类型检查

 

  宏函数里井号的作用:

    1). 单井号:把参数编程对应的字符串

#define STR(x) puts(#x)STR(hello);打印出来hello

    2). 双井号:拼接标示符

 1 #include <stdio.h>  2   3 #define SWAP(T,x,y){T t=x;x=y;y=t;}  4 #define MAX(x,y) (x<y?y:x)  5 #define PI 3.14159  6 #define AREA(r) PI*(r)*(r)  7 #define STR(x) puts(#x)  8   9 void welcomestudent(){printf("welcome every body.\n");} 10 void welcometeacher(){printf("welcome all teacher\n");} 11 #define welcome(who) welcome##who() 12  13 int main() 14 { 15     int a =10,b=20; 16     double c = 12.3, d=45.6; 17     int e=50, f=60; 18  19     SWAP(int, a,b); 20     SWAP(double, c, d); 21  22     printf("a=%d , b=%d\n",a,b); 23     printf("c=%g,d=%g\n",c,d); 24  25     printf("%d\n",MAX(a,b)+MAX(e,f)); 26     printf("%g\n",AREA(a+b)); 27     printf("%d\n",MAX(++a,++b)); 28  29     STR(hello); 30  31     welcome(student); 32     welcome(teacher); 33     return 0; 34     }


练习: 写一个ISLEAP(Y)的宏函数 判断闰年

 

C-08宏