c語言中可變引數的原理 printf 函式

2021-05-24 03:03:08 字數 1291 閱讀 2840

函式原型: int printf(const char *format[,argument]...)

返 回 值: 成功則返回實際輸出的字元數,失敗返回-1.

函式說明:

在printf()函式中,format後面的引數個數不確定,且型別也不確定,這些引數都存放在棧內.呼叫printf()函式時,根據format裡的格式("%d %f...")依次將棧裡引數取出.而取出動作要用到va_arg、va_end、va_start這三個巨集定義,再加上va_list.

(1)va_list事實上是一char *型別,即:

typedef char* va_list;

(2)三個巨集定義:

#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,type)  ( *(type *)((ap += _intsizeof(t)) - _intsizeof(t)) ) 

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

attention】c語言中可變引數的原理---printf()函式

int printf(const char* format,...);  

使用過c語言的人所再熟悉不過的printf函式原型,它的引數中就有固定引數format和可變引數(用」…」表示).而程式設計師又可以用各種方式來呼叫printf,如:

printf("%d ",value);  

printf("%s ",str);  

printf("the number is %d,string is:%s ",value,str);

可以看出,該函式的引數格式不固定,引數型別不固定.在c語言中使用巨集來處理這些可變引數.這些巨集看起來很複雜,其實原理挺簡單,即根據引數入棧的特點從最靠近第乙個可變引數的固定引數開始,依次獲取每個可變引數的位址.

(1)巨集va_start

通過該巨集定義可以獲取到可變參數列的首位址,並將該位址賦給指標ap.

(2)巨集va_arg

通過該巨集定義可以獲取當前ap所指向的可變引數,並將指標ap指向下乙個可變引數.注意,該巨集的第二個引數為型別.

(3)巨集va_end

通過該巨集定義可以結束可變引數的獲取.

程式設計師通過這三個巨集定義就可以實現對可變引數的處理.例如:

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...

C語言中的可變引數

1 需要標頭檔案 include 2 函式定義 void logcmd int arg0,void logcmd char arg0,3 解析 i 數字型別 void logcmd int n,其中n表示引數的個數,n之後才是真正的引數。呼叫如 logcmd 0 logcmd 1,9 logcmd ...