rainbowzc

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

宏定义有两种:不带参数的宏定义和带参数的宏定义。

不带参数的宏定义
不带参数宏定义的一般形式为:

#define  宏名 字符串
#define  PI  3.1415926
 main() 
{
float  area, r;
printf (“area=%f”,PI*r*r);
}
以上程序中以宏名PI来替换字符串3.1415926,这样做的好处是显然的,一是可以简化程序,二是便于修改。
说明:
1. 宏定义一般写在程序的开头。
2. 宏名的命名规则同变量名,一般习惯用大写字母如PI,以区别程序中的变量。
3. 宏名的有效范围是从宏定义开始到本源程序文件结束,或遇到预处理命令#undef时止。
#define  PI  3.14
宏PI的有效范围
 main( )
 {
 . . .
 }
  #undef  PI
f1( )
{
. .
}
4. 宏定义不但可以定义常量,还可以定义c语句和表达式等。另外宏定义还可以嵌套定义。即在宏定义中的字符串
以引用被另一个宏定义所定义的宏名。  #define  PI  3.14
#define  R  30
 #define  AREA  PI *R*R
 #define  PRN  printf(“/n”); 
     main()
     {
        printf(“%lf”,AREA);
       PRN
     }
5. 宏代换只是指定字符串的简单替换,不作任何语法检查,只是在编译已被展开的源程序时,才可能报错。如后面
分号,则连分号一起置换。如上例第四句。
6.不能替换双引号中与宏名相同的字符串,也不能用户标识符中与宏名相同的成分。如printf(“PI”)中的PI,和PIR
的PI与前面定义过的宏名相同,但它们不能用3.14来替换。
带参数的宏定义            
带参数的宏定义的一般形式如下:
 #define  宏名(形参表)  字符串
  例如  #define  M(a,b)  a*b
                 . . .
                 s=M(3,5);  
     说明:
1. 上例宏调用的结果是s=3*5=15,即用实参3,5来代替形参a,b,实参个数要与形参个数相同,而没有类型要求,
点与函数调用不同,函数调用要求参数类型一致。
2. 如宏调用改为s=M(3+2,5+1),则调用为s=3+2*5+1,显然与我们希望的结果不符,这时应将宏定义改为 
#define  M(a,b)  (a)*(b)
这样才得到我们希望的结果s=(3+2)*(5+1)。
3. 如宏调用改为s=3/M(3+2,5+1),则替换后s=3/(3+2)*(5+1),                   也与
们希望的结果不符,这时应将宏定义改为
#define  M(a,b)  ((a)*(b))
这样才得到我们希望的结果s=3/((3+2)*(5+1))。通过以上两点是想让大家注意宏定义中圆括号的使用。
4. 宏定义中有双引号括起来的字符串常量中,含有形参,则在做宏替换时实参不能替换此双引号中的形参。如:          
#define  ADD(m)  printf(“m=%d/n”,m)
 用ADD(x+y);语句调用,结果为printf(“m=%d/n”,x+y);
 如要解决此问题则可在形参前加一“#”号,变为如下形式:
#define  ADD(m)  printf(#m“=%d/n”,m)
则调用ADD(x+y);语句后,结果就会变为printf(“x+y=%d/n”,x+y);
5. 如宏定义包含双“##”号,则宏替换时将双“##”号去掉,并将其前后字符串合在一起。例如:
#define  S(a,b)  a##b
当调用S(define ,5);语句时,宏展开为define5。

 

 

 

 

posted on 2006-08-16 21:46  ct  阅读(1513)  评论(0编辑  收藏  举报