#define由在编译器之前暂存的预处理器运行。预处理完成后,代码如下所示:
/* Everything that is inside stdio.h is inserted here */
void foo()
{
}
int main() {
printf("%d", 1000);
return 0;
}
这就是实际编译的内容。
预处理器对于使头文件正常工作非常重要。在它们中,您会看到这样的结构:
#ifndef foo
#define foo
/* The content of the header file */
#endif
没有这个,如果头文件被多次包含,编译器会报错。您可能会问为什么要多次包含头文件。好吧,头文件可以包含其他头文件。考虑一下这个宏,它对调试很有用。它打印变量的名称,然后打印值。请注意,您必须为不同的类型制作单独的版本。
#define dbg_print_int(x) fprintf(stderr, "%s = %d", #x, x)
这是非常通用的,因此您可能希望将其包含在头文件中以供自己使用。由于它需要 stdio.h,因此我们将其包含在内。
/* debug.h */
#include <stdio.h>
#define dbg_print_int(x) fprintf(stderr, "%s = %d", #x, x)
当你包含这个文件并在你的主程序中包含 stdio.h 时会发生什么?好吧,stdio.h 将被包含两次。这就是为什么 debug.h 应该是这样的:
/* debug.h */
#ifndef DEBUG_H
#define DEBUG_H
#include <stdio.h>
#define dbg_print_int(x) fprintf(stderr, "%s = %d", #x, x)
#endif
文件 stdio.h 具有相同的结构。这里的主要内容是它在编译器之前运行。定义是一个简单的替换命令。它对范围或类型一无所知。但是,正如您在此处看到的,其中内置了一些基本逻辑。预处理器做的另一件事是删除所有的 cmets。
您可以在此处阅读有关 C 预处理器的更多信息:http://www.tutorialspoint.com/cprogramming/c_preprocessors.htm