c
語言——
可變引數
宗旨:技術的學習是有限的,分享的精神是無限的。
1
、目前為止,見過比較熟悉的可變引數的函式就是
printf()
函式
[cpp]view plain
copy
print?
intprintf(
const
char
*format, …);"font-family: arial, helvetica, sans-serif; background-color: rgb(255, 255, 255);"
>
2
、可變引數巨集
[cpp]view plain
copy
print?
void
va_start(
va_list
arg_ptr, prev_param);
type va_arg(va_list
arg_ptr, type);
void
va_end(
va_list
arg_ptr);
va_list:用來儲存巨集va_start、va_arg和va_end所需資訊的一種型別。為了訪問變長引數列表中的引數,必須宣告va_list型別的乙個物件 定義: typedef char * va_list;
va_start:訪問變長引數列表中的引數之前使用的巨集,它初始化用va_list宣告的物件,初始化結果供巨集va_arg和va_end使用;
va_arg:展開成乙個表示式的巨集,該表示式具有變長引數列表中下乙個引數的值和型別。每次呼叫va_arg都會修改用va_list宣告的物件,從而使該物件指向引數列表中的下乙個引數;
va_end:該巨集使程式能夠從變長引數列表用巨集va_start引用的函式中正常返回。
c語言記憶體管理中,我們提到函式的引數存放在棧中。通過反彙編可知,可變引數是從右向左依次壓棧的,所以第乙個引數靠近棧頂,最後乙個引數靠近棧底。這些引數在記憶體中是連續存放的,每個引數都
4位元組對齊。
3
、stdarg.h
的一種實現
[cpp]view plain
copy
print?
/* stdarg.h standard header */
#ifndef _stdarg
#define _stdarg
/* type definitions */
typedef
char
*va_list
; /* macros */
#define va_arg(ap, t) \
(* (t *)(((ap) += _bnd(t, 3u)) - _bnd(t, 3u)))
#define va_end(ap) (void)0
#define va_start(ap, a) \
(void
)((ap) = (
char
*)&(a) + _bnd(a, 3u))
#define _bnd(x, bnd) (sizeof (x) + (bnd) & ~(bnd))
#endif /*_stdarg */
這個標頭檔案中的內部巨集定義將型別或變數的長度對齊到位元組的整數倍,例如
_bnd(char, 3u)
的值是4
,_bnd(int, 3u)
也是44
、可變引數函式實現思路
(
1)首先在函式裡定義乙個
va_list
型的變數
,這裡是
arg_ptr,
這個變數是指向引數的指標。(2
)然後用
va_start
巨集初始化變數
arg_ptr,
這個巨集的第二個引數是第
乙個可變引數的前乙個引數
,是乙個固定的引數。
(
3)然後用
va_arg
返回可變的引數
,並賦值給整數
j. va_arg
的第二個引數是你要返回的引數的型別
,這裡是
int型。(4
)最後用
va_end
巨集結束可變引數的獲取
.然後你就可以在函式裡使
用第二個引數了
.如果函式有多個可變引數的
,依次呼叫
va_arg
獲取各個引數。
5
、myprintf
函式實現
[cpp]view plain
copy
print?
#include
#include
void
myprintf(
const
char
*format, ...)
case
's':
default
: putchar(c);
} }
va_end(ap);
} int
main(
void
)
c 語言可變引數
1 當無法列出傳遞函式的所有實參的型別和數目時,可用省略號指定參數列 void foo void foo parm list,2 函式引數的傳遞原理 函式引數是以資料結構 棧的形式訪問,從右至左入棧.eg include void fun int a,int main output 12 343 獲...
c語言可變引數
ifdef debug print info x printk x,else print info x endif 一 什麼是可變引數 我們在c語言程式設計中有時會遇到一些引數個數可變的函式,例如printf 函式,其函式原型為 int printf const char format,它除了有乙個...
C語言可變引數
在gnu c中,巨集可以接受可變數目的引數,就象函式一樣,例如 1 2 define pr debug fmt,arg.printk kern debug fmt,arg 用可變引數巨集 variadic macros 傳遞可變參數列 你可能很熟悉在函式中使用可變參數列,如 1 voidprintf...