可变参数列表

原创 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;
}




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

Java的可变参数列表

1.什么是Java的可变参数列表 请阅读下面的示例代码: public class Main { public void printf(String... args) { for (String...
  • hu285279904
  • hu285279904
  • 2014年12月17日 23:10
  • 2309

【c语言】用可变参数列表实现一个简化的printf函数

//实现一个简化的printf函数。 #include #include void my_printf(const char *str,...) { va_list arg; //准备...
  • zhaoyaqian552
  • zhaoyaqian552
  • 2015年04月06日 16:46
  • 730

可变参数列表(...)

如果有一组事物,可以把它们当作列表传递,如果有了一个数组,可把它们当作可变参数类表传递 java SE5之前 可变参数列表 public class ke_bian_can_shu_lie_bia...
  • fuckluy
  • fuckluy
  • 2015年12月14日 17:45
  • 181

从头认识java-4.8 数组的初始化(2)-可变参数列表

接着上一节,我们这一章节来聊一下数组的另外一个应用:可变参数列表1.可变参数列表带来的改变在没有出现可变参数列表的时候,我们一般会使用数组来替代,但是有一个问题,每一次都需要先建立一个数组作为参数,不...
  • raylee2007
  • raylee2007
  • 2015年10月28日 09:46
  • 1519

可变参数列表

可变参数列表 1.stdarg宏        可变参数列表是通过宏来实现的,这些宏定义于stdarg.h头文件,它是标准库的一部分。这个头文件声明了一个类型va_list和三个宏-------v...
  • qdlgdx_lsy
  • qdlgdx_lsy
  • 2013年11月04日 10:34
  • 635

全面解析C语言中可变参数列表

全面解析c语言中可变参数列表问题:1、大众版:大家习惯的使用方式;2、真实版:真正的使用方式;3、实际原理:具体原理,本质;4、自己实现可变参数列表:理解本质后,自己用自己的方法来实现可变参数列表;5...
  • YuZhiHui_No1
  • YuZhiHui_No1
  • 2015年02月11日 15:27
  • 7044

/可变参数列表

package com.cn.test8; //可变参数列表 public class Test2 { /** * @param args */ public static void m...
  • u014657292
  • u014657292
  • 2014年04月16日 15:17
  • 382

C语言可变参数列表应用——多字符串复制和链接

C标准库中头文件中包含可变参数列表的实现,完成遍历未知数目和类型的函数参数列表的功能。提供以下3个宏以及va_list变量:                 va_start(va_list ap,...
  • chosen0ne
  • chosen0ne
  • 2012年10月17日 23:27
  • 3996

可变参数列表浅析

1,什么是可变参数? 我们在C语言编程中会遇到一些参数个数可变的函数,例如printf()这个函数,它的定义是这样的:       int printf( const char* format, ...
  • lengxinxuexic
  • lengxinxuexic
  • 2017年11月20日 20:09
  • 56

Java 可变参数列表

应用场景可变参数列表应用于不确定参数个数和参数类型的时候基本语法public class Varargs { public static void main(String[] args) { ...
  • Lirj_
  • Lirj_
  • 2017年05月18日 23:39
  • 87
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:可变参数列表
举报原因:
原因补充:

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