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"信息的這么一個字符串。
.
