stdarg.h(c标准库)
生活随笔
收集整理的這篇文章主要介紹了
stdarg.h(c标准库)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?
1 /*my_stdarg.h*/ 2 /* 3 * c允許定義可接受一個(gè)可變參數(shù)列表的函數(shù)。而且是自己定義的額外的函數(shù)。 4 * stdarg.h定義的宏。允許在任何時(shí)候從頭到尾地便利一個(gè)附加參數(shù)列表。 5 * 在遇到每一個(gè)參數(shù)之前,必須知道它的類型,但在一個(gè)給定的調(diào)用發(fā)生之前,不必知道它的細(xì)節(jié)。 6 * 宏va_start,一個(gè)函數(shù)必須至少聲明一個(gè)固定的參數(shù)。宏va_start引用了最后一個(gè)固定參數(shù)所以它能夠?qū)勺儏?shù)進(jìn)行定位, 7 * 訪問(wèn)所有未命名的參數(shù)之前調(diào)用宏。對(duì)類型va_list ap初始化。 8 * 宏va_arg,每一次調(diào)用都會(huì)修改ap,每次調(diào)用這個(gè)宏展開(kāi)的表達(dá)式的類型和值跟調(diào)用的下一個(gè)參數(shù)的相同。 9 * 第一次調(diào)用返回parmN后面的第一個(gè)參數(shù)。 10 * 宏va_end,一個(gè)函數(shù)在返回到它的調(diào)用者之前一定要調(diào)用va_end。 11 * stdarg.h聲明了一種類型,定義了3個(gè)宏,這樣就可以提前訪問(wèn)一個(gè)參數(shù)表,調(diào)用函數(shù)在編譯時(shí)并不知道這個(gè)參數(shù)表中參數(shù)的數(shù)目和類型。 12 * 在...之前的那個(gè)參數(shù)起著特殊的作用,記作parmN。 13 * 聲明類型va_list。 14 * 可重復(fù)使用。 15 * 16 * 17 * c標(biāo)準(zhǔn)定義,一個(gè)可變參數(shù)表在內(nèi)存中占據(jù)了一個(gè)連續(xù)的字符數(shù)組; 18 * 后繼的參數(shù)占據(jù)著字符數(shù)組更高為位。 19 * 一個(gè)參數(shù)占據(jù)的空間開(kāi)始于2^N字節(jié)的整數(shù)倍的存儲(chǔ)邊界。 20 * 存儲(chǔ)空間的大小是可以表示這個(gè)參數(shù)2^N字節(jié)的最小倍數(shù)。 21 * 存儲(chǔ)空間留下的任何間隙總是在參數(shù)數(shù)據(jù)對(duì)象的開(kāi)頭或者結(jié)尾。 22 * 23 */ 24 25 #define _AUPBND 3/*在可變參數(shù)表內(nèi)部確定存儲(chǔ)邊界的屏蔽宏,2^N-1*/ 26 #define _ADNBND 3/*確定存儲(chǔ)空隙是否在一個(gè)參數(shù)數(shù)據(jù)對(duì)象的開(kāi)端或者結(jié)尾的屏蔽宏,在尾處2^N-1,否則為0*/ 27 /*4倍數(shù)對(duì)齊,且結(jié)尾為開(kāi)始出,則 3 0*/ 28 #ifndef MY_STDARG_H_ 29 #define MY_STDARG_H_ 30 /*保存一個(gè)指向下一個(gè)參數(shù)空間的起始位置的指針*/ 31 typedef char *va_list; 32 /* 33 * 通過(guò)增加va_list對(duì)象ap的內(nèi)容來(lái)使它指向下一個(gè)參數(shù)空間的起始位置,然后再退回來(lái)指向當(dāng)前參數(shù)的起始位置, 34 * 然后通過(guò)強(qiáng)制類型轉(zhuǎn)換把這個(gè)指針值轉(zhuǎn)換成為指定類型的指針,最后解引用這個(gè)指針以訪問(wèn)存儲(chǔ)在數(shù)據(jù)對(duì)象中的值。 35 */ 36 #define va_arg(ap, T) (*(T *)(((ap) += _Bnd(T, _AUPBND)) - _Bnd(T, _ADNBND))) 37 /*占位符*/ 38 #define va_end(ap) (void)0 39 /*跳過(guò)已命名的參數(shù),也就是最后一個(gè)固定參數(shù),使用內(nèi)部宏_Bnd把它的參數(shù)大小操作為2^N字節(jié)的一個(gè)倍數(shù)*/ 40 #define va_start(ap, A) (void)((ap) = (char *)&(A) + _Bnd(A, _AUPBND)) 41 #define _Bnd(X, bnd) (sizeof(X) + (bnd) &~ (bnd)) 42 #endif?
1 /*my_stdarg.c*/ 2 #include <assert.h> 3 #include <stdio.h> 4 #include "my_stdarg.h" 5 6 typedef struct { 7 char c; 8 }cstruct; 9 10 static int tryit(const char *fmt, ...) 11 { 12 int ctr = 0; 13 va_list ap; 14 15 va_start(ap, fmt); 16 for(; *fmt; ++fmt) 17 switch(*fmt){ 18 case 'i': 19 assert(va_arg(ap, int) == ++ctr); 20 break; 21 case 'd': 22 assert(va_arg(ap, double) == ++ctr); 23 break; 24 case 'p': 25 assert(va_arg(ap, char *)[0] == ++ctr); 26 break; 27 case 's': 28 assert(va_arg(ap, cstruct).c == ++ctr); 29 } 30 va_end(ap); 31 return ctr; 32 } 33 int main(void) 34 { 35 cstruct x = {3}; 36 37 assert(tryit("iisdi", '\1', 2, x, 4.0, 5) == 5); 38 assert(tryit("") == 0); 39 assert(tryit("pdp", "\1", 2.0, "\3") == 3); 40 printf("sizeof(va_list) == %u\n", sizeof(va_list)); 41 puts("success testing stdary.h"); 42 return 0; 43 }?
轉(zhuǎn)載于:https://www.cnblogs.com/kevin-kang/p/3172720.html
總結(jié)
以上是生活随笔為你收集整理的stdarg.h(c标准库)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【转】强大的vim配置文件,让编程更随意
- 下一篇: Oracle RMAN中备份表空间名为'