服务器之家

服务器之家 > 正文

C语言宏定义使用分析

时间:2020-11-13 11:54     来源/作者:C语言中文网

1、如何区分宏定义中的“宏名称”和“宏字符串”?对于带参数的宏又该注意什么?

在宏定义中,“宏名称”和“宏字符串”是通过“空格”来区分的。编译器在处理时宏定义时,首先从“#define”后第一个空格开始读取字符串,直到遇见下一个空格为止,两个空格之间的字符串为“宏名称”,确定好“宏名称”之后,本行的所有其他字符串都为“宏字符串”。图示:#define + N个空格(1 < N) + 宏名称(中间没有空格) + N个空格(1 < N) + 宏字符串(直到本行结束)。这里讲到的都是一行之内的宏定义,如果跨越多行则用“\”字符进行“续行”,本质上可以当做一行来对待。

对于“带参数宏”,宏名称和“( )”之间不能有空格,否则就变成了“无参数宏”(根据上面的原则)。而且当“无参数宏”和“带参数宏”的名字相同时,“无参数宏”会屏蔽掉“带参数宏”,即使以“带参数宏”的方式调用,也行不通。

试验内容及结果

C语言宏定义使用分析C语言宏定义使用分析

实验分析

可以看到“#define PI  3.1415”和“#define P I 689”分别是两个不同的宏定义“PI”和“P”;"G(4)"被“(X) (2*X) (4)”替换掉;当调用“F(4)”时,系统并没有替换成“2*4”,而是替换成了“123(4)”,说明“#define F  123”完全屏蔽掉了“#define F(X)  (2*X)”,当注释掉“#define  F  123”后"#define F(X)  (2*X)"可以正常工作。因此,在进行宏定义时,要密切关注空格的影响,并且“带参数宏”和“无参数宏”的名称一定不能相同,否则会出现混乱。但是,在宏调用时空格并不影响效果,例如F(3)和F (3)效果相同(F(X)是带参数宏)。

2、宏和函数在使用方式和效果上有何异同?

在宏定义时,要善于利用括号对变量进行封装,把每个参数都括起来,预防出现与优先级有关的问题;同时整个结果表达式也应该括起来,以防止当宏用于一个更复杂的表达式时可能出现问题。尽量提高宏的可靠性,。例如:“#define ABS(x)  (((x) > 0) ? (x) : (-x))”的可靠性要远远优于“#define ABS(x)  x > 0 ? x : -x”,可以以ABS(a-b)来进行试验。

在宏调用时,如果有自增(++)或自减(--)操作符,一定要注意很可能会产生副作用。因为宏在替换时,如果变量出现了多次,就相当于自增或自减操作进了多次,这个跟函数调用是完全不同的,函数调用中形参会复制实参的数值,并对形参进行操作并不会影响实参,而宏调用就是直接多次修改实参。例如:a = 5; "ABS(a++) “展开后就变成“(((a++) > 0) ? (a++) : (-a++))”,操作完成后”a = 7“而不是”a = 6“;当写成函数就完全不用担心这个问题。

如果在宏调用时,进行了了多层嵌套调用,则宏展开后会产生非常庞大的表达式,而且相当复杂;函数调用则不会出现这种情况。

3、宏和类型定义typedef的区别

由于宏的本质就是替换,所以可以对变量类型进行一层封装,利用该封装做变量定义,这样做的好处是增加可移植性,当修改时只需要改动宏定义即可。例如:

复制代码 代码如下:

MY_TYPE a;
MY_TYPE b,c,d;


但是最好不要这么用,因为我们有typedef,它是专门进行类型定义的。而且,使用类型定义会使代码更加通用一些,避免一些深层的问题。例如:

复制代码 代码如下:

typedef uint_8 * MY_TYPE2

MY_TYPE1 a,b;
MY_TYPE2 c,d;

分析

 

从概念上看,MY_TYPE1 和 MY_TYPE2 完全相同,都是指向uint_8的指针,但是当我们声明多个变量时,就出现问题了。它们分别被扩展成了:

复制代码 代码如下:

uint_8 *a,b;
MY_TYPE2 c,d; //因为MY_TYPE2已经是一种类型了


可以看到,本来想定义两个指针变量a,b;现在却变成了一个指针变量a和一个整型变量b,这不是我们想要的。而MY_TYPE2本身就是一种类型(自定义)了,故c,d都是指针类型,符合预期。所以,如果想自定义类型,果断选择 ”typedef“ 放弃宏定义,否则吃亏的是自己。

标签:

相关文章

热门资讯

2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
Intellij idea2020永久破解,亲测可用!!!
Intellij idea2020永久破解,亲测可用!!! 2020-07-29
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享
歪歪漫画vip账号共享2020_yy漫画免费账号密码共享 2020-04-07
电视剧《琉璃》全集在线观看 琉璃美人煞1-59集免费观看地址
电视剧《琉璃》全集在线观看 琉璃美人煞1-59集免费观看地址 2020-08-12
最新idea2020注册码永久激活(激活到2100年)
最新idea2020注册码永久激活(激活到2100年) 2020-07-29
返回顶部