结构体中函数应该怎样定义才能返回值_单片机编程时可变参函数的实现

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

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

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

其实程序思路与我们常用的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 { sum+=va_arg(ap,int);//取得一个参数 } va_end(ap);//与va_start配对 return sum;}

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


技术考题:(关注电子技术控  -菜单栏-考题库)

ae0b9944bcc1ca1bd415150dfd3f5a29.png

4f127e0d3816f729fca8ff389aa466f8.png

关注(  电子技术控  )-学习干货、升职加薪、步步高升


6ed8960aa750341c014411751f10b991.gif 戳“

http://www.niftyadmin.cn/n/1425399.html

相关文章

jsf上下文取request

通过faces上下文和外部上下文获得request对象FacesContext facesContextFacesContext.getCurrentInstance();HttpServletRequest request (HttpServletRequest)facesContext.getExternalContext().getRequest(); 获得session对象HttpSession sessionrequest.getSession(); St…

Fixture_pytest

Fixture通常用来对测试方法,测试函数,测试类,和整个测试文件进行初始化或还原测试环境。 setup_module/teardown_module:在当前文件中,在所有测试用例执行之前与之后执行 setup_class/teardown_class:在当前…

*jsf的错误的提示

FacesMessage msg new FacesMessage(); msg.setSummary("两次输入的新密码不相同。"); msg.setDetail("两次输入的新密码不相同。"); //为了与原来例子保持一致,这里设置了消息的严重等级 …

图解python_图解数据结构--使用Python

章 数据结构导论 1 1.1 数据结构的定义 2 1.1.1 数据与信息 2 1.1.2 数据的特性 3 1.1.3 数据结构的应用 3 1.2 算法 5 1.3 认识程序设计 7 1.3.1 程序开发流程 8 1.3.2 结构化程序设计 8 1.3.3 面向对象程序设计 9 1.4 算法性能分析 11 1.4.1 Big-Oh 12 1.4.2 Ω 15 1.4.3 θ …

权限树

权限系统示例应用程序软件工程从需求,设计,编码,测试和发布等流程。RBAC即基于角色的访问控制系统,它以角色role为中心构成。用户->角色->  权限(操作,对象)三个表person,role,permissi…

pytest参数化

import pytest import math#pytest参数化 pytest.mark.parametrize("base,exponent,expected",[(2,2,4),(2,3,8),(1,9,1),(0,9,0)],ids["case1","case2","case3","case4"] )def test_pow(base,exponent,expected):assert ma…

c++ 快速排序_快速入门基数排序

数据结构排序算法之基数排序演示_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com通过示例理解基数排序假设我们有 10 万个手机号码,希望将这 10 万个手机号码 从小到大排序,你有什么比较快速的排序方法呢?归并排序、快排&#xff0c…

pytest运行测试

-s:用于关闭捕捉,从而输出打印信息 -v:用于增加测试用例冗长 -q:减少测试的运行冗长,也可以用--quiet代替 -k:运行名称中包含某字符串的测试用例 例如:pytest -k add test_assert.py 运行t…