在我的项目代码中,我发现有人在代码中使用了 #ifdef
和 #if
。我想知道使用它们的目的是什么?据我所知,它对预处理器说不会在该代码中执行任何操作。下面的代码给出了两个使用它们的例子。我试图找到 TEST_PURPOSE
(真/假)的定义,但找不到。从下面的代码中,如何在 #ifdef TEST_PURPOSE
里面做一些事情?我正在使用视觉工作室 2012
#ifdef TEST_PURPOSE
int i=1;
printf("Something %d,"i);
#endif
#if 0
int i=1;
printf("Something %d,"i);
#endif
原文由 Jame 发布,翻译遵循 CC BY-SA 4.0 许可协议
#ifdef
的含义是,只有定义了前面提到的预处理器宏,块内的代码才会被包含在编译中。类似#if
意味着只有当表达式的计算结果为真时才会包含块(当用0替换出现在表达式中的未定义宏时)。这里重要的一点是预处理器在编译之前处理源代码,如果不包含该块,则实际编译器根本不会对其进行解析。这是结构的一个重要特征。
现在由于某种原因 C/C++ 使用它。这些语言以线性顺序处理文件,因此出现在源代码下方的内容尚不为人所知,而更重要的内容则出现在其他源文件中。这意味着没有(好的)自动方式可以在另一个源文件中引用一个源文件中的符号,特别是如果您希望类型正确。这意味着您必须拥有原型和
extern
定义才能引用这些。此外,如果两个源文件应该共享数据类型(struct
s 和enum
s),则必须这样做。为了使其更实用,可以将它们放在每个源文件可以
#include
的头文件中(这基本上意味着将头文件插入到实际编译器看到的内容中)。这反过来很容易导致一个头文件包含另一个头文件的情况,您可能会遇到同一个文件被包含两次的情况。由于重复struct
定义是无效的,因此需要确保相同的头文件没有定义两次 - 这就是#ifndef
在包含保护中派上用场的地方:此外,在文件的解析和编译需要很长时间的情况下,这可能会导致加速,因为可以快速跳过标头的有效负载(预处理阶段处理源代码的速度比实际编译阶段快得多)。
“需要”宏的另一个原因是早期的 C 编译器可能只是直接将代码翻译成汇编程序。您可以通过使用宏来避免函数调用,这会导致它的扩展将直接插入到现场并在此处生成代码,而不必进行函数调用。同样的事情也适用于常量,否则这些常量是必须在其他地方获取的变量,而不是直接放入生成的代码中。
第三个原因是条件编译的可能性。大多数编译器预定义了一组宏,旨在提供有关正在编译的系统的信息。例如,我们有宏
_WIN32
仅在您为 Windows 编译时才定义。这将有可能拥有一个仅包含在 windows 中的代码片段,而另一个将包含在另一个平台上的代码片段。大多数编译器还可以从命令行设置自定义宏,这意味着可以从命令行(在 Visual Studio 中,您也可以在项目设置中更改它们)更改将被编译的部分。最引人注目的此类宏是NDEBUG
宏,如果定义该宏将禁用所有assert
s - 在编译版本时添加/DNDEBUG
是正常的。