va_list 原理以及用法
VA_LIST 是在C語言中解決變參問題的一組巨集
他有這麼幾個成員:
1) va_list型變數:
#ifdef _M_ALPHA
typedef struct {
char *a0; /* pointer to first homed integer argument */
int offset; /* byte offset of next parameter */
} va_list;
#else
typedef char * va_list;
#endif
2)_INTSIZEOF 巨集,獲取型別佔用的空間長度,最小佔用長度為int的整數倍:
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
3)VA_START巨集,獲取可變引數列表的第一個引數的地址(ap是型別為va_list的指標,v是可變引數最左邊的引數):
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
4)VA_ARG巨集,獲取可變引數的當前引數,返回指定型別並將指標指向下一引數(t引數描述了當前引數的型別):
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
5)VA_END巨集,清空va_list可變引數列表:
#define va_end(ap) ( ap = (va_list)0 )
VA_LIST的用法:
(1)首先在函式裡定義一具VA_LIST型的變數,這個變數是指向引數的指標;
(2)然後用VA_START巨集初始化變數剛定義的VA_LIST變數;
(3)然後用VA_ARG返回可變的引數,VA_ARG的第二個引數是你要返回的引數的型別(如果函式有多個可變引數的,依次呼叫VA_ARG獲取各個引數);
(4)最後用VA_END巨集結束可變引數的獲取。
使用VA_LIST應該注意的問題:
(1)可變引數的型別和個數完全由程式程式碼控制,它並不能智慧地識別不同引數的個數和型別;
(2)如果我們不需要一一詳解每個引數,只需要將可變列表拷貝至某個緩衝,可用vsprintf函式;
(3)因為編譯器對可變引數的函式的原型檢查不夠嚴格,對程式設計查錯不利.不利於我們寫出高質量的程式碼;
小結:可變引數的函式原理其實很簡單,而VA系列是以巨集定義來定義的,實現跟堆疊相關。我們寫一個可變引數的C函式時,有利也有弊,所 以在不必要的場合,我們無需用到可變引數,如果在C++裡,我們應該利用C++多型性來實現可變引數的功能,儘量避免用C語言的方式來實現。
轉自:http://www.cppblog.com/xmoss/archive/2009/07/20/90680.html
相關文章
- 「前端面試題系列4」this的原理以及用法前端面試題
- JVM引數以及用法JVM
- ThreadLocal用法及原理thread
- 可變引數va_list
- exists()、not exists() 、in()、not in()用法以及效率差異
- 正規表示式以及group的用法
- Laravel框架中 getClientIps() 原理和用法Laravel框架client
- Elaticsearch(一)--基礎原理及用法
- webpack基本用法及原理(10000+)Web
- npm基本用法及原理(10000+)NPM
- Java中ThreadLocal的用法和原理Javathread
- JS中的九個console命令以及用法JS
- Python模組以及日曆常見用法Python
- GO 同 (異) 包呼叫以及 struct 的用法GoStruct
- 變數常量類的命名格式以及用法變數
- MySQL 5.6 GTID 原理以及使用MySql
- 節流原理以及實現
- MySQL 索引原理以及優化MySql索引優化
- Ajax原理以及優缺點
- Stream常用操作以及原理探索
- JavaScript閉包原理與用法例項JavaScript
- 購物車原理以及實現
- react-redux/redux相關API,用法原理ReactReduxAPI
- Unity 協程(Coroutine)原理與用法詳解Unity
- 常用的使用者以及檔案管理命令有哪些,並演示命令以及用法。
- JSP簡介以及各種內建物件的用法JS物件
- Android 常用換膚方式以及原理分析Android
- CyclicBarrier、CountDownLatch以及Semaphore使用及其原理分析CountDownLatch
- GPU的介紹 以及原理的分析GPU
- 點陣圖(bitmap)原理以及實現
- 堆的原理以及實現O(lgn)
- Fiddler(1)基本介紹以及工作原理
- 防抖原理以及簡單實現
- Synchronized的實現原理以及優化synchronized優化
- 交換機的概念以及工作原理
- 紅黑樹的原理以及實現
- Android快取機制-LRU cache原理與用法Android快取
- Java基礎 | Stream流原理與用法總結Java