• 可变参数__VA_ARGS__ 、 va_start、va_arg、valist 简单使用


     1. 调试功能一般会使用到宏+可变参数的方式

    1.1

     ##__VA_ARGS__      之详细解析

    例如:

    case A.

    #define my_print1(...)    printf(__VA_ARGS__)   

    my_print1("i=%d,j=%d ",i,j)  正确打印

    case B.

    #define my_print2(fmt,...)  printf(fmt, __VA_ARGS__)  

    my_print1("i=%d,j=%d ",i,j) 

    正确打印

    my_print2("iiiiiii ")       

    编译失败,因为扩展出来只有一个参数,至少要两个及以上参数

    case C.

    #define my_print2(fmt,...)  printf(fmt, ##__VA_ARGS__)  

    my_print1里面不管是几个参数都能正确打印

    宏前面加上##的作用在于,当可变参数的个数为0时,这里的##起到把前面多余的","去掉的作用,否则会编译出错

    #define MODULE_NAME     "MY_LIBS"
    #define log_e(fmt, ...)  printf("[ERROR]["MODULE_NAME"](%s|%d)"fmt,__func__,__LINE__,##__VA_ARGS__)

    #include <stdio.h>
    
    
    #define MODULE_NAME      "MY_LIBS"
    
    #define log_e(fmt, ...)  printf("[ERROR]["MODULE_NAME"](%s|%d)"fmt,__func__,__LINE__, ##__VA_ARGS__)
    
     
    int main(){
    
      int i = 1111;
    
      log_e("hello : i=%d
    ", i);
    
    
      return 0;
    }

    root@lmw-virtual-machine:/home/lmw/桌面/C_Text#
    root@lmw-virtual-machine:/home/lmw/桌面/C_Text# gcc my_log.c -o ab
    root@lmw-virtual-machine:/home/lmw/桌面/C_Text#
    root@lmw-virtual-machine:/home/lmw/桌面/C_Text# ./ab
    [ERROR][MY_LIBS](main|14)hello : i=1111
    root@lmw-virtual-machine:/home/lmw/桌面/C_Text#

     1.2

    #include <iostream>
    #include <stdio.h>
    using namespace std;
    
    #define Debug( fmt2,  arg12... )         
        do{    printf("%s,  %s  %s
    ", fmt2,  ##arg12);     // 这里有两个%s对应##arg12,所以就会打印出可变参数中的两个参数"what" 和"nice"
                   printf("***************[%s-%s-%d]: "fmt2 , __FILE__, __FUNCTION__, __LINE__, ##arg12);  
                                 }while(0);
    
    int main(){
    
      Debug("hi %s %s 
    ", "what", "nice"); // 针对这条打印进行分析
    
      return 0;
    }
    
    // 实测,第二条打印语句内的 "hi %s %s 
    " 就是fmt2。  
    //              而"what", "nice"是不定参数##arg12的值

     第二条打印语句分析: "hi %s %s "就是fmt2。 而"what", "nice"是不定参数##arg12的值。

    需要注意的是: 如果只有1个%s格式符对应##arg12,那么只会打印出第一个"what",如果有两个格式符,那么则会打印出两个可变参数。

    代码运行结果:

     

     

     

    2. 编写一些功能函数的时候,我们也会用到可变参数

    C++代码示例:

    string combine_devtypes(int num, ...){
    
        string ret, tmp;
        va_list valist;
        char* str = NULL;
        int i;
     
        /* 为 num 个参数初始化 valist */
        va_start(valist, num);
     
        /* 访问所有赋给 valist 的参数 */
        for (i = 0; i < num; i++)
        {
           str = va_arg(valist, char*);
           tmp = str;
           ret += tmp;
    
           if(i < num-1){
             tmp = " ";
             ret += tmp;
           }
        }
    
        /* 清理为 valist 保留的内存 */
        va_end(valist);
     
        return ret;
    }

    本例子的函数功能是拼接字符串,并且在中间加上一个空字符。

    调用方式: string obj = combine_devtypes(2, "hello", "boy") , 得到的是包含"hello boy"信息的这么一个字符串。

     

     

    .

    /************* 社会的有色眼光是:博士生、研究生、本科生、车间工人; 重点大学高材生、普通院校、二流院校、野鸡大学; 年薪百万、五十万、五万; 这些都只是帽子,可以失败千百次,但我和社会都觉得,人只要成功一次,就能换一顶帽子,只是社会看不见你之前的失败的帽子。 当然,换帽子决不是最终目的,走好自己的路就行。 杭州.大话西游 *******/
  • 相关阅读:
    表格批量导入
    js——全选框 checkbox
    Sui 弹框固定
    【转】理解cookie和session机制
    【转】Session ID/session token 及和cookie区别
    下载表格
    金额转换
    货币 数字按格式转换
    超大文本相加
    csv文件的格式
  • 原文地址:https://www.cnblogs.com/happybirthdaytoyou/p/12264808.html
Copyright © 2020-2023  润新知