va_list、va_start、va_end 巨集用法小結
阿新 • • 發佈:2019-02-04
直奔主題,在VS幫助文件中va_list、va_start、va_end的說明是:
type va_arg(
va_list arg_ptr,
type
);
void va_end(
va_list arg_ptr
);
void va_start(
va_list arg_ptr,
prev_param
); // (ANSI version)
void va_start(
arg_ptr
); // (Pre-ANSI-standardizationversion)
用 VS幫助文件的話說,va_list、va_start、va_end就是“訪問變數引數列表”。我的理解是,用於輔助完成函式引數的訪問提取的。什麼樣的函式引數需要用這種方法來訪問呢?那就是擁有可變引數的函式,比如: int demoFunction(int a, …);
下面來看看他們分別的作用吧。
- va_list: 一個指向當前引數的指標型別。
- va_start: 用於初始化 va_list 物件的。
- va_end: 用於釋放 va_list 指標的。
- va_arg: 返回當前引數。(在本文裡沒有用到)
對於程式猿(媛)來說,你講在多的理論也不如給他個Demo。我們在Demo中實踐用法,下面一段程式碼時《Windows程式設計(第五版)》中的例子。
<span style="font-size:18px;">#include <windows.h> #include <tchar.h> #include <stdio.h> int CDECL MessageBoxPrintf (TCHAR * szCaption, TCHAR * szFormat, ...) { TCHAR szBuffer [1024] ; va_list pArgList ; // The va_start macro (defined in STDARG.H) is usually equivalent to: // pArgList = (char *) &szFormat + sizeof (szFormat) ; va_start (pArgList, szFormat) ; // The last argument to wvsprintf points to the arguments _vsntprintf ( szBuffer, sizeof (szBuffer) / sizeof (TCHAR), szFormat, pArgList) ; // The va_end macro just zeroes out pArgList for no good reason va_end (pArgList) ; return MessageBox (NULL, szBuffer, szCaption, 0) ; } int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { int cxScreen, cyScreen ; cxScreen = GetSystemMetrics (SM_CXSCREEN) ; cyScreen = GetSystemMetrics (SM_CYSCREEN) ; MessageBoxPrintf ( TEXT ("ScrnSize"), TEXT ("The screen is %i pixels wide by %i pixels high."), cxScreen, cyScreen) ; return 0 ; }</span>
(注意:《Windows 程式設計》中的例子,有點老,_vsntprintf 可能會報錯,改為 _vsntprintf_s 就好了。)
其中,各自的作用是這樣的:
說明一下va_start 的用法,
所以,也就是說,va_start 所在的函式,至少要有一個引數。
裡面除了有對 va_start、va_end說明外,還有說明引數傳遞原理。 到此,謝謝!如有不對之處,請指正。