嵌入式技术
宏函数是一种特殊的函数宏,与普通函数宏不同的是,它可以拥有多条语句和局部变量,从而实现更复杂的功能。它的定义类似于普通函数,但用大括号包裹起来,并以分号结束每个语句。
#define TEST(a, b)
({
int temp = a;
a = b;
b = temp;
})
好奇的读者就会有这样的疑问,为什么要这样写呢,去掉个小括号不行吗,去掉大括号不行吗,只留下小括号不行吗,只留下大括号不行吗?这篇文章就来探讨一下为什么这样写。
| 测试一
直接就去掉上边的两个括号,借助gcc把宏函数展开,通过展开后的代码进行分析:
#include "stdio.h"
#define INT_TEST1(a, b)
int tmp = a;
a = b;
b = tmp;
int main()
{
int a = 10;
int b = 20;
// test1
INT_TEST1(a, b);
printf("a:%d
", a);
printf("b:%d
", b);
}
通过 gcc -E -P 1.c>2.c 命令,把1.c源码文件展开复制到2.c文件中,就可以通过2.c文件找到对应展开的宏函数代码:

可以看到展开后的宏函数在源码中的表现,如果在if或者while等语句不加大括号时,代码执行的效果和预期的不同,不了解过程的就会不好排查问题。
| 测试二
只加小括号会不会能解决问题呢,其实这个语法是不行的,代码会直接报错的:

| 测试三
只加小括号会报错,那只加大括号会不会也报错呢,事实上只加大括号是不会报错的:

是不是解决了if或者while等语句不加大括号时导致出现异常情况,但是这样的写法也带来了新的问题,那就是if语句或者其他语句有分支并且没有带大括号会出现问题:

| 测试四
既加小括号又加大括号会不会是个完美的解决方法呢,通过实测是能通过编译的:

| 测试五
除了测试四的写法,那有没有其他写法呢,答案肯定是必然的:

这个写法是不是更加优美简洁呢,这样的写法应该是很常见的,只是过去没怎么去深究为什么要这样写。
| 测试六
宏函数可以直接对结构体进行初始化,就可以很方便的在定义结构体的时候直接对它进行初始化:

除了上边这样的写法,还可以是这样的写法:

关于宏函数就简单回顾一下,不知道有没有触发到各位的知识盲区呢?
编辑:黄飞
全部0条评论
快来发表一下你的评论吧 !