C++面试常见问题——01预处理与宏定义
C++面试常见问题--------01预编译和宏的使用
C++预处理器
预处理器是一些指令,它将指示编译器在实际编译之前需要完成的预处理。预处理必须要在对程序进行词法与语义分析、代码生成与优化等通常的编译过程之前进行,经过预处理的程序不再包含之前的预处理命令。
所有的预处理器指令都以#号开始,并且前面不可以出现除了空白字符以外的字符。预处理器指令不是C++指令,所以不需要以 ;结尾。所有的C++程序实例都有预处理器指令 #include,这个宏用于把头文件包含在源文件中。
预处理器指令是C++统一规定的,但不是C++本身的组成部分,因此编译器无法对其进行识别和编译。
#define预处理
#define预处理器指令用于创建符号常量,这个符号常量被称为宏。在预编译时,所有的宏都会被替换成相应的字符,
#define DEBUG //DEBUG是宏 #define SQR(x) x*x //求两个数的平方,注意陷阱 int a = 2; cout<<SQR(a+1)<<endl; //在预编译时会被替换为 2+1*2+1 ,结果是5而不是9 //若真的想求两个数的平方可以做如下改写 #define SQR(x) ((x)*(x)) cout<<SQR(a+1)<<endl; //此时会得到正确答案9
参数宏
C++可以用#define来定义一个带有参数的宏。
#define MIN(a,b) (a<b?a:b)
内联函数(inline)实现起来比带参数的宏更加方便与安全,因此带参数的宏已经较少使用了。
条件编译
一下指令可以是程序有选择的对部分源码进行编译
#ifdef DEBUG //代码 #endif //如果之前已经在上面定义了DEBUG,就会执行上面的代码部分,否则在预处理阶段就会直接跳过该部分,编译器也不会对其进行编译。
#和##运算符
#和 ##预处理器运算符在C++和C中都可用:#用于将宏的代替文本转换为用引号引起来的字符串,##用于连接两个参数。
#define STR(X) #x cout<<STR(hello world)<<endl; //此时会直接输出hello world #define PEW(a,b) (int)(a##e##b) cout<<PEW(2,2)<<endl; //在预编译时被替换为2e2 ,最后结果是200
宏的优点
- 提高程序的可读性也方便修改
- 提高程序运行效率:宏在预处理时可以完成与函数调用相同的功能,同时又避免了函数的入栈与出栈操作,减小了系统开销,提高了运行效率。
- 宏是由预处理器处理的,通过字符串操作能轻松的完成很多编译器无法实现的功能。(宏定义中的#与##)
#include<iostream> using namespace std; #define FMALLY_CLASS(who) class fmally_##who{}; #define ADD(arg_a,arg_b) printf(#arg_a"+"#arg_b"=%d\n",arg_a+arg_b) int main(){ ADD(2,233); FMALLY_CLASS(mengziyue); fmally_mengziyue ziyue; FMALLY_CLASS(menglihua); fmally_menglihua lihua; }
宏的缺点
- 由于可能是直接嵌入的,代码量可能较多。
- 嵌套定义肯能引起可读性较差,并且容易出错。
- 对于带参数的宏来说,仅仅是字符的替换,且缺乏编译器的检测,可能称为错误的隐患。
参考链接:
相关推荐
choupiaoyi 2020-04-19
ddsdevgroup 2015-08-29
Joymine 2020-01-01
lvbin0 2012-07-03
Will0 2011-03-15
fengjing81 2019-11-07
liangds 2011-10-03
ericasadun 2012-01-04
wwater 2011-11-20
liangds 2012-06-03
mojianc 2019-06-27
87214551 2013-06-13
小南地带 2019-06-21
tubiebutu 2019-06-21
tubiebutu 2019-06-20
shi0 2011-09-29
fzhykx 2018-08-16