c語言的可變引數函式的實現需要使用標頭檔案stdarg.h,在該標頭檔案中定義了乙個變數型別va_list和三個巨集va_start、va_arg、va_end(),下面將在**中講解這幾個巨集的使用方法。
第一種方法是在函式內部手動指定可變引數的型別。首先需要知道可變引數的個數,並作為第乙個引數傳入。由於函式引數入棧的順序是從右往左,因此必須把引數個數寫在最左邊,可變引數寫右邊。
// 可變引數的實現
#include
int showvarlist
(int n,
...)
手動指定只在某些特殊場合有用,通常情況下需要自動檢測可變引數的個數和型別(如printf,sprintf等)。其實現步驟和上述過程類似,只是把引數個數換成了乙個格式化字串,然後通過處理該字串,判斷引數的個數和型別(格式化字串的處理過程比較複雜,具體細節可以看printf的原始碼)。這裡不分析如何處理格式化字串,而是直接使用庫函式來實現自定義的可變參函式。
這裡要用的庫函式是vsnprintf,在標頭檔案stdarg.h中定義:
#include
int vsprintf
(char *str,
const char *format, va_list ap)
;// 不限制輸出字串長度
int vsnprintf
(char *str, size_t size,
const char *format, va_list ap)
;// 限制長度,防止陣列越界
/*用途:將引數列表ap按format的格式輸出到str中,並限制總字元個數最多size
引數說明:
size:輸出字串的最大長度
format:格式化字串
ap:引數列表
返回值:返回生成字串的長度,如果大於size,則只會把前size個拷貝到str中,失敗返回負值
*/
// 根據示例結合實際情況修改
#include
#include
#define max_size
1000
char print_buf[
max_size];
// 輸出字串存入的陣列
int printvatlist
(const char* format,
...)
實現c語言中的可變引數函式
c語言程式設計中有時會遇到一些引數個數可變的函式,例如printf 函式,其函式原型為 int printf const char format,它除了有乙個引數format固定以外,後面跟的引數的個數和型別是可變的 用三個點 做引數佔位符 實際呼叫時可以有以下的形式 printf d i prin...
C語言中可變引數函式實現原理
c函式呼叫的棧結構 可變引數函式的實現與函式呼叫的棧結構密切相關,正常情況下c的函式引數入棧規則為 stdcall,它是從右到左的,即函式中的最右邊的引數最先入棧。例如,對於函式 void fun int a,int b,int c 其棧結構為 0x1ffc d 0x2000 a 0x2004 b ...
C語言中可變引數函式實現原理
說的非常詳細,但是有部分口誤,希望只吸取精華 c函式呼叫的棧結構 可變引數函式的實現與函式呼叫的棧結構密切相關,正常情況下c的函式引數入棧規則為 stdcall,它是從右到左的,即函式中的最右邊的引數最先入棧。例如,對於函式 void fun int a,int b,int c 其棧結構為 0x1f...