函数宏,即包含多条语句的宏定义,其通常为某一被频繁调用的功能的语句封装,且不想通过函数方式封装来降低额外的弹栈压栈开销。
第一种:
#define INT_SWAP(a,b) \
int tmp = a; \
a = b; \
b = tmp
但是这种方式作用域在遇到if、while等不使用{}会在第一个分号就结束了。
第二种:
#define INT_SWAP(a,b)\
{ \
int tmp = a; \
a = b; \
b = tmp; \
}
此方式可以避免第一种问题,但是在无{}的if else语句中会编译出错,原因是INT_SWAP();中的最后一个;会把if的作用域终结,所以else不能匹配到相应的if。
解决方法:
1、可以使用
if(1)
INT_SWAP(A,B)
else
{
/"CODE"/
}
2、可以使用
if(1)
{
INT_SWAP(A,B);
}
else
{
/"code"/
}
第三种:
#define INT_SWAP(a,b) \
do{ \
int tmp = a; \
a = b; \
b = tmp; \
}while(0)
因为是while,所以比起第二种可以break;提前退出,可以添加参数检测,可以在无{}切有else的语句中调用,且do{}while()语法必须用;作为语句结尾,所以可以正常使用,如:
if(1)
INT_SWAP(A,B);
else
/"code"/
但是此封装没有返回值,不能作为右值使用,有场景限制。
第四种:
#define INT_SWAP(a,b) \
({ \
int tmp = a; \
a = b; \
b = tmp; \
})
注意:({})方法为GNU C扩展语法,非原生语法
此方法与第三种方法包括第三种方法的所有场景,但是不能使用break退出函数宏,但是支持函数返回值,可以作为右值使用。
因为C 语言规定 ({}) 中的最后一条语句的结果为该双括号体的返回值。
如:
int main()
{
int a = ({
10;
1000;
});
printf("a = %d\n", a); // a = 1000
}
此上四种方法为函数宏封装方法,此为嵌入式大杂烩上借鉴而来