回答
它擴大到2+3*2+3
,相當於2+(3*2)+3
。使用括號來修復它:
#define square(x) ((x)*(x))
現在有了square(x++)
嘗試一下,你會碰到更多的問題(未定義行爲)。如果可以的話,避免將它作爲宏來執行。
等效的C++函數應該和宏一樣有效(在優化出現的現代編譯器上)並且不會受到這個影響問題。 – 2011-04-27 16:09:05
@Martin:正確,如果OP使用C++。適應症是它可能是C.我認爲C99也有內聯函數,它似乎是GNU C中的擴展。http://en.wikipedia.org/wiki/Inline_function#Language_support – 2011-04-27 16:12:02
square(2+3)
擴展到2+3*2+3
這相當於2+(3*2)+3
[*
的優先級高於+
]
海合會可以使用-E
選項來查看您的預處理器產生什麼
C:\Users\SUPER USER>type a.c
#define square(x) x*x
int main()
{
a = square(2+3); //a = 11
}
C:\Users\SUPER USER>gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"
int main()
{
a = 2+3*2+3;
}
補救
試試這個
#define square(x) ((x)*(x))
因爲2 + 3
在表達x * x
字面上取代,它變得2 + 3 * 2 + 3
和*
操作具有更高的優先級,所以你沒有得到預期的結果。
務必附上宏參數和整個括號中的表達式,以避免這種情況:
#define SQUARE(x) ((x) * (x))
另外請注意,您通過任何表達都需要進行兩次評估,如果表達式有副作用,這樣可以不希望作爲分配或函數調用。在這些情況下,最好使用內聯函數。
總是也將括號括在括號中。根據你的建議,'1.0/square(x)'將被評估爲'1.0 /(2 + 3)*(2 + 3)',因此'1.0'而不是'0.04'。 – 2011-04-27 16:11:16
@Sam:採取的措施。具有諷刺意味的是,但我自己曾經說過幾個月前在這個答案:http://stackoverflow.com/questions/4455307/weird-macro-definition-issue/4455354#4455354 – 2011-04-27 16:12:59
嘗試:
#define square(x) ((x)*(x))
想想你得到什麼,當宏展開。 c預處理器將擴展爲
a = 2 + 3 * 2 + 3
您需要正確定義您的宏。始終將宏變量括在括號中。這會給你預期的結果。
#define square(x) ((x)*(x))
宏擴展會是這樣:
a = ((2 + 3) * (2 + 3))
你的建議是不「正確定義」的宏。 1.0/square(x)'將被評估爲'1.0 /(2 + 3)*(2 + 3)',因此'1.0'而不是'0.04'。 – 2011-04-27 16:10:07
我修復了錯誤定義的宏。增加了另一套括號。 – don 2011-04-27 16:12:41
- 1. 機器學習數據預處理
- 2. C預處理器操作員##
- 3. lambda操作符c#學習
- 4. 學習Objective-C的不知道ç
- 5. 特徵預處理scikit學習
- 6. C++預處理器+檢測對象類型和新操作
- 7. 嵌套##操作者在C預處理
- 8. 學習資源c#Excel互操作
- 9. 機器學習預處理字符串到數字
- 10. 音頻處理 - 我從哪裏開始學習書籍和學習
- 11. C++預處理器
- 12. 學習Python異常處理
- 13. 學習和練習C++
- 14. C++模板和C預處理器
- 15. C#代碼理解和學習
- 16. 深度學習中的圖像預處理
- 17. C++預處理器如何工作?
- 18. C預處理器更換工作不
- 19. 預處理器指令define和ifdef不按我想象的那樣工作?
- 20. 學習C/C++和Java
- 21. 像Xcode中的___DATE___這樣的日期預處理器
- 22. C++預處理器和超載問題
- 23. 學習的Objective-C和Xcode?
- 24. 學習iPhone和Objective C的
- 25. 培訓機器學習預測器
- 26. C預處理器概念
- 27. C++預處理器__typeof
- 28. C++預處理器變量
- 29. C預處理器警衛?
- 30. C++ #define預處理器
就像一個忠告,這個例子顯示的很多原因,你應該避免使用宏在C,直到有一天,你在哪裏一個* *真的**知道你在做什麼。當然,當那一天到來時,你會知道爲什麼要詳細地避免它們... – 2011-04-27 16:13:30
@ T.E.D .:宏(和一般的預處理器)是一個類似於任何其他工具的工具。這個例子並沒有說明爲什麼你不應該使用宏 - 它只是顯示了一個不適用的特殊用例。宏的好用和壞用都有。 – 2011-04-27 16:21:07
也就是說,當然有更多壞的用途比好的:) – 2011-04-27 16:21:26