[英]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.