[英]Macro expansion in context of arithmetic expression?
我在網站上看到了以下代碼。 我無法判斷結果如何變為11
,而不是25
或13
。
為什么我在想25
因為SQ(5) 5*5
或13
因為
SQ(2) = 4;
SQ(3) = 9;
可能是最終結果將是13 (9 + 4)
但是驚訝地看到結果為11
。 結果如何成為11
?
using namespace std;
#define SQ(a) (a*a)
int main()
{
int ans = SQ(2 + 3);
cout << ans << endl;
system("pause");
}
預處理器在源代碼上執行簡單的文本替換。 它對基礎語言或其規則一無所知。
在您的示例中, SQ(2 + 3)
擴展為(2 + 3*2 + 3)
,其值為11
。
定義SQ
更健壯的方法是:
#define SQ(a) ((a)*(a))
現在, SQ(2 + 3)
將擴展為((2 + 3)*(2 + 3))
,得到25
。
雖然這個定義是一種改進,但它仍然不是防彈的。 如果將SQ()
應用於具有副作用的表達式,則可能會產生不良后果。 例如:
f()
是一個向控制台輸出內容並返回int
的函數,則SQ(f())
將導致輸出被打印兩次。 i
是int
變量,則SQ(i++)
導致未定義的行為 。 有關宏的困難的更多示例,請參閱宏陷阱 。
由於這些原因,通常優選使用函數而不是宏。
#define
擴展在編譯器看到源代碼之前啟動。 這就是為什么它們被稱為預處理器指令 ,這里的處理器是將C轉換為機器可讀代碼的編譯器。
所以,這就是宏預處理器傳遞給編譯器的原因:
SQ(2 + 3)
擴展為(2 + 3*2 + 3)
所以,這真的是2 + 6 + 3
= 11
。
你怎么能讓它做你期望的?
C預處理器在編譯器解釋表達式和C語法之前進行文本替換。 因此,在此代碼上運行C預處理器會轉換:
SQ(2 + 3)
成:
2 + 3*2 + 3
這簡化為:
2 + 6 + 3
這是11。
它只是在編譯之前的替代品
所以你應該試試這個:
#define SQ(a) ((a)*(a))
在您的情況下, SQ(2 + 3)
相當於(2+3*2+3)
,即11
。
但正如我在上面所寫的那樣糾正它,它會像((2+3)*(2+3))
,即5*5 = 25
,這就是你想要的答案。
#define preprocesor
語法: #define identifier replacement
#define也可以使用參數來定義函數宏:
# define SQ(a) (a*a)
將在編譯時用* a替換任何SQ(a)的出現。 因此,
SQ(2 + 3)將被替換為2 + 3 * 2 + 3在更換完成后執行計算。 因此回答2 + 3 * 2 + 3 = 11
對於您的實現,該值將擴展為2+3 * 2+3
,這將導致2 + 6 + 3 = 11。
您應該將其定義為:
#define SQ(x) ({typeof(x) y=x; y*y;})
測試gcc
,輸入如
注意: typeof
是標准C的GNU添加。可能在某些編譯器中不可用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.