黑马程序员技术交流社区

标题: 宏定义#define [打印本页]

作者: 洪吉童    时间: 2015-9-29 22:57
标题: 宏定义#define
本帖最后由 洪吉童 于 2015-9-29 23:02 编辑

被定义为“宏”的标识符称为“宏名”(如:#define    MAN    1  其中的MAN被称为宏名)。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。宏定义是由源程序中的宏定义命令完成的。宏代换是由预处理程序自动完成的。
宏定义分为无参数的宏定义和有参数的宏定义。
(1):无参数的宏定义
无参数的宏定义。一般形式为:#define 标识符 字符串,如:#define    MAN    1,下面我们从程序里面来看一下无参数#define的作用
  1. #include"stdio.h"
  2. #include"stdlib.h"
  3. #define   MAN           1         //将1宏定义为MAN
  4. #define   WOMAN         0         //将0宏定义为WOMAN
  5. void main()
  6. {
  7.    int a=2,b=0,c=0;
  8.    b=a+MAN;                       //等价于b=a+1;
  9.    c= a+WOMAN;                    //等价于c= a+0;
  10.    printf("%d,%d\n",b,c);           //打印运算后的b,c
  11.   
  12.     system("pause") ;             //DOS窗口停留  
  13. }
复制代码
程序打印结果为:3,2
从程序中可以很明白的看出,程序中所有出现的“宏名”,都用宏定义中的字符串去简单的代换。那么,这个字符串除了上例中的常数外还可以是些什么呢?下面再看一段程序:
  1. #include"stdio.h"
  2. #include"stdlib.h"
  3. #define   MAN           A         //将A宏定义为MAN
  4. #define   WOMAN         B         //将B宏定义为WOMAN
  5. void main()
  6. {
  7.    //int a=2,b=0,c=0;
  8.   // b=a+MAN;                       //等价于b=a+1;
  9.   // c= a+WOMAN;                    //等价于c= a+0;
  10.    printf("%c,%c\n",MAN,WOMAN);           //打印MAN,WOMAN
  11.   
  12.     system("pause") ;             //DOS窗口停留  
  13. }
复制代码
我们的目的是想打印出字符A和B,但是这段程序看官可以试一试,会报错的:error C2065: 'A' : undeclared identifier   error C2065: 'B‘ : undeclared identifier,未定义
这样定义的A和B就相当于程序中的普通变量,相当于打印
printf("%c,%c\n",A,B);// 然而A,B在函数中根本没有定义,
所以需要将变量定义并赋值
  1. #include"stdio.h"
  2. #include"stdlib.h"
  3. #define   MAN           A         //将A宏定义为MAN
  4. #define   WOMAN         B         //将B宏定义为WOMAN
  5. void main()
  6. {
  7.    //int a=2,b=0,c=0;
  8.   // b=a+MAN;                       //等价于b=a+1;
  9.   // c= a+WOMAN;
  10.         //等价于c= a+0;
  11.         char A='A',B='B'; //将变量赋值
  12.    printf("%c,%c\n",MAN,WOMAN);           //打印MAN,WOMAN
  13.   
  14.     system("pause") ;             //DOS窗口停留  
  15. }
复制代码
这样就如我们所愿,打印出A,B字母。其实这样做打印AB是画蛇添足,最好的方式是用宏定义直接定义:
#define   MAN           'A '        //将A宏定义为MAN
#define   WOMAN         'B '        //将B宏定义为WOMAN
到现在我们知道这个一般定义形式(#define 标识符 字符串)中的字符串可以是常数,字符(其实字符也是常数),变量(程序中需要定义),当然这个字符串也可以是由变量和常数或字符组成的表达式,如(a+b),a+1,a+'C'等等,下面看程序举例:
  1. #include"stdio.h"
  2. #include"stdlib.h"
  3. #define   MAN            a+b         
  4. #define   WOMAN         (a+b)         
  5. void main()
  6. {
  7.    int a=2,b=3,c=4,d=0,e=0;
  8.    d=c*MAN;                       //等价于 d=c*a+b;
  9.    e= c*WOMAN;                     //等价于e=c*(a+b);
  10.    printf("%d,%d\n",d,e);           //打印d,e
  11.   
  12.     system("pause") ;             //DOS窗口停留  
  13. }
复制代码
程序运行结果为:11,20
所以要注意有括号与无括号的区别,宏定义不生产运算,只是一个字符串的搬运工。
(2):有参数的宏定义

有参数的宏定义跟功能函数类似,但不完全一样,前者是在预处理的时候将程序中出现的宏名全部替换其为对应的字符串,程序运行时不分配新的函数内存空间,而后者是程序运行时要分配相应函数内存空间。下面来看看有参数的宏定义的例子:

  1. #include"stdio.h"
  2. #include"stdlib.h"
  3. #define   MAN(x,y)            (x+y*2)              
  4. void main()
  5. {
  6.    int a=2,b=3,c=4,d=0;
  7.    d=c*MAN(a,b);                       //等价于 d=c*(a+b*2);
  8.    printf("%d\n",d);           //打印d
  9.   
  10.     system("pause") ;             //DOS窗口停留  
  11. }
复制代码
打印结果为:32


函数预处理的时候将程序中出现的MAN(a,b)替换为(a+b*2),这是替换而不是函数中的值传递,虽然结果一样,但是原理不一样。

(3)总结:

“宏定义”又称为“宏代换”或“宏展开”,顾名思义,就是将程序中的宏名代换或展开为相应的字符串(常数,表达式等)。












欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2