以奇怪的方式使用#define预处理程序指令

时间:2011-04-22 08:52:05

标签: c c-preprocessor identifier

今天我刚刚读完并试验了 C 关于如何使用#define来创建一个清单常量,之后我想到了一些东西,下面是代码。

#include <stdio.h>
#define dummy main
#define yam {
#define apple }

int dummy(void)        //constant substitution main with dummy
yam                          // constant substitution { with yam
  printf("It works!!\n");
  return 0;
apple                           //constant substitution } with apple

正如预期的那样,它就像魅力一样,我只是想知道为什么这样的东西不会导致任何错误,也许我可以理解为什么可以替换main(),因为main是一个标识符(名称)赋予函数,变量和常量),但为什么{}也可以用符号名替换?第二件事是, C 用于存储此符号常量的数据类型,该常量不是单引号""中包含的字符,也不是整数或浮点数。

4 个答案:

答案 0 :(得分:7)

#define语句在实际编译程序之前由预处理程序进行评估,因此编译器永远不会看到yam。预处理器执行直接文本替换。

也就是说,当编译器看到你的代码时,它看起来像这样:

int main(void)        //constant substitution main with dummy
{                          // constant substitution { with yam
  printf("It works!!\n");
  return 0;
}                           //constant substitution } with apple

答案 1 :(得分:2)

定义是字面上的文本替换。在预处理器步骤中,编译器将遍历您的代码并将所有dummy替换为main,将yam替换为{,将apple替换为} }。

答案 2 :(得分:2)

这是有效的,因为预处理器是* PRE *处理器,即它是在实际处理之前发生的事情。

因此,在真正的编译器查看代码之前,预处理器会执行粗文本替换。

答案 3 :(得分:2)

#define由预处理器处理。在编译器编译代码之前,将逐个字符地替换这些东西。您基本上可以使用#define来模糊整个代码,但是任何拥有预编译器的人都可以在以后隐藏它。预处理器替换了您定义的“常量”的所有出现,除非它用引号括起来(例如char *test="dumy yam apple";将保持不变)。