int printf ( const char * format, ... );通過使用可變個數參數,就是傳入的參數個數是可變的,如printf需要根據format實參傳入多個實參。
/* * Author: guojun07 */ #include程序的數據結果如下:#include #include #include void myprintf(char *format, ...) { va_list ap; int pos = 0; int int_val = 0; float f_val; char buf[64]; memset(buf, 0, 64); // 得到所有的參數放到下一個list中ap中 va_start(ap, format); while (format[pos] != '') { // 判斷'%',表示要得到下一個參數 if (format[pos] == '%') { pos ++; switch(format[pos]) { case 'd': case 'u': // 得到ap中的下一個參數 int_val = va_arg(ap, int); sprintf(buf, %d, int_val); // 將數據寫到標准輸出 write(STDOUT_FILENO, buf, strlen(buf)); memset(buf, 0, 64); pos ++; break; case 'f': // 得到ap中的下一個參數 f_val = (float)va_arg(ap, double); sprintf(buf, %f, f_val); // 將數據寫到標准輸出 write(STDOUT_FILENO, buf, strlen(buf)); memset(buf, 0, 64); pos ++; break; default: break; } } else { write(STDOUT_FILENO, &(format[pos]), 1); pos ++; } } } int main(void){ myprintf(this is a testing, i = %d, u = %u, f = %f , -1, 5, 0.2); return 0; }
guojun8@guojun8-desktop:~/test/valist$ ./main this is a testing, i = -1, u = 5, f = 0.200000
#ifndef _VALIST #define _VALIST typedef char *va_list; #endif /* _VALIST */ /* * Storage alignment properties */ #define _AUPBND (sizeof (acpi_native_int) - 1) #define _ADNBND (sizeof (acpi_native_int) - 1) /* * Variable argument list macro definitions */ #define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd))) #define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND)))) #define va_end(ap) (void) 0 #define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
a) va_list
從實現中可以看出va_list類型實際上就是一個指針;
b) va_start
這個宏的作用是將T所指向的參數後面的內容放到ap中,其中_bnd (A,_AUPBND)是返回A的size並與系統的機器位數對齊,因為參數在棧中的地址一定是與系統的字長對齊的,其中acpi_native_int就表示機器字長;
c) va_end
這個宏的作用就是返回0;
d) va_arg
這個宏的作用是取得ap指向的當前的參數,並將ap指向參數列表中的下一個參數;