我是靠谱客的博主 疯狂斑马,最近开发中收集的这篇文章主要介绍【C语言笔记】【宏定义系列】 获取可变参数宏的参数数量【C语言笔记】【linux宏定义系列】 获取可变参数宏的参数数量宏定义说明实现代码示例程序实现过程[参考资料],觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

【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;
}

直接被替换成了对应传递进去的参数数量。

实现过程

  1. 我们先看__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...给吸收走。

  2. 接下来再看下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宏定义系列】 获取可变参数宏的参数数量宏定义说明实现代码示例程序实现过程[参考资料]所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部