stdarg.h(c标准库)
生活随笔
收集整理的這篇文章主要介紹了
stdarg.h(c标准库)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
1 /*my_stdarg.h*/ 2 /* 3 * c允許定義可接受一個可變參數列表的函數。而且是自己定義的額外的函數。 4 * stdarg.h定義的宏。允許在任何時候從頭到尾地便利一個附加參數列表。 5 * 在遇到每一個參數之前,必須知道它的類型,但在一個給定的調用發生之前,不必知道它的細節。 6 * 宏va_start,一個函數必須至少聲明一個固定的參數。宏va_start引用了最后一個固定參數所以它能夠對可變參數進行定位, 7 * 訪問所有未命名的參數之前調用宏。對類型va_list ap初始化。 8 * 宏va_arg,每一次調用都會修改ap,每次調用這個宏展開的表達式的類型和值跟調用的下一個參數的相同。 9 * 第一次調用返回parmN后面的第一個參數。 10 * 宏va_end,一個函數在返回到它的調用者之前一定要調用va_end。 11 * stdarg.h聲明了一種類型,定義了3個宏,這樣就可以提前訪問一個參數表,調用函數在編譯時并不知道這個參數表中參數的數目和類型。 12 * 在...之前的那個參數起著特殊的作用,記作parmN。 13 * 聲明類型va_list。 14 * 可重復使用。 15 * 16 * 17 * c標準定義,一個可變參數表在內存中占據了一個連續的字符數組; 18 * 后繼的參數占據著字符數組更高為位。 19 * 一個參數占據的空間開始于2^N字節的整數倍的存儲邊界。 20 * 存儲空間的大小是可以表示這個參數2^N字節的最小倍數。 21 * 存儲空間留下的任何間隙總是在參數數據對象的開頭或者結尾。 22 * 23 */ 24 25 #define _AUPBND 3/*在可變參數表內部確定存儲邊界的屏蔽宏,2^N-1*/ 26 #define _ADNBND 3/*確定存儲空隙是否在一個參數數據對象的開端或者結尾的屏蔽宏,在尾處2^N-1,否則為0*/ 27 /*4倍數對齊,且結尾為開始出,則 3 0*/ 28 #ifndef MY_STDARG_H_ 29 #define MY_STDARG_H_ 30 /*保存一個指向下一個參數空間的起始位置的指針*/ 31 typedef char *va_list; 32 /* 33 * 通過增加va_list對象ap的內容來使它指向下一個參數空間的起始位置,然后再退回來指向當前參數的起始位置, 34 * 然后通過強制類型轉換把這個指針值轉換成為指定類型的指針,最后解引用這個指針以訪問存儲在數據對象中的值。 35 */ 36 #define va_arg(ap, T) (*(T *)(((ap) += _Bnd(T, _AUPBND)) - _Bnd(T, _ADNBND))) 37 /*占位符*/ 38 #define va_end(ap) (void)0 39 /*跳過已命名的參數,也就是最后一個固定參數,使用內部宏_Bnd把它的參數大小操作為2^N字節的一個倍數*/ 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 }?
轉載于:https://www.cnblogs.com/kevin-kang/p/3172720.html
總結
以上是生活随笔為你收集整理的stdarg.h(c标准库)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】强大的vim配置文件,让编程更随意
- 下一篇: Oracle RMAN中备份表空间名为'