可变参列表

在可变参数列表中,我们在没有对应的参数表示符时,如何获取参数列表,在可变参数列表中我们,只有"...",所以通过标示符得到是不可能的,于是我们只好寻找另一种方式去获取,我们知道函数在调用时都会返回地址,参数,等压入到分配的栈空间中。参数的入栈顺序会取决于你的调用约定,如stdcall cd call fastcall等等,因此其实参数的顺序是有顺序的,va_start(va_list va,last)我们可以通过last参数的地址,从而访问其他的参数.其实va_list 本质上只是char*类型

1)typedef char * va_list;_list 
2)#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
3)#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )

将最后一个参数的地址加上可变参数对其便宜后赋值给ap,即可变参数的首地址
4)#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

指向下一个参数的地址

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

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

void translate(va_list va,const char *cmd);
void myprintf(const char *cmd,...);

int main()
{
	myprintf("%s %d %c %f\n","aa",14,'b',3.14);
	return 0;
}

void myprintf(const char *cmd,...)
{
	va_list va;
	va_start(va,cmd);
	translate(va,cmd);
	va_end(va);
}

void translate(va_list va,const char* cmd)
{
	if('\0' == *cmd)
		return;
	if('%' != *cmd)
	{
		translate(va,cmd+1);	
	}
	else
	{
		switch(*(cmd+1))
		{
			case 'd':case 'x':case 'c':
			{
				char buf[3] = "%";
				buf[1] = *(cmd+1);
				int value;
				value = va_arg(va,int);
				printf(buf,value);	
			}
			break;
			case 'f':
			{
				double value = va_arg(va,double);
				printf("%f",value);
			}
			break;
			case 's':
			{
				char *value = va_arg(va,char*);
				printf("%s",value);
			}
			break;
			default:
				printf("%%");
				
		}
		translate(va,cmd+2);
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值