2013-01-01 44 views
-3

我剛開始學習C++。請原諒這樣的問題。 我的任務是編寫一個宏來計算周長並對其進行測試。C++:宏似乎有點奇怪

#define _USE_MATH_DEFINES 
#include <cmath> 

#define LENGTH(radius) (2 * M_PI * radius) 

float l1 = LENGTH(1 + 2); // The result should be 18.8495... I have 8.28. Incorrect result. 
float l2 = 1/LENGTH(2); // The result should be 0.07957... Working correctly. 

我增加了額外的對parenthethis的:

float l1 = LENGTH((1 + 2)); // Correct result. 

怎麼能寫出這樣一個宏,我得到無需添加額外的括號正確的結果?

+0

你可以做的最好的事情是編寫一個'constexpr'(或不)函數。 – Griwes

+4

這裏有什麼奇怪的是使用宏。內聯函數會更合適。 –

回答

12

使用:

#define LENGTH(radius) (2 * M_PI * (radius)) 

當你寫

float l1 = LENGTH(1 + 2); 

與您定義的預處理器將其轉換爲

float l1 = 2 * M_PI * 1 + 2 
3

永遠,永遠,包宏參數在() - 無論多麼它可能看起來微不足道,你遲早會需要它。

當然,編寫同樣功能的函數有以下好處: 1.您可以在調試器中進入,因此您可以真正弄清楚發生了什麼。 2.宏觀參數表達式沒有奇怪。

要說明一點二,說我們使用您的宏有這樣的代碼:

// Print 10 lengths, 3, 5, 7, ... 
int x = 3; 
for(i = 0; i < 10; i++) 
{ 
     printf("Length of radius %d is %5.2f\n", x, LENGTH(x += 2)); 
} 

現在,有人拿了一個優化級別,並實現了2 *什麼是快做的東西+什麼的,所以重寫宏要快:

#define LENGTH(radius) (((radius) + (radius)) * M_PI) 

現在,既然我們已經在x+=2LENGTH宏,奇怪的事情發生(因爲同一個變量在同一語句[是,兩者之間的平均更新兩次成爲未定義行爲序列點]。如果有一個length函數,它會像你期望的那樣完美工作。

1

不使用宏本 - 一個inline function在各方面都

更好但是發生的事情是很簡單的undertand,並瞭解它是有用知道爲什麼宏最好避免。

#define LENGTH(radius) (2 * M_PI * radius) 

float l1 = LENGTH(1 + 2); 

宏是隻是■簡單文本替換,所以上面的代碼被取代以:

float l1 = (2 * M_PI * 1 + 2); 

這顯然有錯誤的操作優先級。