2011-06-16 52 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