📄 codetc13b.dat
字号:
1. 不带参数的宏定义
用一个指定的标识符(即名字)来代表一个字符串,它的一般形式为 #define 标识符字符串.
例如: #define PI 3.1415926
它的作用是指定用标识符PI来代替"3.1415926"这个字符串,在编译预处理时,将程序中在该命令以后出现的所有PI 都用"3.1415926"代替. 这种方法使用户能以一个简单的名字代替一个长的字符串,因此把这个标识符称为"宏名", 预编译时将宏名替换成字符串的过程为"宏展开".#define是宏定义的命令.
例题: #define PI 3.1415926
main()
{
float l,s,r,v;
printf("input radius:");
scanf("%f",&r);
l=2.0*PI*r;
s=PI*r*r;
v=3.0/4*PI*r*r*r;
printf("l=%10.f\ns=%10.4f\nv=%10.4f\n",l,s,v);
}
运行结果如下:
input radius: 4
l=25.1328
s=50.2655
v=150.7966
说明:(1) 宏名一般习惯用大写字母表示,以便与变量名相区别.但这并非规定,也可用小写字母.
(2) 使用宏名代替一字符串,可以减少程序中重复书写某些字符串的工作量.
例如,如果不定义PI代表3.1415926,则在程序中多处出现3.1415926,不仅麻烦,而且容易写错,用宏名代替, 简单不易出错,因为记住一个宏名要比记住一个无规律的字符串容易,而且在读程序时能立即知道它的含义 ,当需要改变某一个常量时,可以只改变#define命令行, 一改全改.
(3) 宏定义是用宏名代替一个字符串,也就是作简单的置换,不作正确性检查.如果写成: #define PI 3.l4159 即把数字1写成小写字母l,预处理时也照样代入,不管含义是否正确.也就是说预编译时不作任何语法检查. 只有在编译已被宏展开后的源程序时才会发现错误并报错.
(4) 宏定义不是C语句,不必在行末加分号.如果加了分号则会连分号一起进行置换.
如: #define PI 3.1415926;
area=PI*r*r;
经过宏展开后,该语句为 area=3.1415926;*r*r;
显然出现错误语法.
(5) #define命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束.通常,#define命 令写在文件件开头,函数之前,作为文件一部分,在此文件范围内有效.
(6) 可以用#undef命令终止宏定义的作域.例如:
#define G 9.8
main() |
{ |
. |
. G的有效范围
. |
} |
#undef G |
f1()
{
.
.
.
}
由于#undef的作用,使G的作用范围在#undef行处终止,因此在f1函数中,G不再代表9.8.这样可以灵活控制 宏定义的作用范围.
(7) 在进行宏定义时,可以引用已定义的宏名,可以层层置换.例如:
#define R 3.0
#define PI 3.1415926
#define L 2*PI*R
#define S PI*R*R
main()
{
printf("L=%f\nS=%f\n",L,S);
}
运行结果如下:
L=18.849556
S=28.274333
经过宏展开后,printf函数中的输出项L被展开为2*3.1415926*3.0,S展开为3.1415926*3.0*3.0,printf函 数调用语句展开为
printf("L=%f\nS=%f\n",2*3.1415926*3.0,3.1415926*3.0*3.0);
(8) 对程序中用双括号括起来的字符串内的字符,即使与宏名相同,也不进行置换.
(9) 宏定义是专门用于预处理命令的一个专用名词,它与定义变量含义不同,只作字符替换,不分配内存空间.
----
2. 带参数的宏定义
不是进行简单的字符串替换,还要进行参数替换.其定义的一般形式为: #define 宏名(参数表) 字符串
字符串中包含在括弧中所指定的参数.如:
#define S(a,b) a*b
area=S(3,2);
定义矩形面积S,a和b是边长.在程序中用了S(3,2),把3,2分别代替宏定义中形式参数a,b,即用3*2代替S(3,2).因此 赋值语句展开为 area=3*2;
对带参数的宏定义是这样展开置换的:在程序中如果有带参数的宏(如S(3,2)), 则按#define命令行中指定的字符串 从左到右进行置换.如果串中包含宏中的形参(如a,b),则 将程序语句中相应的实参代替形参,如果宏定义中的字符 不是参数字符(如a*b中的*号),则保留.这样就形成了置换的字符串.例题:
#define PI 3.1415926
#define S(r) PI*r*r
main()
{
float a,area;
a=3.6;
area=S(a);
printf("r=%f\narea=%f\n",a,area);
}
运行结果如下:
r=3.600000
area=40.715038
赋值语句area=S(a);经宏展开后为
area=3.1415926*a*a;
说明: (1) 对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符串代替#define命令行中的形参.在上例 语句中有S(a),在展开时,找到#define命令行中的S(r),将S(a)中的实参a代替宏定义中的字符串"PI*r*r" 中的形参r,得到PI*a*a.这是容易理解而且不会发生什么问题的.但是,如果有语句:area=S(a+b) 这时把 实参a+b代替PI*r*r中的 形参r,成为area=PI*a+b*a+b;请注意在a+b外面没有括弧,显然与程序设计者的 原意不符.原意希望得到 area=PI*(a+b)*(a+b);为了得到这个结果,应当在定义时,在字符串 中的形式参 数外面加一个括弧.
即 #defineS(r) PI*(r)*(r)在对S(a+b)进行宏展开时,将a+b代替r,就成了area=PI*(a+b)*(a+b);这就达 到了目的.
(2) 在宏定义时,在宏名与带参数的知弧之间不应加空格,否则将空格以后的字符都作为替代字符串的一部分. 例如,如果有 #define S (r)PI*r*r被认为S是符号常量(不带参数的宏名),它代表字符串"(r) PI*r*r". 如果在语句中有 area=S (a); 则被展开为: area=(r) PI*r*r (a) 显然不对了.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -