C /C++ define 來簡化函式; C/C++ 預定義巨集. 那我們開始吧! C/C++ define 基本用法. 以下為C/C++ define ... ... <看更多>
「c define函式」的推薦目錄:
- 關於c define函式 在 十三誡增修--09:慎用Macro(#define) - 看板C_and_CPP 的評價
- 關於c define函式 在 C/C++ define 用法與範例 - ShengYu Talk 的評價
- 關於c define函式 在 [(C/C++) program] 面試練習題(const , #define, inline ... - 隨意窩 的評價
- 關於c define函式 在 C語言#define 簡單使用方式與好處- YouTube 的評價
- 關於c define函式 在 define / use a Macro inside a fcuntion - good style/practice? 的評價
- 關於c define函式 在 C語言初學者- #define的陷阱 - Facebook 的評價
- 關於c define函式 在 define用法-在PTT/IG/網紅社群上服務品牌流行穿搭-2022-08 ... 的評價
- 關於c define函式 在 If you could define function by prepending `inline` in header ... 的評價
c define函式 在 [(C/C++) program] 面試練習題(const , #define, inline ... - 隨意窩 的推薦與評價
1. 試說明const , #define, inline ,function 的不同首先先個別介紹#define =>可建立巨集Macro, 或宣告常用常數使用是一種pre-compile header,會在程式編譯成機械語言 ... ... <看更多>
c define函式 在 C語言初學者- #define的陷阱 - Facebook 的推薦與評價
C 語言的巨集帶給大家很大的好處,除了可以定義常數外,定義function也是大家喜愛的功能之一,不過使用上要特別小. ... <看更多>
c define函式 在 define用法-在PTT/IG/網紅社群上服務品牌流行穿搭-2022-08 ... 的推薦與評價
稍微進階一點的用法是用巨集寫簡單的擬函式。 ... 承上節,程式設計者可以利用#define 為C 語言創造新語法。 define as翻譯及用法- 英漢詞典- ... ... <看更多>
c define函式 在 If you could define function by prepending `inline` in header ... 的推薦與評價
Then why people bother to use the method "Declare function in header first, then define it in a seperate .cpp file" . ... <看更多>
c define函式 在 十三誡增修--09:慎用Macro(#define) - 看板C_and_CPP 的推薦與評價
誡9改了很多,有錯請告知....
========================================================
09. 慎用macro(#define)
Macro是個像鐵鎚一樣好用又危險的工具:
用得好可以釘釘子,用不好可以把釘子打彎、敲到你手指或被抓去吃子彈。
因為macro 定義出的「偽函式」有以下缺點:
(1) debug會變得複雜。
(2) 無法遞迴呼叫。
(3) 無法用 & 加在 macro name 之前,取得函式位址。
(4) 沒有namespace。
(5) 可能會導致奇怪的side effect或其他無法預測的問題。
所以,使用macro前,請先確認以上的缺點是否會影響你的程式運行。
替代方案:enum(定義整數),const T(定義常數),inline function(定義函式)
C++的template(定義可用不同type參數的函式),
或C++11開始的匿名函式(Lambda function)與constexpr T(編譯期常數)
以下就針對macro的缺點做說明:
(1) debug會變得複雜。
編譯器不能對macro本身做語法檢查,只能檢查預處理(preprocess)後的結果。
(2) 無法遞迴呼叫。
根據C standard 6.10.3.4,
如果某macro的定義裡裏面含有跟此macro名稱同樣的的字串,
該字串將不會被預處理。
所以:
#define pr(n) ((n==1)? 1 : pr(n-1))
cout<< pr(5) <<endl;
預處理過後會變成:
cout<< ((5==1)? 1 : pr(5 -1)) <<endl; // pr沒有定義,編譯會出錯
(3) 無法用 & 加在 macro name 之前,取得函式位址。
因為他不是函式,所以你也不可以把函式指標套用在macro上。
(4) 沒有namespace。
錯誤例子:
#define begin() x = 0
for (std::vector<int>::iterator it = myvector.begin();
it != myvector.end(); ++it) // begin是std的保留字
std::cout << ' ' << *it;
改善方法:macro名稱一律用大寫,如BEGIN()
(5) 可能會導致奇怪的side effect或其他無法預測的問題。
錯誤例子:
#include <stdio.h>
#define SQUARE(x) (x * x)
int main()
{
printf("%d\n", SQUARE(10-5)); // 預處理後變成SQUARE(10-5*10-5)
return 0;
}
正確例子:在 Macro 定義中, 務必為它的參數個別加上括號
#include <stdio.h>
#define SQUARE(x) ((x) * (x))
int main()
{
printf("%d\n", SQUARE(10-5));
return 0;
}
不過遇到以下有side effect的例子就算加了括號也沒用。
錯誤例子: (感謝 yaca 網友提供)
#define MACRO(x) (((x) * (x)) - ((x) * (x)))
int main()
{
int x = 3;
printf("%d\n", MACRO(++x)); // 有side effect
return 0;
}
備註:
C++11開始支援匿名函式(Lambda function),可視情況使用。
補充資料:
- https://stackoverflow.com/questions/14041453/why-are-preprocessor-
macros-evil-and-what-are-the-alternatives
- https://stackoverflow.com/questions/12447557/can-we-have-recursive-macros
- C11 Standard 6.10.3.4
- https://en.cppreference.com/w/cpp/language/lambda
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.128.143.228
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1463986797.A.CC6.html
... <看更多>