C中#define预处理器的范围

时间:2011-06-16 22:49:49

标签: c c-preprocessor

#define的范围直到文件末尾。但它从哪里开始。 基本上我尝试了以下代码。

 #include<stdio.h>
 #include<stdlib.h>
 #define pi 3.14
 void fun();
 int main()
{
 printf("%f \n",pi);
 #define pi 3.141516
    fun();
return 0;
}
void fun(){
printf("%f \n",pi);}

上述程序的输出结果为

3.140000
3.141416

考虑到main的预处理,pi的值应为3.141516 和主要3.14之外。这是不正确的,但请解释原因。

6 个答案:

答案 0 :(得分:21)

C预处理器从上到下运行文件,并将#define语句视为美化的复制粘贴操作。遇到行#define pi 3.14后,它会开始用pi替换单词3.14的每个实例。预处理器不处理(甚至注意)C语言范围机制,如括号和花括号。一旦看到#define,该定义就会生效,直到达到文件末尾,宏未定义为#undef,或者(如本例所示)宏重新定义用另一个#define语句定义。

如果您想要遵守C范围规则的常量,我建议在const float pi = 3.14;的行中使用更多内容。

答案 1 :(得分:6)

#define的范围是从文件的出现位置到文件的末尾,而不管任何介入的C范围。

答案 2 :(得分:1)

预处理器没有“范围”的概念 - 它操纵程序的文本,而不知道文本是什么

符号从其定义定义到编译单元结束(源文件及其包含的文件)

答案 3 :(得分:1)

当您有预处理器问题时:

  

gcc -E foo.c&gt; foo.i; vim foo.i

答案 4 :(得分:1)

预处理器处理完文件后,大致情况如下:

 void fun();
 int main()
 {
    printf("%f \n",3.14);
   
    fun();
    return 0;
 }
 void fun(){
 printf("%f \n",3.141516);}

这些是去编译器进行编译的行(为了清楚起见,我丢弃了许多代码,只保留了您编写的代码)。由于预处理器将#define伪指令替换为您提供的文本/值,因此预处理后您将不再看到#define伪指令。因此,很清楚将在控制台/终端上打印什么。

答案 5 :(得分:0)

据我所知,预处理器按照遇到它们的顺序使用#define语句。在这种情况下,您的第一个printf语句正确打印3.14,第二个3.141516(您的程序输出中是否有拼写错误?)。