c中不定参数情形的处理

不定参数函数的处理

    不定参数的情形如: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;
}

程序输出为


原文地址:https://www.cnblogs.com/OpenLinux/p/5020710.html