C语言允许带有参数的宏。类似函数,在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带有参数的宏,预处理时,应先用实参替代形参,再将宏展开。带参数的宏定义的一般形式如下:
#define标识符(形参表)替换列表
形参表包含一个或多个参数,参数之间用逗号分隔,替换列表中应该含有形参名。
带参数宏的调用的一般形式如下:
宏名(实参表)
例如:
在宏调用时,用实参5去代替形参x,经预处理宏展开后的语句为“y=5*5+6”。
【例10-4】用带参数的宏求两个数中较大的数。
程序运行结果如图10-2所示。
关于带参数宏定义的使用,还应该注意以下几点。
(1)宏名和形参表之间不能有空格,否则,C语言编译系统将空格以后的所有字符均作为替代字符串,而将该宏视为无参数宏。
(2)带参数宏定义中,为了避免当实际参数本身是表达式时出现起的宏调用的错误,在定义时最好将替换列表中出现的形式参数用括号括起来。
(www.xing528.com)
图10-2 例10-4的运行结果
【例10-5】
例10-5 运行视频
程序运行结果如图10-3所示。
图10-3 例10-5的运行结果
通过对结果的分析可以看出,第一个结果是正确的,而第二个结果是错误的。语句“area2=S(a+b);”被宏替换后变为“area2=3.1415926*a+b*a+b;”,这显然不是求半径为a+b的圆面积所需的表达式,所以结果是错误的。为避免出现这种问题,可以将宏定义改为“#define S(r)PI*(r)*(r)”,这样宏替换后的结果为“area2=3.1415926*(a+b)*(a+b);”。
(3)带参数宏和带参数函数虽然很相似,但两者间有本质的区别。
①函数调用时,先求出实参表达式的值,然后带入形参。而使用带参的宏只是进行简单的字符替换。
②函数调用是在程序运行时处理的,分配临时的内存单元;而宏展开则是在编译时进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。
③对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时带入指定的字符即可。宏定义时,字符串可以是任何类型的数据。
④宏替换不占运行时间,只占编译时间;而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。