现在的位置: 首页 > 综合 > 正文

浅析可变参数函数

2018年02月08日 ⁄ 综合 ⁄ 共 1012字 ⁄ 字号 评论关闭
int ejArgs(int argc, char_t **argv, char_t *fmt, ...)
{
	va_list	vargs;
	char_t	*cp, **sp;
	int		*ip;
	int		argn;
/*
va_start(va_list vap, 最后一个普通参数)
va_start(vargs, fmt); 相当于  char *vargs= (char *)&fmt + sizeof(int);
此时vap正好指向n后面的可变参数表中的第一个参数。
实质是宏定义:

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )
*/
	va_start(vargs, fmt);

	if (argv == NULL) {
		return 0;
	}

	for (argn = 0, cp = fmt; cp && *cp && argv[argn]; ) {
		if (*cp++ != '%') {
			continue;
		}

		switch (*cp) {
		case 'd':
/*
类型 va_arg(va_list vargs, 类型名)
取得可变变量参数地址
在第一次使用va-arg时,它返回可变参数表中的第一个参数,后续的调用都返回表中的下一个参数
实质是宏定义:
#define va_arg(ap,type)    ( *(type *)((ap += _INTSIZEOF(type)) - _INTSIZEOF(type)) )
*/
			ip = va_arg(vargs, int*);
			*ip = gatoi(argv[argn]);
			break;

		case 's':
			sp = va_arg(vargs, char_t**);
			*sp = argv[argn];
			break;

		default:
			a_assert(0);
		}
		argn++;
	}
/*
功能就是把指针ap赋值为0,使它不指向内存的变量
实质是宏定义:
#define va_end(ap)      ( ap = (va_list)0 )
*/
	va_end(vargs);
	return argn;
}

使用:
 ejArgs(argc, argv, T("%d %s"), &type, &field);
中心点:
函数调用中,参数在堆栈中是顺序存放,取得最后一个普通参数地址,可以依次取得堆栈中存放的其他参数地址。

参考博客:

http://blog.csdn.net/hackbuteer1/article/details/7558979#

抱歉!评论已关闭.