C庫中對函式的可變引數的支援

2021-07-05 07:08:07 字數 1761 閱讀 4422

c語言在標頭檔案定義了一些巨集,當函式引數未知時去獲取函式的引數。

包括乙個va_list型別和三個函式(巨集)va_start, va_arg和va_end .

變數和定義

va_list型別通過stdarg巨集定義來訪問乙個函式的參數列,引數列表的末尾會用省略號省略

宣告:void va_start(va_list ap, last_arg);

用va_arg和va_end巨集初始化引數ap,last_arg是傳給函式的固定引數的最後乙個,省略號之前的那個引數注意va_start必須在使用va_arg和va_end之前呼叫

宣告:type va_arg(va_list ap, type);

用type型別擴充套件到參數列的下個引數

注意ap必須用va_start初始化,如果沒有下乙個引數,結果會是undefined

宣告:void va_end(va_list ap);

允許乙個有參數列(使用va_start巨集)的函式返回,如果返回之前沒有呼叫va_end,結果會是undefined。引數變數列表可能不再使用(在沒呼叫va_start的情況下呼叫va_end) 

windows下的定義如下:

#ifndef _va_list_defined  

#ifdef  _m_alpha  

typedef 

struct  va_list;  

#else

typedef 

char *  va_list;  

#endif

#define _va_list_defined  

#endif

#ifdef  _m_ix86       

#define _intsizeof(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )  

#define va_start(ap,v)  ( ap = (va_list)&v + _intsizeof(v) )  

#define va_arg(ap,t)    ( *(t *)((ap += _intsizeof(t)) - _intsizeof(t)) )  

#define va_end(ap)      ( ap = (va_list)0 )  

#elif   defined(_m_mrx000) 

其中比較不容易理解的就是_intsizeof巨集:其實_intsizeof(n)表示得到變數n的記憶體大小,這裡要考慮記憶體對齊問題,在32位中系統中,一般是4位元組(32位)對齊。(sizeof(n) + sizeof(int))表示湊成4位元組的整數被,(sizeof(n) + sizeof(int)) & (sizeof(int) -1)表示將湊齊後多餘的位元組刪除。比如說10位元組的變數,佔記憶體的大小為:(10+4)&((11111100)2)= 12位元組;

c語言中利用可變引數的函式就是最常用的printf。而且c標準庫中也是包括3個引數含有va_list的函式:vprintf,vfprintf,vsprintf。而這三個函式與對應的不加「v「的函式用法是一樣的,只不過,vprintf類要求可變引數用va_list指定。其實printf就是利用vprintf來實現的。

下面是乙個模仿printf的函式:

#include 

#include 

void print(

char* fmt,...)

va_end(ap); }

int main()

C庫中對函式的可變引數的支援

c語言在標頭檔案定義了一些巨集,當函式引數未知時去獲取函式的引數。包括乙個va list型別和三個函式 巨集 va start,va arg和va end 變數和定義 va list型別通過stdarg巨集定義來訪問乙個函式的參數列,引數列表的末尾會用省略號省略 宣告 void va start v...

函式中的可變引數c

在資料的大小,個數,型別是未知的情況下,會用到可變引數。include include include 標準引數,解決可變引數問題 intadd int num,va end argp 結束讀取 return res void main include include include 標準引數,解決...

C 中函式中的可變引數

using system using system.collections.generic using system.linq using system.text vfun values console.writeline vfun aaa bbb ccc console.writeline say...