在C++中使用预处理器来“宏”化某些操作,这样我们就不用了一遍又一遍地手动输入代码了,我们可以用预处理器来在某种程度上帮助我们实现自动化。当我们编译C++代码时,首先发生的事情是:预处理器会过一遍C++所有你看到的语句,它以#符号开头(预处理指令符号),当预处理器评估完代码之后,之后会把评估后的代码给到编译器,进行实际的编译以及其他操作。所以说预处理阶段基本上是一个文本编辑阶段,在这个阶段我们可以确定什么样的代码会实际递给编译器。
示例:
#include <iostream>
int main()
{
std::cin.get();
}
#include <iostream>
#define WAIT std::cin.get()
int main()
{
WAIT;
}
上面两种代码实现效果相同。
#include <iostream>
#define LOG(x) std::cout << x << std::endl
int main()
{
LOG("Hello"); //std::cout << "Hello" << std::endl
return 0;
}
在VS中,编译器有两种模式:debug和release;
在debug模式下,编译器不会进行优化,会保留宏;但是在release模式下,编译器则会消除宏,即宏不可见。
#include <iostream>
#define _DEBUG //定义_DEBUG
#ifdef _DEBUG //假如有定义
#define LOG(x) std::cout << x << std::endl //定义的操作
#else //否则
#define LOG(x) //定义空操作
#endif //结束定义
int main()
{
LOG("Hello");
return 0;
}
以上代码在debug模式下可以实现宏定义,但是当切换到release模式下时,这个就被移除了,原因是在release模式下,在编译时,不会包含特定的代码(在前面已经为我们删除了宏定义的代码)。
#include <iostream>
#define _DEBUG 1
#if _DEBUG == 1
#define LOG(x) std::cout << x << std::endl
#elif defined(_RELEASE) //假如定义了_RELEASE的值为1(检测函数,检测括号里面的预定义是否存在,如果存在返回ture,不存在就返回false)
#define LOG(x)
#endif
int main()
{
LOG("Hello");
return 0;
}
使用#define _DEBUG 1
相比#define _DEBUG
,一方面可以不需要通过注释移除整个符号了或者直接删除符号,另一方面可以直接控制_DEBUG的值,可读性更好。
而且通过使用#if 0
(配合#endfi
)可以使得整个宏被禁用。
示例:使用反斜杆来写多行的宏
#include <iostream>
#define MAIN int main() \
{\
std::cin.get();\
}
MAIN
以上代码用反斜杆来转义换行符,等价于:
#include <iostream>
int main()
{
std::cin.get();
}
切记不能在反斜杠后面加空格,因为这样就会是对空格的转义,而不是换行。