案例**:
int cdecl messageboxprintf (tchar * szcaption, tchar * szformat, ……)
va_list arg_ptr:定義乙個指向個數可變的引數列表指標;
va_start(arg_ptr, argn):使引數列表指標arg_ptr指向函式引數列表中的第乙個可選引數,說明:argn是位於第乙個可選引數之前的固定引數,(或者說,最後乙個固定引數;…之前的乙個引數),函式引數列表中引數在記憶體中的順序與函式宣告時的順序是一致的。如果有一va函式的宣告是void va_test(char a, char b, char c, …),則它的固定引數依次是a,b,c,最後乙個固定引數argn為c,因此就是va_start(arg_ptr, c)。
va_arg(arg_ptr, type):返回引數列表中指標arg_ptr所指的引數,返回型別為type,並使指標arg_ptr指向引數列表中下乙個引數。
va_copy(dest, src):dest,src的型別都是va_list,va_copy()用於複製引數列表指標,將dest初始化為src。
va_end(arg_ptr):清空引數列表,並置引數指標arg_ptr無效。說明:指標arg_ptr被置無效後,可以通過呼叫va_start()、va_copy()恢復arg_ptr。每次呼叫va_start() / va_copy()後,必須得有相應的va_end()與之匹配。引數指標可以在引數列表中隨意地來回移動,但必須在va_start() … va_end()之內。
自定義除錯列印巨集,輸出當前檔名與行號
#define _debug_trace_cmh_ 2
#if 0 != _debug_trace_cmh_
#include #endif
#if 1==_debug_trace_cmh_ //普通列印
#define trace_cmh printf
#elif 2==_debug_trace_cmh_ //列印檔案名、行號
#define trace_cmh(fmt,...) \
printf("%s(%d): "##fmt, __file__, __line__, ##__va_args__)
#elif 3==_debug_trace_cmh_ //列印檔案名、行號、函式名
#define trace_cmh(fmt,...) \
printf("%s(%d)-<%s>: "##fmt, __file__, __line__, __function__, ##__va_args__)
#else
#define trace_cmh
#endif //_trace_cmh_debug_
1)
__va_args__
是乙個可變引數的巨集,這個可巨集是新的c99規範中新增的,目前似乎gcc和vc6.0之後的都支援(vc6.0的編譯器不支援)。巨集前面加上##的作用在於,當可變引數的個數為0時,這裡的##起到把前面多餘的","去掉的作用。
2) __file__
巨集在預編譯時會替換成當前的源檔名
3) __line__
巨集在預編譯時會替換成當前的行號
4) __function__
巨集在預編譯時會替換成當前的函式名稱
參考文件:
c 可變引數列表 va list 作為引數傳遞
include include void log int level,char fmt,debug void d char fmt,info void i char fmt,warn void w char fmt,error void e char fmt,在上面 中,log函式定義形式不能正確接...
va list 可變引數
什麼是變長引數?所謂含有變長引數的函式是指該函式可以接受可變數目的形參。例如我們都非常熟悉的 printf,scanf等等。2 變長引數如何實現?首先來看下面這樣乙個例子 include include include void demo char msg,else break para va ar...
可變引數列表
模擬實現printf函式 va list是在c語言中解決變參問題的一組巨集,所在標頭檔案 include 用於獲取不確定個數的引數 va start,函式名稱,讀取可變引數的過程其實就是在堆疊中,使用指標,遍歷堆疊段中的引數列表,從低位址到高位址乙個乙個地把引數內容讀出來的過程 va arg,這個巨...