#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。这是不正确的,但请解释原因。
C 预处理器从上到下运行文件,并将
#define
语句视为美化的复制粘贴操作。 一旦遇到 #define pi 3.14
行,它就会开始用 pi
替换单词 3.14
的每个实例。 预处理器不会处理(甚至不会注意到)C 语言作用域机制,例如括号和大括号。 一旦它看到 #define
,该定义就会生效,直到到达文件末尾、未使用 #undef
定义宏,或者(如本例中)使用另一个 重新定义宏。 #define
声明。
如果您想要遵守 C 作用域规则的常量,我建议使用更多类似
const float pi = 3.14;
的内容。
#define
的范围是从出现到文件末尾(或相应的#undef
),无论中间有任何C范围。
当您有预处理器问题时:
gcc -E foo.c > foo.i; vim foo.i
预处理器没有“范围”的概念——它操纵程序的文本,而不知道文本是什么
符号从其定义开始一直到编译单元结束(源文件及其包含的文件)
这是预处理器处理完文件后的大致样子:
void fun();
int main()
{
printf("%f \n",3.14);
fun();
return 0;
}
void fun(){
printf("%f \n",3.141516);}
这些是进入编译器进行编译的行(为了清楚起见,我放弃了大部分代码,只保留了您编码的内容)。由于预处理器将
#define
指令替换为您提供的文本/值,因此在预处理后您将不再看到 #define
指令。所以控制台/终端上将打印什么内容很清楚。
据我所知,预处理器按照遇到的顺序使用
#define
语句。在这种情况下,您的第一个 printf
语句正确打印 3.14 和第二个 3.141516 (程序的输出中是否存在拼写错误?)。