可變參數__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\n",i,j)  正確打印

 

case B.

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

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

正確打印

my_print2("iiiiiii\n")       

編譯失敗,因為擴展出來只有一個參數,至少要兩個及以上參數

 

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\n", 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\n", fmt2,  ##arg12);   \  // 這里有兩個%s對應##arg12,所以就會打印出可變參數中的兩個參數"what" 和"nice"
               printf("***************[%s-%s-%d]: "fmt2 , __FILE__, __FUNCTION__, __LINE__, ##arg12); \ }while(0); int main(){ Debug("hi %s %s \n", "what", "nice"); // 針對這條打印進行分析

  return 0; } // 實測,第二條打印語句內的 "hi %s %s \n" 就是fmt2。 // 而"what", "nice"是不定參數##arg12的值

 第二條打印語句分析: "hi %s %s \n"就是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"信息的這么一個字符串。

 

 

.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM