可变参数列表

原创 2016年08月30日 21:27:20

在很长的一段时间里,我都感觉可变参数列表难!很难! 

今天又遇到了这个难题。起因是要写一个求和的函数,函数的参数不确定。这就需要使用可变参数列表来实现。然我写不出来。脾气上来了决定好好研究一下这个,然后开始查源码,研究了一下突然发现好简单……

可变参数列表是怎么实现的呢?举个例子可能更好理解

现在需要写一个对参数求和的函数,传入的参数不确定。参数原型 int Sum(size_t N,  ...);

接下来需要知道实现可变参数的工具:一个类型va_list,三个宏va_start、 va_arg、 va_end。不要被这四个单词吓着了(虽然今天之前我也是这样)。

va_list:

它的真面目是这样的, typedef char*   va_list;说白了它就是一个char * ,用来定义变量访问访问可变参数。

va_list arg;


va_start:

va_start(arg,N); 
va_start的作用是将arg指向可变参数部分的第一个参数。比如Sum(3,1,2,3); va_start 会将arg指向1。具体操作如下:

(1)拿到N的地址,强转为va_list类型,然后赋给arg

(2)arg向后偏移N的大小个字节,指向N后面的参数,即可变参数的第一个参数

vs2013中的源码是这样的:

#define  va_start   _crt_va_start
#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
#define _ADDRESSOF(v)   ( &(v) )
#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )<span style="font-size: 12px; font-family: Arial, Helvetica, sans-serif;">//这样写是为了字节对齐,详解http://www.cnblogs.com/diyunpeng/archive/2010/01/09/1643160.html</span>

 

va_arg:

ret += va_arg(arg, int);

va_arg会返回当前arg指向的参数的值,同时会让arg指向下一个参数。具体操作如下:

(1)让arg指向下一个参数,即arg+=sizeof(int);

(2)返回arg之前指向的参数的值,即 *(int*)(arg - sizeof(int))

vs2013中的代码:

#define va_arg   _crt_va_arg
#define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )


va_end:

va_end(arg);
将arg赋为NULL,防止野指针

#define va_end   _crt_va_end
#define _crt_va_end(ap)      ( ap = (va_list)0 )

so 函数Sum的完整实现如下:

int Sum(size_t N, ...)
{
	int ret = 0;
	va_list arg;
	va_start(arg, N);
	while (N--)
	{
		ret += va_arg(arg, int);
	}

	va_end(arg);
	
	return ret;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

数组的顺序表示和实现:利用可变参数列表实现多维数组的创建

数组的顺序表示和实现:利用可变参数列表实现多维数组的创建

奇特的可变参数列表实现print函数

熟悉C的人都知道,C语言支持可变参数函数(Variable Argument Functions),即参数的个数可以是不定个,在函数定义的时候用(...)表示,比如我们常用的printf()\exec...

可变参数列表详解(内附求平均数和实现简单的printf)

在求平均数的时候,如果数字只要少数的几个,那么我们可以依次给函数传参。可是,如果数字很多怎么办,数字类型不同又怎么办?难道要写出每个实参对应的形参吗?C语言是非常聪明的,这时候就出现了可变参数列表。1...
  • IT_10
  • IT_10
  • 2016年10月29日 20:43
  • 286

可变参数列表的简单实现

使用可变参数列表实现一个sum函数 #include #define _AUPBND (sizeof (int) - 1) #define _ADNBND (siz...

C语言可变参数列表编程

最近在看一份代码,想定义一些自己的打印信息。但是其中涉及到C语言可变参数的编程,虽然之前了解相关的内容,但还不是很熟练,不得不重新温故一下。如下代码权当记录基本的用法,很多原理还说不上来。 #incl...

求任意多个数的最大值(利用可变参数列表)

#include #include int Max(int n, ...) { int i = 0; int max = 0; va_list arg; va_sta...

gcc宏定义可变参数列表(__VA_ARGS__)

gcc编译器宏定义做了许多扩展,支持宏定义的可变参数

Linux 源码系列之可变参数列表实现

背景从事 android 开发四年有余,应用开发做得越久,就越有“知其然不知其所以然”的感觉,于是乎,过去的大半年,我几乎一有时间就去啃《Linux内核完全剖析-基于0.12内核》,接近1000页的 ...

专题6-2,可变参数列表与宏分析(国嵌C语言视频)

1. 问 如何编写一个可以计算n个数平均值的函数? 答; #include float func(int array[], int size) { int i = 0; flo...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:可变参数列表
举报原因:
原因补充:

(最多只允许输入30个字)