单片机编程时可变参函数的实现

2020-8-7 18:04 1302 43

新的多功能使用主控+模块块的设计,板与板之间使用自定的协议来传递数据,在程序书写上, 我希望写成一个通用的数据协议,这样这个协议可以在后续直接移植我以后相当长一个时间内的其它产品上,这其中就需要用到可变参函数。

那么可变参函数如何实现呢。。。

我在这儿简单写一写, 有遇到类似问题的朋友们可以参考参考。

其实程序思路与我们常用的printf相同。

我们先来看看printf:

int printf(const char *format, ...);

看到上面的…了没,这个就表示在format 参数后有不定个数的参数。

比如:

printf("%s %d %c\n", "abc", 10, 'A');
  • format是"%s %d %c\n"
  • 其后不定参数部分有三个参数,分别为字符数组类型、整型、字符型。
  • 具体实现:

    我们需要使用stdarg.h头文件下声明的函数和数据类型来完成,这里我用到了一个数据类型和3个函数类型:

  • va_list类型
  • void va_start(va_list ap, last);
  • type va_arg(va_list ap, type);
  • void va_end(va_list ap);
  • 在使用可变参部分前,首先要定义一个va_list变量,后续需要用到这个变量

    先来看看三个函数的说明:

    a_start

    这个函数有两个参数,第一个参数是我们定义的va_list变量,第二个参数是可变参...左侧最靠近...的变量名,本例为fmt。通过这个函数就可以定位到可变参部分的位置了。

    va_arg

    这个函数(暂且当函数看吧)用于获取每一个可变参数,由其声明可以看到,返回值为我们需要的类型,函数参数为va_list变量和我们期望的函数类型。

    va_end

    用于销毁va_list结构所使用的资源。

    可变数量参数函数定义形式为:

    type functionName(type argName, ...)

    {

    }

    即一般至少第一个参数类型是已知的,后面的参数可以使用三个点来代替(注意是英文编码)。

    使用时,在函数体中需要定义一个va_list的变量,相当于可变参数的列表,使用va_start将函数参数加载到va_list列表当中。形式为va_start(va_list变量,函数参数),这样在后面即可以使用va_arg(va_list变量,变量类型)获取当前变量的值,并且每调用一次va_arg后变量指针就会后移一次。操作完成后应使用va_end(va_list变量)结束,否则在某些场合会导致内存泄漏。

    long get_sum(int artCnt,...)//第一个参数为参与计算的数字的个数
    {
    va_list ap;//定义可变参数列表
    long sum = 0;//
    int i = 0; //
    va_start(ap,artCnt);//取得参数列表
    for(i = 0; i<artCnt; i++)
    {
    sum+=va_arg(ap,int);//取得一个参数
    }
    va_end(ap);//与va_start配对
    return sum;
    }

    到这里,一个可变参函数就实现了。

    推荐阅读
    (新基建5g网络)5G和口罩哪个更重要,美国进口中国商品关税? 2020-05-26 14:44
    比一比,安卓手机麒麟980和骁龙855哪个好?测试跑分、通信性能 2020-03-19 12:30
    Covid-19无线电影响,主流业余电台型号加速了销声匿迹? 2020-08-05 16:31
    lenovo联想液晶显示器故障不用“烧机”原因:电容短路导致 2021-07-28 17:34
    高速设计差分线也有差模,共模,奇模,偶模? 2020-03-06 12:20