伪指令-宏定义:使用#define定义一个宏,宏体中包含命名空间信息导致vs大量报红,但编译和运行却正常

宏定义:使用#define伪指令定义一个宏

宏体中包含命名空间信息导致vs大量报红,但编译和运行却正常

宏分为不带参数的宏和带参数的宏。
在带参数的宏中,关键字#define后面出现的第一个连续字符序列作为宏名,剩下的部分作为宏体。
在这里插入图片描述

不带参数的宏中,关键字#define后面出现一个连续字符序列作为宏标识符。
在这里插入图片描述

宏定义有文件作用域,不论宏定义出现在文件中的哪个地方,函数体内,类型定义内部,命名空间等,在它后面的任何地方都可以引用宏。

注意点:
1、宏定义不是c/c++语句,伪指令都不是c/c++指令,所以它们后面都不加分号;,如果加上了分号,分号就会成为宏的一部分,而在编译器不会认为宏中有分号是问题,所以不会报错,但是在编译时,宏标识全部被替换为宏体,此时的分号经常为代码带来编译错误。
2、任何宏在预编译处理阶段都是简单的文本替换,没有类型检查和语法检查,这个工作由编译器进行,因此宏体内可能会隐藏语法错误,参数替换发生在宏扩展之前。
3、宏定义可以嵌套,前面的标志宏可以出现在后面的标志宏的宏体中。

例如:

#define PI 3.14
#define PI2 (2*PI)

4、宏无法被调试,因为宏不会进入符号表,编译器创建符号表的时候,宏已经被预编译器生成为中间文件了,编译过程中宏是已经不存在了的,因此宏替换带来的错误无法被定位到宏定义中,而是被定位到源程序中。
在这里插入图片描述
宏体中出现了啥都不会报错

如果恰好宏体中包括了命名空间,那编译器会无法查看到该命名空间中的关键字与函数等导致大面积的报红,但是编译和运行不会有问题,这个经常会让人犯迷糊

5、程序里被双引号括起来的宏或包含宏的字符串在预处理过程中不会被替换。
6、定义带参数的宏时,宏名和做括号之间不能出现空格,否则其参数就会变成宏体,编译器不会发现任何问题,但编译过程中对替换后的结果肯定是有影响的,并且肯定无法按照预先的思路运行。
7、带参数的宏体的各个形参都应该用括号括起来,除了单个形参,整个宏体也要用括号括起来。
8、宏体内不应该有自增自减的操作,更不能把带参数的宏当做函数使用,因为宏虽然没有函数调用的开销,却有生成重复代码,使可执行代码.exe的体积增大的影响。
9、inline函数不会完全取代宏,因为功能上inline和宏是有区别的,一个是函数一个不是函数,只是功能上有相近之处而已。
10、不需要的宏可以用#undef来取消它的定义。

在这里插入图片描述

**具体写宏的注意点:
1、宏定义应该简洁清晰,意义明确,例如WIN32,WINDOWS
2、宏名采用大写字符组成的单词或其缩写序列,各单词之间使用下划线_分隔
3、需要被公布的宏应当放置在头文件中或定义文件的顶部。
4、定义新类型名时使用typedef,不应该用宏,否则容易造成错误。

typedef int LEVEL;

5、宏常量尽量用const取代。

const int MAXLEVEL = 100;//最高等级为一百

6、对于较长的,使用频率较高的重复代码片段,建议使用函数或模板;较短的代码可以使用带参宏定义。
7、全局宏定义在全局,局部宏定义在局部,但尽量避免局部范围定义宏,否则损害程序清晰性。**

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值