不定参数函数的处理
不定参数的情形如:void printMultiParam(int count, ...),对于与C中的printf与scanf等函数都属于这种情形。下边就其原理和处理方式进行说明:
原理:c++参数栈为从高地址向低地址增长,函数参数的入栈顺序为从右到左(即右边参数在高地址空间)。针对这种不定参数的处理,c语言有相关的函数可以处理(va_list, va_arg等宏,在下面有说明),同时,由原理我们也可以自己做一个简单的模拟。 废话不多说,下面直接进入程序:
#include<stdlib.h>
#include<stdarg.h>
#include<iostream>
usingnamespace std;
/*模拟多个int型参数*/
//根据原理对栈指针进行操作,模拟输出多个int型
voidprintMultiParam(int count, int a, ...)
{
char *pInt = (char *)&a;
for(int i = count; i > 0; i--)
{
cout<<(int)(*pInt)<<endl;
pInt+=sizeof(int);
}
}
/*
采用va_list/ va_start/ va_arg/ va_end实现
包含头文件stdarg.h
typedef char * va_list;
#define va_start(ap,v) ( ap =(va_list)&v + _INTSIZEOF(v) ) //获取第一个参数地址,其中_INTSIZEOF(v)相当于sizeof(v)
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) -_INTSIZEOF(t)) ) //可知获取了字段的地址
#define va_end(ap) ( ap = (va_list)0 ) //做最后的清理工作
*/
voidprintMultiParam_E(int count, int a, ...)
{
va_list ap;
va_start(ap, count);
for(int i = count; i > 0; i--)
{
int pInt = va_arg(ap,int);
cout<<pInt<<endl;
}
va_end(ap);
}
/*模拟多个char *型参数*/
//根据原理对栈指针进行操作,模拟输出多个char*型
voidprintMultiParam_ptrChar(int count, char *a, ...)
{
//va_list list;
//va_start();
char *pChar = (char *)&a; //这里&不能少
for(int i = count; i > 0; i--)
{
cout<<*(char**)pChar<<endl; //这边也得这样写,才能打印正确
pChar += sizeof(char *);
}
}
//采用va_list等函数实现
voidprintMultiParam_ptrChar_E(int count, char *a, ...)
{
va_list ap;
va_start(ap, count);
for(int i = count; i > 0; i--)
{
char *pStr = va_arg(ap,char *);
cout<<pStr<<endl;
}
va_end(ap);
}
int main(int argc, char **argv)
{
printMultiParam(3,1,2,6);
printf("\n");
printMultiParam_E(3,1,2,6);
printf("\n");
printMultiParam_ptrChar(3, "hello","world", "!");
printf("\n");
printMultiParam_ptrChar_E(3,"hello", "world", "!");
//printMultiParam(3, "hello","world", "!");
return 0;
}
程序输出为