• C++.可变参数_ZC测试


    ZC:环境: Win7 x64(旗舰版),Microsoft Visual Studio 2010(版本 10.0.30319.1 RTMRel, Microsoft .NET Framework(版本 4.0.30319 RTMRel))

    1、代码:

    #include <stdio.h>
    #include <stdarg.h>
    #include <windows.h>
    
    int sum(int count, ...);//原型中使用省略号
    
    // 函数的参数为:DWORD _dw, HWND _h, char* _pc
    void TextZ(int _n, ...)// ZC: 貌似无法动态获得参数的个数,∴只能在参数中带上参数的个数(需要的话),我一般放在可变参数前面的位置。
    {
        va_list ap;//声明一个va_list变量
        va_start(ap, _n);//初始化,第二个参数为最后一个确定的形参// ZC: 需要 参数个数 作为函数va_start(...)的参数
    
        // ZC: 貌似参数只能依次取,不能随机取?
        DWORD dw = va_arg(ap, DWORD);//读取可变参数,的二个参数为可变参数的类型
        HWND h = va_arg(ap, HWND);
        char* pc = va_arg(ap, char*);
    
        va_end(ap);//清理工作
    
        // ***
    
        printf("DWORD : %d, HWND : %d, char* : %s
    ", dw, h, pc);
    }
    
    // 下面的函数 和 上面的函数 几乎一模一样,只是这里是使用 指针来取得可变参数,这里是尝试其可行性
    void TextZ01(int _n, ...)// ZC: 貌似无法动态获得参数的个数,∴只能在参数中带上参数的个数(需要的话),我一般放在可变参数前面的位置。
    {
        va_list ap;//声明一个va_list变量
        va_start(ap, _n);//初始化,第二个参数为最后一个确定的形参// ZC: 需要 参数个数 作为函数va_start(...)的参数
    
        // ZC: 貌似参数只能依次取,不能随机取?
        DWORD* pdw = &va_arg(ap, DWORD);//读取可变参数,的二个参数为可变参数的类型
        HWND* ph = &va_arg(ap, HWND);
        char** ppc = &va_arg(ap, char*);
    
        va_end(ap);//清理工作
    
        // ***
    
        printf("DWORD : %d, HWND : %d, char* : %s
    ", *pdw, *ph, *ppc);
    }
    
    void main()
    {
        //int i = sum(3, 4,5,6);
        //printf("sum : %d
    ", i);
    
        TextZ(3, 567, 30303030, "TextZ");
        TextZ01(3, 567, 30303030, "TextZ");
        system("pause");
    }
    
    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    
    int sum(int count, ...)//count 表示可变参数个数
    {
        va_list ap;//声明一个va_list变量
        va_start(ap, count);//初始化,第二个参数为最后一个确定的形参
    
        int sum = 0;
        for(int i = 0; i < count; i++)
            sum += va_arg(ap, int);//读取可变参数,的二个参数为可变参数的类型
    
        va_end(ap);//清理工作
        return sum;
    }

    2、控制台输出:

      

    3、

    4、自己的包装函数(1)

      ZC:主要是在 函数内部去使用 sprintf_s(...) 来组合字符串,省的写在外面(写在外面 代码太多太乱 看不清晰)

      ZC:下面,函数传入的可变参数 都是 DWORD类型的,如果需要 不同的类型的话,可以在可变参数中加入指定参数类型的参数,见下面的"5"

    void ShowMsg_Thread_DLL_VA_DWORD(char* _pc, int _n, ...)
    {
        if (g_fnShowMsg_Thread == NULL)
            return;
        if (_n > 5)
        {
            ::MessageBoxA(0, "Parameter count not enough .", "ShowMsg_Thread_DLL_VA_DWORD", 0);
            return;
        }
    
        DWORD dws[16] = {0};
        char buf[512] = {0};
    
        va_list ap;
        va_start(ap, _n);
    
        if (_n == 0)
            g_fnShowMsg_Thread(_pc);
        else if (_n == 1)
        {
            dws[0] = va_arg(ap, DWORD);
            sprintf_s(buf, sizeof(buf), _pc, dws[0]);
        }
        else if (_n == 2)
        {
            for (int i=0; i<_n; i++)
                dws[0] = va_arg(ap, DWORD);
            sprintf_s(buf, sizeof(buf), _pc, dws[0], dws[1]);
        }
        else if (_n == 3)
        {
            for (int i=0; i<_n; i++)
                dws[0] = va_arg(ap, DWORD);
            sprintf_s(buf, sizeof(buf), _pc, dws[0], dws[1], dws[2]);
        }
        else if (_n == 4)
        {
            for (int i=0; i<_n; i++)
                dws[0] = va_arg(ap, DWORD);
            sprintf_s(buf, sizeof(buf), _pc, dws[0], dws[1], dws[2], dws[3]);
        }
        else if (_n == 5)
        {
            for (int i=0; i<_n; i++)
                dws[0] = va_arg(ap, DWORD);
            sprintf_s(buf, sizeof(buf), _pc, dws[0], dws[1], dws[2], dws[3], dws[4]);
        }
    
        va_end(ap);
        g_fnShowMsg_Thread(buf);
    }

    5、自己的包装函数(2)

      ZC:函数传入的可变参数,如果需要是 不同的类型的话,可以在可变参数中加入指定参数类型的参数,例如 我在 D?SvgExe的D?RemoteCall代码中的使用方式

    6、

    7、(20191112)Qt598x64(vs2017) 编译的"Widgets Application"中 printf(...)和fprintf(...)调用后,不会立即在控制台输出信息,需要调用"fflush(stdout);"后 信息才会显示出来,于是就想 封装一个信息打印的函数 在函数中直接调用 fflush(...),这就需要 封装成可变参数的函数,于是查了资料,封装成这样:

    #include <stdarg.h>
    
    void MsgPrint(const char *format, ...)
    {
        va_list ap;
        int n;
    
        va_start(ap, format);
        n = vprintf(format, ap);
        va_end(ap);
        //return n;
    
        // ZC: 上面是 printf(...)的实现
        fflush(stdout);// Qt598不执行这一句的话 print(...)和fprintf(stdout, ...)输出的信息 不会立即显示在"应用程序输出"中
    }

     (1)va_list 、va_start、 va_arg、 va_end 使用说明 - 土戈 - CSDN博客.html(https://blog.csdn.net/f110300641/article/details/83822290

    // 附:可变参数应用实例
    
    //  1.printf实现
    
    #include <stdarg.h>
     
    int printf(char *format, ...)
    {
        va_list ap;
        int n;
         
        va_start(ap, format);
        n = vprintf(format, ap);
        va_end(ap);
        return n;    
    }
    
    
    //  2.定制错误打印函数error
    
    #include  <stdio.h>
    #include  <stdarg.h>
     
    void error(char *format, ...)
    {
        va_list ap;
        va_start(ap, format);
        fprintf(stderr, "Error: ");
        vfprintf(stderr, format, ap);
        va_end(ap);
        fprintf(stderr, "
    ");
        return;    
    }

    8、

    9、

  • 相关阅读:
    头条java 后台一面凉经
    JVM运行时数据区
    基础篇——Spring Cloud Hystrix
    bug篇——idea拉取代码认证失败重新登录
    基础篇——代理模式之SpringAOP
    基础篇——代码优化100条之(11—20)
    电商项目实战(架构八)——RabbitMQ实现延迟消息
    电商项目实战(架构七)——Mongodb实现文档操作
    基础篇——代码优化100条之(1—10)
    电商项目实战(架构六)——Elasticsearch实现商品搜索
  • 原文地址:https://www.cnblogs.com/cppskill/p/8716242.html
Copyright © 2020-2023  润新知