2011-06-16 50 views
10

#define的范围一直到文件末尾。但是它从哪里开始。 基本上我尝试了下面的代码。#define预处理器的范围C

#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 

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

+5

请记住它是PREprocessing。它不知道或关心你的代码的结构,在#define的情况下,它正在按照它看到它们的顺序进行替换,这个替换与最新的#defined变量的值相关。 – Joe 2011-06-16 22:55:03

+5

这段代码实际上是格式不正确的:除非定义相同,否则不能'定义与当前定义的另一个宏具有相同名称的宏。所以,第二个'#define pi'使程序不合格。你需要先#undef pi'。 – 2011-06-16 23:05:48

+1

* #define的范围直到文件末尾。*否,文件结尾**或#undef **具有相同的宏标识符。 – Jens 2013-11-14 21:10:32

回答

16

C预处理器通过文件从上到下运行并将#define语句看作是一种优化的复制和粘贴操作。一旦遇到行#define pi 3.14,它开始用3.14替换单词pi的每个实例。预处理器不处理(或者甚至通知)C语言范围机制,如括号和花括号。一旦它看到#define,该定义将一直有效,直到达到文件末尾,则宏定义为#undef,或者(在此情况下)宏用另一个#define语句重新定义。

如果你想要符合C范围规则的常量,我建议在const float pi = 3.14;的行上使用更多的东西。

+1

“或(在这种情况下)该宏被重新定义与另一个”#define“语句。”实际上,没有前面的##undef的第二个'#define'使得程序不合格。 – 2011-06-16 23:06:28

+1

请注意,'const'不会创建一个常量,例如,在开关标签中:它会创建一个只读对象。在http://ideone.com/f3aON举例 – pmg 2011-06-16 23:15:11

0

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

+0

nope ..输出正确.. – 2011-06-16 23:11:12

4

#define的范围是从出现到结束的文件,不管任何介入C范围。

1

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

符号是从它的定义界定,直至编译单元结束的任何想法(源文件和文件)

1

当你有预处理器的问题:

GCC-E的foo.c> foo.i; vim foo.i