[英]What are the benefits of using macros instead of functions in C?
第一個代碼:
#include <stdio.h>
int area(int a,int b){
int area1 = a*b;
return area1;
}
int main()
{
int l1 = 10, l2 = 5, area2;
area2 = area(l1,l2);
printf("Area of rectangle is: %d", area2);
return 0;
}
第二個代碼:
#include <stdio.h>
// macro with parameter
#define AREA(l, b) (l * b)
int main()
{
int l1 = 10, l2 = 5, area;
area = AREA(l1, l2);
printf("Area of rectangle is: %d", area);
return 0;
}
兩個代碼相同的 output:矩形面積為:50
我的問題:很明顯,C 語言中的宏與函數相同,但宏比函數占用更少的空間(更少的行)。 這是使用宏而不是函數的唯一好處嗎? 因為它們看起來大致相同。
宏絕對不同於函數。 宏是文本替換1 ; 它們不像函數那樣被調用。
你的AREA
宏的問題是,如果你傳遞一個像AREA(l1+x,l2)
這樣的表達式,它會表現不佳 - 這將擴展為(l1+x * l2)
,它不會做你想要的。 Arguments 到宏不被評估,它們被擴展到位。
宏和類似函數的宏對於創建符號常量、簡化重復的文本塊以及實現粗略的類似模板的行為很有用。
宏很有用的一種情況是當您將它們與__FILE__
和__LINE__
結合使用時。
我在Bismon軟件項目中有一個具體的例子。 在其文件cmacros_BM.h
我定義
// only used by FATAL_BM macro
extern void fatal_stop_at_BM (const char *, int) __attribute__((noreturn));
#define FATAL_AT_BIS_BM(Fil,Lin,Fmt,...) do { \
fprintf(stderr, "BM FATAL:%s:%d: <%s>\n " Fmt "\n\n", \
Fil, Lin, __func__, ##__VA_ARGS__); \
fatal_stop_at_BM(Fil,Lin); } while(0)
#define FATAL_AT_BM(Fil,Lin,Fmt,...) FATAL_AT_BIS_BM(Fil,Lin,Fmt,##__VA_ARGS__)
#define FATAL_BM(Fmt,...) FATAL_AT_BM(__FILE__,__LINE__,Fmt,##__VA_ARGS__)
和致命錯誤正在調用類似(來自文件user_BM.c
的示例)
FILE *fil = fopen (contributors_filepath_BM, "r+");
if (!fil)
FATAL_BM ("find_contributor_BM cannot open contributors file %s : %m",
contributors_filepath_BM);
當fopen
失敗時,致命錯誤消息會顯示該FATAL_BM
宏調用的源文件和行號。
fatal_stop_at_BM
function 在文件main_BM.c
中定義
另請注意,您的一些 C 文件可能由GNU bison 、 GNU m4 、 ANTLR 、 SWIG等程序生成,並且GNU autoconf也使用預處理器符號。
還要研究Linux kernel的源代碼。 它廣泛使用宏。
最重要的是,閱讀 C 編譯器的文檔(例如GCC )。 許多 C 編譯器可以向您顯示 C 代碼的預處理形式。
您的
// macro with parameter
#define AREA(l, b) (l * b)
是錯誤的,如果您希望AREA(x+2,y-3)
按預期工作,則應為#define AREA(l, b) ((l) * (b))
。
出於性能原因,您可以將 function 定義為
inline int area(int a,int b){ return a*b; }
gcc -Wall -Wextra -g
調用);我同意@Eric Postpischil。 舊的編譯器不支持宏,它們對宏一無所知。 因此,如果您使用舊的編譯器,這會使調試變得更加困難。
這是使用宏而不是函數的唯一好處嗎?
不,宏是類似函數的,只能用於定義非常簡單的東西,例如簡單的公式,但不建議使用它們定義 C function 因為它們試圖將所有內容都線性化和平坦化,這就是您可能面臨軟件設計問題的原因他們使調試更加困難。 所以,這並不總是一個好處。
在你的情況下,我認為這不是一個大而嚴重的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.