可变参数列表是通过stdarg.h内的宏来实现的:

类型 va_list

三个宏:

  va_start

  va_arg

  va_end

我们可以声明一个va_list变量,与这三个宏配合使用。

可变参数必须要有一个命名参数,因为可变参数是通过栈来实现的,函数中的最右边的参数最先入栈。

void function(int a, int b, int c)
{
int d;
...
}

其栈结构为

0x1ffc-->d

0x2000-->a

0x2004-->b

0x2008-->c

栈的空间是连续的,所以函数第一个必须是命名参数,这样就可以通过第一个参数来寻址,根据类型所占字节偏移,获取后续的所有可变参数值。

下面是利用可变参数计算平均值函数:

#include <stdarg.h>

float average(int n_num, ...)
{
int count;
float sum = 0; //var_arg是一个指针,通过va_start指向第一个命名参数位置
va_list var_arg;
va_start(var_arg, n_num); for (count = 0; count < n_num; count++) {
//va_arg第二个参数是类型,根据类型来偏移获取参数值
sum += va_arg(var_arg, int);
} //让指针指向NULL,不在指向堆栈
va_end(var_arg); return sum / n_num;
}

所以这些宏存在两个问题,一来无法确定参数数量,因为不同类型所占空间不同,二来无法确定类型,printf函数的类型是通过字符串中的格式字符串来提取类型实现的。

参考:http://blog.chinaunix.net/uid-20545038-id-1648593.html

     http://www.cnblogs.com/cpoint/p/3368993.html

C和指针 第七章 可变参数的更多相关文章

  1. C和指针 第七章 习题

    7.1 hermite递归函数 int hermite(int n, int x) { if (n <= 0) { return 1; } if (n == 1) { return 2 * x; ...

  2. C和指针第七章第五题

    实现一个简化的printf函数,能够处理%d,%f,%s,%c等格式. /*************************************************************** ...

  3. C和指针 第七章 函数递归与迭代

    C语言通过运行时堆栈支持递归函数的实现,递归函数时直接或者间接调用自身的函数,经常有人拿斐波那契实现当做递归的实现,然后这样做效率并不高. n < 1;  Fib(1) =1 n = 2;  F ...

  4. 【转载】va_list 可变参数 简介 va_copy vprintf

    [说明]本文转载自 smart 的文章 http://blog.sina.com.cn/s/blog_590be5290100qhxr.html  及百度百科 va_list是一个宏,由va_star ...

  5. C++可变参数列表处理宏va_list、va_start、va_end的使用

      VA_LIST是在C语言中解决变参问题的一组宏他有这么几个成员: 1)va_list型变量: #ifdef     _M_ALPHA typedef    struct{ char* a0; /* ...

  6. 【转】C++可变参数列表处理宏va_list、va_start、va_end的使用

    VA_LIST是在C语言中解决变参问题的一组宏他有这么几个成员: 1)va_list型变量: #ifdef     _M_ALPHA typedef    struct{ char* a0; /*po ...

  7. 可变参数以及stdcall

    void event_warnx(const char *fmt, ...) EV_CHECK_FMT(1,2); #define EV_CHECK_FMT(a,b) __attribute__((f ...

  8. C++逆向 可变参数Hook

    目录 C++逆向 可变参数Hook 0x00 前言: 0x01 C++可变参数: 可变参数简介 可变参数代码实战 0x02 逆向分析C++可变参数原理 0x03 printf Hook实战 Pwn菜鸡 ...

  9. C和指针 (pointers on C)——第七章:函数(上)

    第七章 函数 这一章对于有一定C的基础的人有一定优秀代码风格的人来说,并非非常虐.关于stdarg宏可能有些陌生.它负责可变參数列表的定义. 总结: 新式风格和旧式风格就不要提了.八百年前的事情. 函 ...

随机推荐

  1. 洛谷P1991无线通讯网[kruskal | 二分答案 并查集]

    题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫星电话线路的哨所(两边都 ...

  2. Linux 进程间通讯详解五

    msgrcv函数 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg); --功能:是从一个消息队列接 ...

  3. 初学C#和MVC的一些心得,弯路,总结,还有教训(1)--语言的选择

    因为惰性,自制力,求知欲等各方面原因....一直没有学新技术,总感觉VB6凑合能用就凑合用.... 于是大概从05年开始,几乎每次新版的vs一发布,我就下载回来,然后安装,然后,,,,就扔那了.... ...

  4. knockoutJS学习笔记01:从拼接字符串到编写模板引擎

    开篇 关于knockout的文章,园里已经有很多大神写过了,而且都写得很好.其实knockout学习起来还是很容易的,看看官网的demo和园里的文章,练习练习就可以上手了(仅限使用,不包含研究源码). ...

  5. 吉特仓储管系统(开源WMS)--分享两月如何做到10W+的项目

    在此文开篇之处先特别申明,此文在有些人的眼中会有广告的嫌疑,但是本人不想将其作为一个广告宣传的文章,在此提到软件内容部分请大家予以谅解和包含,作为时间不算短的程序员给大家分享一些自己开发吉特仓储管理软 ...

  6. Ceph RGW 和 niginx 配置要点

    cat /etc/nginx/sites-enabled/rgw.conf server { listen 80 default; #server_name .com .com.cn .net .cn ...

  7. net MVC 重定向总结

    [HttpPost] public ActionResult StudentList(string StudName, string studName, DateTime BirthDay, Form ...

  8. epub电子书--目录结构介绍

    epub电子书简介 epub全称为Electronic Publication的缩写,意为:电子出版, epub于2007年9月成为国际数位出版论坛(IDPF)的正式标准,以取代旧的开放Open eB ...

  9. 【poj2065】 SETI

    http://poj.org/problem?id=2065 (题目链接) 题意 题意半天看不懂..给你一个素数P(P<=30000)和一串长为n的字符串str[].字母'*'代表0,字母a-z ...

  10. bzoj2194: 快速傅立叶之二

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...