C 中 #define 预处理器的范围

问题描述 投票:0回答:6

#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 c-preprocessor
6个回答
29
投票

C 预处理器从上到下运行文件,并将

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

如果您想要遵守 C 作用域规则的常量,我建议使用更多类似

const float pi = 3.14;
的内容。


11
投票

#define
的范围是从出现到文件末尾(或相应的
#undef
),无论中间有任何C范围。


4
投票

当您有预处理器问题时:

gcc -E foo.c > foo.i; vim foo.i


1
投票

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

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


1
投票

这是预处理器处理完文件后的大致样子:

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

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

这些是进入编译器进行编译的行(为了清楚起见,我放弃了大部分代码,只保留了您编码的内容)。由于预处理器将

#define
指令替换为您提供的文本/值,因此在预处理后您将不再看到
#define
指令。所以控制台/终端上将打印什么内容很清楚。


0
投票

据我所知,预处理器按照遇到的顺序使用

#define
语句。在这种情况下,您的第一个
printf
语句正确打印 3.14 和第二个 3.141516 (程序的输出中是否存在拼写错误?)。

© www.soinside.com 2019 - 2024. All rights reserved.