#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之外。这是不正确的,但请解释原因。
答案 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(您的程序输出中是否有拼写错误?)。