1. 程式人生 > >va_list、va_start、va_end 巨集用法小結

va_list、va_start、va_end 巨集用法小結

直奔主題,在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說明外,還有說明引數傳遞原理。 到此,謝謝!如有不對之處,請指正。