码迷,mamicode.com
首页 > 编程语言 > 详细

C语言可变参数va_list

时间:2017-10-20 16:07:52      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:va_list c/c++

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

/*
1. 使用va_list va_start va_arg va_end实现可变参数
*/
void simple_va_fun(int i, ...) {
	va_list arguments;
	int j = 0;
	int k, m;
	va_start(arguments, i);
	j = va_arg(arguments, int);
	m = va_arg(arguments, int);
	va_end(arguments);

	printf("%d,%d,%d\n",i,j,m);

}

/*
2. 固定参数函数
*/
void fixed_args_func(char x, int a, double b, char *c)
{	//打印参数在栈中的地址
	printf("x = 0x%p\n", &x);
	printf("a = 0x%p\n", &a);
	printf("b = 0x%p\n", &b);
	printf("c = 0x%p\n", &c);
}
/*
3. 实现自己的可变参数,实则是按顺序从栈中取出参数的值
*/
void var_args_func(const char * fmt, ...) {
	char* ap;
	ap = (char *)&fmt + sizeof(fmt);

	int* int_ap = (int *)ap;
	printf("first:%d\n",*int_ap);

	int_ap = int_ap + 1;

	printf("second:%d\n",*int_ap);

	int_ap = int_ap + 1;// string start index
	char* c_ptr = (char*)int_ap;

	char* str = (char* )*int_ap;

	printf("&int_ap = 0x%p\n",int_ap);
	printf("&c_ptr  = 0x%p\n", c_ptr);
	printf("&str    = 0x%p\n",str);
	
	//栈里面存储的是指向字符串"helloworld的指针",即二级字符指针
	printf("third1:	%s\n",str);
	printf("third2:	%s\n", *(char **)int_ap);



}
//stdarg.h 中提供的标准可变参数宏
void std_vararg_func(const char *fmt, ...) {
	va_list ap;
	va_start(ap, fmt);

	printf("%d\n", va_arg(ap, int));
	printf("%f\n", va_arg(ap, double));
	printf("%s\n", va_arg(ap, char*));

	va_end(ap);
}

int main() {

	
	//fixed_args_func(‘a‘,17, 5.40, "hello world");

	//char* p = "xiongwei";
	//printf("%d\n",sizeof(p));
	var_args_func("%d %d %s\n", 4, 5, "helloworld");
	printf("--------------------------------------\n");
	std_vararg_func("%d %f %s\n", 4, 5.4, "helloworld");

	system("pause");
	return 0;
}

对比一下 std_vararg_func和var_args_func的实现,va_list似乎就是char*, va_start似乎就是((char*)&fmt) + sizeof(fmt),va_arg似乎就是得到下一个参数的首地址。没错,多数平台下stdarg.h中va_list, va_start和var_arg的实现就是类似这样的。一般stdarg.h会包含很多宏,看起来比较复杂。在有的系统中stdarg.h的实现依赖some special functions built into thethe compilation system to handle variable argument lists and stack allocations,多数其他系统的实现与下面很相似:(Visual C++ 6.0的实现较为清晰,因为windows上的应用程序只需要在windows平台间做移植即可,没有必要考虑太多的平台情况)。

output://

first:4

second : 5

& int_ap = 0x003EF968

& c_ptr = 0x003EF968

& str = 0x013780D4

third1 : helloworld

third2 : helloworld

--------------------------------------

4

5.400000

helloworld


C语言可变参数va_list

标签:va_list c/c++

原文地址:http://xwandrew.blog.51cto.com/2909336/1974600

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!