StdC--09 宏


 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  宏函数里井号的作用

 

  2.5 #if definded


 

 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 1
int 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     }

NOTE:  起别名

  typedef  char A[10];   //起别名

  #define  Bool  int    //只是替换

 

2.5 #if definded

  1 #include <stdio.h>
  2 
  3 int main()
  4 {
  5 #if defined(GONGCHANG)
  6     printf("100%%\n");
  7 #elif defined(JINGPIN)
  8     printf("jingpin\n");
  9 #else 
 10     printf("80%%\n");
 11 
 12 #endif
 13     return 0;
 14 }

 

练习:

1. 写一个ISLEAP(Y)的宏函数 判断闰年

 

posted @ 2014-09-14 23:48  wg934  阅读(197)  评论(0编辑  收藏  举报