专栏首页嵌入式大杂烩【C语言笔记】变参函数

【C语言笔记】变参函数

提到变参函数,我们的感觉是不是既熟悉又陌生?感觉熟悉是因为我们平时都在使用着,如我们常使用的printf()函数与scanf()函数就是典型的变参函数。因为printf()函数是变参函数我们才可以根据我们的需要灵活地输出变量的值。如:

printf("hi");    //给printf函数传入1个参数
printf("%d\n",a);  //给printf函数传入2个参数
printf("%s  %d", str, a); //给printf函数传入3个参数
...
...                      //给printf函数传入n个参数

我们可以根据需要给printf()函数传入n个参数,这就是变参函数。

感觉陌生是因为我们没有试着创建变参函数。要创建变参函数需要包含头文件stdarg.h,并且创建变参函数应按照如下步骤进行:

【第一步】定义一个使用省略号的函数原型,如printf()与scanf()函数的原型为

int printf (const char *__format, ...)
int scanf (const char*, ...);

【第二步】在函数定义中创建一个va_list类型的变量,用于存储不定的参数;

【第三步】用宏va_start把该变量初始化为一个参数列表;

【第四步】用宏va_arg访问参数列表;

【第五步】用宏va_end完成清理工作。

示例程序:

#include <stdio.h>
#include <stdarg.h>

/*【第一步】:定义一个使用省略号的函数原型 */
double sum(int lim, ...)  
{
 /*【第二步】:声明一个va_list类型的变量ap */
 va_list ap;    
 double sum = 0;  // 用于保存参数之和
 int i;
 /*【第三步】:使用va_start把变量ap初始化为参数列表 */
 va_start(ap, lim); 
 for (i = 0; i < lim; i++)
 {
   /*【第四步】: 使用va_arg访问参数列表。 
   这里第二个参数是double类型,传入的不定参数就应是double类型
   */
   sum += va_arg(ap, double);  
 }
 /*【第五步】:使用va_end完成清理工作 */
 va_end(ap);  

 return sum;
}

int main(void)
{
 double sum1 = 0, sum2 = 0;
 /* 计算 */
 sum1 = sum(3, 1.1, 2.2, 3.3);  
 sum2 = sum(6, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
 printf("sum1 = %f\n", sum1);
 printf("sum2 = %f\n", sum2);
 return 0;
}

变参函数sum()用于求lim个数之和,并且这lim个数的类型必须是double类型,因为sum函数实体中使用va_arg访问参数列表中的参数类型为double类型。

程序输出结果为:

以上就是小编关于可变参数的一点小总结。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【C语言笔记】如何查看数据类型范围?

    当前的编译环境下,你可能不知道int的数据范围是多少,或者记不清无符号短整型的范围是0~65535还是0~65536?这时候就可以按照如下程序进行输出查看:

    正念君
  • 【STM32笔记】复用时钟何时开启呢?

    我们知道,STM32有很多外设,这些外设的外部引脚都是与GPIO共用的。我们可以通过软件来配置引脚作为GPIO引脚还是作为外设引脚。当引脚配置为外设引脚时就叫做...

    正念君
  • C编程练习003

    正念君
  • 放假整理的四个知识,附带小工具

    py 是脚本语言呀,不管是导包,还是定义函数,还是干嘛的,都是一行一行执行的。导入模块的时候,就会把模块内的所有代码执行一次,当然有缓存「pycache」文件,...

    清菡
  • JavaScript :ES6 的箭头函数,让你的代码更简洁

    本文由 Alone88 创作,采用 知识共享署名4.0 国际许可协议进行许可 本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名 最后编辑时间为...

    Alone88
  • ARM等硬件、Linux驱动内核面试问题

    user:非特权模式,大部分都在这种模式下工作 FIQ:快速中断模式 异常模式,特权模式 IRQ:普通中断模式 异常模式,特权模式 Supervisor:复位或...

    用户5426759
  • MeanShift算法C++解析(三)

    最后是最重要的核心啦,就是MeanShift_Tracking这个函数。同样的,我们先来看看这个函数的内部变量。

    钱塘小甲子
  • 面试Mybatis之类型处理器​(typeHandlers)

    无论是MyBatis在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换...

    小土豆Yuki
  • python国际化(i18n)和中英文切

    Python通过gettext模块支持国际化(i18n),可以实现程序的多语言界面的支持,下面是我的多语言支持实现:

    py3study
  • 聊聊JavaScript和Scala的表达式 Expression

    函数f的实现,会检查这两个参数的类型,如果是函数,则执行函数调用,再打印其返回值,否则直接打印传入的表达式的值。

    Jerry Wang

扫码关注云+社区

领取腾讯云代金券