2016-01-27 42 views
-2

假設我們有這樣的表達:C++定義表達式求值

#define cube(x) x * x * x 

然後我們把它叫做:

int n = 3, v; 
v = cube(n + 1); // v = 10 
v = cube((n + 1)); // v = 64 
v = cube(n);  // v = 27 

所以,問題是:爲什麼第一個操作不作v = 64

+3

閱讀有關運算符優先級的內容。手動展開MACRO並檢查。 –

+0

這必須是重複的... – chqrlie

+0

@chqrlie我懷疑,但我找不到類似的東西。 – tomab

回答

11

宏未評估(在評估的常見解釋意義上),它們在編譯時被擴展。

文件編譯之前,還有被稱爲C Preprocessor另一個程序,它取代了宏調用字面上/文本方式並準備實際編譯的文件,所以您的宏

#define cube(x) x * x * x when you do this 

v = cube(n + 1); 

被替換爲(展開的是正確的術語

v = n + 1 * n + 1 * n + 1; 
// Simplifies to 
v = n + n + n + 1; 
// and again 
v = 3 * n + 1; 

這對於n = 3給你10完全觀察到的結果。

注意,當您添加括號

v = cube((n + 1)); 

然後,擴展

v = (n + 1) * (n + 1) * (n + 1); 

這是你所期望的cube()做,所以防止這種情況,你應該重新定義宏這樣

#define cube(x) ((x) * (x) * (x)) 

如果您使用的是GCC嘗試

gcc -E source.c 

並檢查結果,以驗證該宏是如何擴大。

+0

@iharob:很好的答案。您可能會添加有關多次評估的潛在問題的警告。 – chqrlie

+3

@tomab,這是純粹的文本替換,如果您嘗試使用帶有副作用的宏來擴展宏,它會讓您感到更加驚訝。 – StoryTeller

+0

只是一個挑剔的問題:宏觀/文本擴展*是一種評估形式,雖然它不是大多數人所想的形式(並且重要的是,它不是根據C++的規則進行的評估,也不是常規代數的評估)。 –