一、基本概念:
预处理器是文本处理器,他在编译前对文本进行预处理。
所有的预处理指令都以#开头,只有空格允许在预处理指令之前存在。
预处理指令不会以;结尾,他不是c++语句。
二、基本指令
预处理器包含的指令有如下几种
#define | #error | #import | #undef |
#elif | #if | #include | #using |
#else | #ifdef | #line | #endif |
#ifndef | #pragma |
由于在项目中暂时只需要用到:
#ifdef / #ifndef / #else / #endif / #define / #undef 这几个宏指令
其他指令可以通过点击链接观看官方文档。
1.#define
包含简单宏定义和带参数的宏定义,这里仅举例简单宏定义。
格式:#define Macro_name replace_text
比如:
#include <iostream>
using namespace std;
#define PI 3.14159
int main ()
{
cout << "Value of PI :" << PI << endl;
return 0;
}
结果为:“Value of PI”
———————————————————————
要理解define而不出错,最重要的是把握直接替换
#define Square(x) x*x
float temp = Square(3+3);
//程序的本意可能是要计算6*6=36,但由于宏定义执行的是直接替换,本身并不做计算,因此实际的结果为 3+3*3+3=15
//想要避免这个问题,只需要修改如下:
#define Square(x) ((x)*(x))
上面这个例子中不会直接给3+3添加括号,而是直接替换过去。
比较好的解决方法是在define中对替换的参数尽量都添加括号。
————————————————————
尽管如此,以下的代码也无法得到预期结果:
#define Square(x) x*x
int a = 3;
float temp = Square(++a);
最终运行结果会变为4*5,而不是4*4
解决办法是尽量不在替换中使用++和--
2.#ifdef / #endif / #ifndef / #else
主要功能是用于判断该宏定义是否已经存在
若存在则true,不存在则为false。
——————————————————
#ifdef要和#endif配套使用,划定作用范围。
如果判断为true,则进入作用范围执行代码。如果判断为false,则跳出该作用范围
______________________________________
#ifndef是与#ifdef相反的指令,同样要和#endif配套使用。
若存在该宏定义则为false,不存在则为true
下面的代码可以防止一个头文件被重复包含:
#ifndef BODYDEF_H
#define BODYDEF_H
//头文件内容
#endif
#ifdef和#endif指令之间可以出现任意数量的#elif指令,但最多允许一个#else指令。该#else伪指令,如果存在的话,必须是#endif之前的最后一个指令.
#ifdef ABC
// ... codes while definded ABC
#elif (CODE_VERSION > 2)
// ... codes while CODE_VERSION > 2
#else
// ... remained cases
#endif // #ifdef ABC
4.#undef
删除先前定义的标识符
#define WIDTH 80
#define ADD( X, Y ) ((X) + (Y))
.
.
.
#undef WIDTH
#undef ADD
参考:
C++宏定义:https://blog.csdn.net/shuzfan/article/details/52860664
详解宏定义(#define)https://blog.csdn.net/yanggangclcsdn/article/details/49704089
C++预处理器:https://www.runoob.com/cplusplus/cpp-preprocessor.html
Preprocessor directives:https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-directives?view=vs-2019