int printf ( const char * format, ... );通过使用可变个数参数,就是传入的参数个数是可变的,如printf需要根据format实参传入多个实参。
/*
* Author: guojun07
*/
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
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] != ‘\0‘) {
// 判断‘%‘,表示要得到下一个参数
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\n", -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指向参数列表中的下一个参数;
原文:http://blog.csdn.net/guojun07/article/details/24893639