嵌入式技术
宏函数是一种特殊的函数宏,与普通函数宏不同的是,它可以拥有多条语句和局部变量,从而实现更复杂的功能。它的定义类似于普通函数,但用大括号包裹起来,并以分号结束每个语句。
#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条评论
快来发表一下你的评论吧 !