为什么一个函数中的预处理程序指令会影响另一个函数的编译?

Shu*_*sal 4 c io c-preprocessor

程序编译成功并打印1000甚至没有foo()从我们的main()函数调用函数.这怎么可能?

#include<stdio.h>


void foo()
{
    #define ans 1000
}

int main() {

  printf("%d", ans);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

klu*_*utt 10

#define由在编译器之前暂存的预处理器运行.预处理器完成后,代码将如下所示:

/* Everything that is inside stdio.h is inserted here */

void foo()
{
}

int main() {

  printf("%d", 1000);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这就是实际编译的内容.

预处理器对于使头文件工作非常重要.在其中,您会看到以下结构:

#ifndef foo
#define foo
/* The content of the header file */
#endif
Run Code Online (Sandbox Code Playgroud)

如果没有这个,如果头文件包含多次,编译器会抱怨.您可能会问为什么要多次包含头文件.好吧,头文件可以包含其他头文件.考虑这个宏,这对调试很有用.它打印变量的名称,然后输出值.请注意,您必须为不同类型执行单独的版本.

#define dbg_print_int(x)  fprintf(stderr, "%s = %d", #x, x)
Run Code Online (Sandbox Code Playgroud)

这是非常通用的,因此您可能希望将其包含在头文件中供自己使用.由于它需要stdio.h,我们将其包括在内.

/* debug.h */
#include <stdio.h>
#define dbg_print_int(x)  fprintf(stderr, "%s = %d", #x, x)
Run Code Online (Sandbox Code Playgroud)

当您包含此文件并在主程序中包含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
Run Code Online (Sandbox Code Playgroud)

文件stdio.h具有相同的构造.这里的主要内容是它在编译器之前运行.define是一个简单的替换命令.它对范围或类型一无所知.但是,正如您在此处所看到的,内置了一些基本逻辑.预处理器所做的另一件事是删除所有注释.

您可以在此处阅读有关C预处理器的更多信息:http://www.tutorialspoint.com/cprogramming/c_preprocessors.htm