宏定义有两种:不带参数的宏定义和带参数的宏定义。
不带参数的宏定义
不带参数宏定义的一般形式为:
#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。