C/C++ 变参函数详解

C/C++ 变参函数详解

1.   简介

调用函数的实现原理是:执行跳转+参数传递。执行跳转,所有的CPU都提供跳转指令;参数传递,CPU会提供多种方式,最常见的是使用栈来传递参数。

2.   变参函数示列

头文件 #include <stdarg.h>

void f2(char* fmt, ...)

{

    va_listap;

    va_start(ap, fmt);

 

    char*p = fmt;

    while(*p) {

       if(*p == '%'&& *(p+1) == 'd') {

           printf("参数类型为int,值为%d\n", va_arg(ap, int));

       }

       elseif (*p == '%' && *(p+1)== 'f') {

           printf("参数类型为double,值为%f\n", va_arg(ap, double));

       }

       elseif (*p == '%' && *(p+1)== 's') {

           printf("参数类型为char*,值为%s\n", va_arg(ap, char*));

       }

       p++;

    }

    va_end(ap);

}

typedef struct BLKONEGROUPTAGFLAG

{

    boolbTagIn;

    boolbTagOut;

    boolbTagValue;

    boolbTagPoint;

    int  nValueSize;

    int  nPointInSize;

    int  nPointOutSize;

}BLKONEGROUPTAG;

// "in,v,4;in,p,%d"

void Serialize(char* fmt, ...)

{  

    va_listap;          // 定义一个变参函数列表变量

    va_start(ap, fmt);  // 将变量初始化指向变参函数

 

    char*pszCurrFmt = newchar(strlen(fmt)+1);

    strcpy_s(pszCurrFmt, strlen(fmt)+1, fmt);

 

    char*pRes = pszCurrFmt;

    char*pRet = NULL;

    char*pszContext = NULL;

 

    boolbTagIn = false;

    while( pRet = strtok_s(pRes, ";",  &pszContext))     

    {

       BLKONEGROUPTAGblkOneGruop;

       memset(&blkOneGruop, 0, sizeof(BLKONEGROUPTAG));

 

       char*pRes2 = pRet;

       char*pszContext2 = NULL;

       while( pRet = strtok_s(pRes2, ",",  &pszContext2))

       {

           char*p = pRet;

           if( *p == 'i'&& *(p+1) == 'n' )

           {

              blkOneGruop.bTagIn = true;

           }

           elseif ( *p == 'o' && *(p+1)== 'u' && *(p+2)== 't' )

           {

              blkOneGruop.bTagOut = true;

           }

           elseif ( *p == 'v' )

           {

              blkOneGruop.bTagValue = true;

           }

           elseif ( *p == 'p' )

           {

              blkOneGruop.bTagPoint = true;

           }

           else

           {

              if ( true == blkOneGruop.bTagIn&& true == blkOneGruop.bTagOut && true== blkOneGruop.bTagPoint)

              {

                  blkOneGruop.nPointInSize= atoi(p);

              }

              else if ( true== blkOneGruop.bTagOut&& true == blkOneGruop.bTagPoint )

              {

                  blkOneGruop.nPointOutSize= atoi(p);

              }

              else if ( true== blkOneGruop.bTagIn&& true == blkOneGruop.bTagPoint )

              {

                  blkOneGruop.nPointInSize= atoi(p);

              }

              else if ( true== blkOneGruop.bTagIn)

              {

                  blkOneGruop.nValueSize= atoi(p);

              }

           }

           pRes2= NULL;

       }

       //解析结构体

       void*pvParam = NULL;

       char*pszData = NULL;

       if( true == blkOneGruop.bTagPoint && true== blkOneGruop.bTagIn)

       {

           pvParam= va_arg(ap,void*); //  传进来的是什么,取出来的就是什么

           pszData= (char*)(*(void**)pvParam);

       }

       elseif ( true == blkOneGruop.bTagPoint&& true == blkOneGruop.bTagOut )

       {

           pvParam= va_arg(ap,void*);

       }

       pRes= NULL;

    }

    va_end(ap);

}

 

int main()

{

    // 测试

    f2("%d,%f,%s", 100, 1.23, "hello world");

    getchar();

 

    char*psz = NULL;

    char*pszIn = "123";

    Serialize("in,v,4;in,p,64;out,p,32", &pszIn,&psz);

    getchar();

    return0;

}

附录:参考资料

https://blog.csdn.net/smstong/article/details/50751121

猜你喜欢

转载自blog.csdn.net/barry1020441722/article/details/79743014
今日推荐