1、可变参数表是通过宏实现的

宏定义于stdarg.h头文件,它是标准库的一部分.这个头文件声明了一个类型var_list和三个宏--va_start、va_arg、va_end.

我们可以声明一个类型为va_list的变量,与这几个宏配合使用,访问参数的值.

参数列表在函数中用三点省略号(...).它表示此处可能传递数量和类型未定的参数.函数原型和函数的定义都要这样做.

函数中要声明一个名叫 va_arg 的变量,它用于访问参数列表的未定部分.这个变量通过调用va_start来初始化.它的第一个参数是var_list变量的名字.第2个参数是省略号前最后一个有名字的参数.初始化过程把va_arg变量设置为指向可变参数部分的第一个参数.

为了访问参数,需要使用,va_arg,这个宏接收两个参数:va_list变量和参数列表中下一个参数的类型.在这个例子中,所有的可变参数都是整型.在有些函数中,你可能要通过前面获得的数据来判断下一个参数的类型. va_arg返回这个参数的值,并使var_arg指向下一个可变参数.

最后,当反问完毕最后一个可变参数之后,我们需要调用va_end;

2、可变参数的限制

可变参数必须从头祷文按照顺序逐个访问.可以访问到一半终止,但是不可以一开始就访问参数列表中间的参数.
由于参数列表中的可变参数部分并没有原型,所以所有作为可变参数传递给函数的值都将执行缺省参数类型提升.
/**
可变参数的定义,求平均值 @param n_values 参数表中参数的个数
@param ... 可变参数表
@return 平均值
*/
float average(int n_values, ...){
va_list var_arg;
int count;
float sum = 0;
//准备访问可变参数
va_start(var_arg, n_values);
//添加取自可变参数列表的值
for (count = 0; count < n_values; count += 1) {
sum += va_arg(var_arg, int);
}
//完成处理可变参数
va_end(var_arg);
return sum/n_values;
}

C和C指针小记(十二)-函数的可变参数表的更多相关文章

  1. C和C指针小记(十)-函数

    1.函数的定义 函数的定义就是函数体的实现. 语法: 类型 函数名(形式参数) 代码块 函数返回类型和函数名分开写是代码风格的问题,现代语言如swift返回值在函数名和参数表的后面,这样使得某些工程工 ...

  2. 深入理解PHP内核(十二)函数-函数的定义、传参及返回值

    原文链接:http://www.orlion.ga/344/ 一.函数的定义 用户函数的定义从function 关键字开始,如下 function foo($var) {    echo $var; ...

  3. C和指针 第十二章 结构体 习题

    12.3 重新编写12.7,使用头和尾指针分别以一个单独的指针传递给函数,而不是作为一个节点的一部分 #include <stdio.h> #include <stdlib.h> ...

  4. C和指针 第十二章 使用结构和指针

    链表是一种常用的数据结构,每个节点通过链或者指针链接在一起,程序通过间接指针访问链表中的节点. typedef struct Node { //指向下一个节点的指针 struct Node *next ...

  5. C和C指针小记(十八)-使用结构和指针-双向链表

    1.双链表 1.1 双向链表的声明 在一个双链表中,每个节点都包含两个指针--指向前一个节点的指针和指向后一个节点的指针. 声明 typedef struct NODE { struct NODE * ...

  6. C和C指针小记(十六)-动态内存分配

    动态内存分配 1.1 为什么使用动态内存分配 直接声明数组的方式的缺点: 1) 声明数组必须指定长度限制.无法处理超过声明长度的数组. 2) 如果声明更大的常量来弥补第一个缺点,会造成更多的内存浪费. ...

  7. C和C指针小记(十四)-字符串、字符和字节

    1.字符串 C语言没有字符串数据类型,因为字符串以字符串常量的形式出现或存储于字符数组中. 字符串常量和适用于那些程序不会对他们进行修改的字符串. 所有其他字符串都必须存储于字符串数组或动态分配的内存 ...

  8. C和C指针小记(一)-字符输入,函数,ASCII扩展表

    1.连续接收输入字符时 int ch; while(ch != EOF && ch != '\n') ch 为什么被声明为整形,我们不是需要用它来读取字符的嘛? 因为:EOF是一个整形 ...

  9. C++ template —— 智能指针(十二)

    在管理动态分配的内存时,一个最棘手的问题就是决定何时释放这些内存,而智能指针就是用来简化内存管理的编程方式.智能指针一般有独占和共享两种所有权模型.-------------------------- ...

随机推荐

  1. ListView中的Item点击事件和子控件的冲突或者item点击没有反应的解决的方法

    fragment中加入了button和checkbox这些控件.此时这些子控件会将焦点获取到.所以经常当点击item时变化的是子控件.item本身的点击没有响应. 这时候就能够使用descendant ...

  2. Django TemplateDoesNotExist

    在联系Django的时候,启动正常,我在浏览器上输入URL地址后报错 TemplateDoesNotExist at /test/ 解决方案 默认这里是空的,这里我们填上我们静态文件的地址

  3. Redis高可用详解:持久化技术及方案选择

    文章摘自:https://www.cnblogs.com/kismetv/p/9137897.html 前言 在上一篇文章中,介绍了Redis的内存模型,从这篇文章开始,将依次介绍Redis高可用相关 ...

  4. 转移 Visual Studio 2017 的安装临时文件

    每次更新 Visual Studio 2017 会在 C 盘留下大量的缓存文件,因为目录比较深,怕以后忘了,用目录链接的形式转移到其它磁盘,也好方便清理: mklink /D C:\ProgramDa ...

  5. [Android实例教程] 教你如何拍照+相册选择图片+剪裁图片完整实现

    [Android实例教程] 教你如何拍照+相册选择图片+剪裁图片完整实现 今天做Android项目的时候要用到图片选择,要实现拍照获取图片和从相册获取图片,并且要求在获取完之后可以裁剪,试了很多方法之 ...

  6. 译:7.使用Spring MVC服务Web内容

    本指南向您介绍了使用Spring创建“hello world”网站的过程.阅读原文:Serving Web Content with Spring MVC 1. 你将会构建什么? 您将构建一个具有静态 ...

  7. 基于Docker的redis集群搭建

    Redis集群官方介绍:http://www.redis.cn/topics/cluster-tutorial.html 基于Docker搭建Redis集群 环境:6个节点,三主三从 制作Redis镜 ...

  8. 【九天教您南方cass 9.1】 05 打印出图

    同学们大家好,欢迎收看由老王测量上班记出品的cass9.1视频课程 我是本节课主讲老师九天. 我们讲课的教程附件也是共享的,请注意索取测量空间中. [点击索取cass教程]5元立得 (给客服说暗号:“ ...

  9. 嵌入式开发之UDP 丢包--- UDP 丢包控制方法

    0. 发送端可以,发送五次左右,再Sleep 1.调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失.对于这种情况可以修改接收 ...

  10. 安卓开发笔记——个性化TextView(新浪微博)

    这几天在仿写新浪微博客户端,在处理微博信息的时候需要处理关键字高亮和微博表情,查了一些资料,决定记录点东西 先来看下效果图: 像以上这种#话题#,@XXX昵称,HTTP:网页链接等元素,在微博里是被高 ...