不定参数函数的处理
不定参数的情形如: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(" "); printMultiParam_E(3,1,2,6); printf(" "); printMultiParam_ptrChar(3, "hello","world", "!"); printf(" "); printMultiParam_ptrChar_E(3,"hello", "world", "!"); //printMultiParam(3, "hello","world", "!"); return 0; }
程序输出为