概述
【C语言笔记】【linux宏定义系列】 获取可变参数宏的参数数量
linux宏定义系列内容。用于记录在linux之中各式各样的宏定义☺。
宏定义说明
用于获取可变参数宏实际传递了多少个参数。
例如调用COUNT_ARGS(1, 2, 3),我们填入了3个参数,返回值就是3;COUNT_ARGS(1),我们填入了1个参数,返回值就是1。
实现代码
#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n
#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
宏定义中:
X...
用于填入参数。
注意:该宏传入的参数不能超过12个。如果传入的参数大于12个,那么这个宏将返回第13个参数的参数值。
示例程序
int main(int argc, char* argv[])
{
#define ARG2
arg2
printf("%dn", COUNT_ARGS());
printf("%dn", COUNT_ARGS(123));
printf("%dn", COUNT_ARGS(test, ARG2));
printf("%dn", COUNT_ARGS(123, test, ARG2));
printf("%dn", COUNT_ARGS(123, test, ARG2, "test"));
printf("%dn", COUNT_ARGS(123, test, ARG2, "test", 66));
return 0;
}
运行后,结果为
0
1
2
3
4
5
结果与预期一致。
打开预编译的.i
文件,看下宏的替换情况。
int main(int argc, char* argv[])
{
printf("%dn", 0);
printf("%dn", 1);
printf("%dn", 2);
printf("%dn", 3);
printf("%dn", 4);
printf("%dn", 5);
return 0;
}
直接被替换成了对应传递进去的参数数量。
实现过程
-
我们先看
__COUNT_ARGS
的实现#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n
这个宏要求至少传递14个参数,返回值就是这第14个参数。超过第14个的参数,会被
X...
给吸收走。 -
接下来再看下
COUNT_ARGS
的实现#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
这个宏本身至少向
__COUNT_ARGS
传递了14个参数,满足了宏__COUNT_ARGS
的需求。下面我们看下实际的使用情况。
传参示例
我们以上面示例程序中传递5个参数的情况进行举例:
COUNT_ARGS(123, test, ARG2, "test", 66)
展开后变为
__COUNT_ARGS(,123, test, arg2, "test", 66, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
传递了19个参数给
__COUNT_ARGS
,接下来我们再与__COUNT_ARGS
里的形参进行对应:_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X... , 123, test, arg2, "test", 66, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
可以看到
_n
的值等于5,宏返回的参数就是5,与传入的形参一致。没有参数的示例
接下来我们看下没有传递参数的情况。
当我们没有参数向
COUNT_ARGS
传递时,X
的值为空,, ##X
这部分会被删除。这里是使用了##
的语法,当X
为空字符串时,会连同最开始的,
被一并删除了。展开的效果如下:
__COUNT_ARGS(, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
有14个参数传递给
__COUNT_ARGS
,然后传递的参数与__COUNT_ARGS
里的形参进行一一对应:_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X... , 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
可以看到
_n
的值等于0,宏返回的参数就是0。从上述的示例可以看出,这个宏就是很巧妙的使用了可变参数宏的特性,将
X...
放在了参数列表的最前面,然后根据参数的数量,使_n
的值等于对应参数数量的值。注意事项
另外要注意传入的参数不能超过12个。如果传入的参数大于12个,那么这个宏将返回第13个参数的参数值。
这里为什么会返回第13个参数的参数值呢?
这里我们举个例子
COUNT_ARGS(123, test, ARG2, "test", 66, 123, test, ARG2, "test", 66, "test", 66, 987, 999)
展开后变为
__COUNT_ARGS(,123, test, arg2, "test", 66, 123, test, arg2, "test", 66, "test", 66, 987, 999, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
接下来我们再与
__COUNT_ARGS
里的形参进行对应:_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X... , 123, test, arg2, "test", 66, 123, test, arg2, "test", 66, "test", 66, 987, 999, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
会发现,超过12个参数之后,不管参数的数量是多少,
_n
对应的永远是第13个参数的值。
[参考资料]
linux kernel 5.8
/include/linux/kernel.h
本文链接:https://blog.csdn.net/u012028275/article/details/118853297
最后
以上就是疯狂斑马为你收集整理的【C语言笔记】【宏定义系列】 获取可变参数宏的参数数量【C语言笔记】【linux宏定义系列】 获取可变参数宏的参数数量宏定义说明实现代码示例程序实现过程[参考资料]的全部内容,希望文章能够帮你解决【C语言笔记】【宏定义系列】 获取可变参数宏的参数数量【C语言笔记】【linux宏定义系列】 获取可变参数宏的参数数量宏定义说明实现代码示例程序实现过程[参考资料]所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复