最近在看linux 0.12源码,写了sprintk()格式化输出函数,本函数是一个可变参数函数,要对参数处理,必需知道,它们的个数和类型,那么这些函数是怎么知道参数个数,和类型的?其实这些可变参数个数和类型 ,函数能过前面的格式化控制字符获取。编写一个简单的例子可以看出,只输出了a的值。
int a;
int b;
printf("%d",a,b);
格式化控制字符串是必需的,且必定位于第一个参数 printf("%d",a,"%d",b);后面的将会忽略,有了参数的个数和类型,还是不够的,我们还需要获取这些参数,在C中函数参数从右向左入栈的,也就是说这个格式化控制字符串指针,将在栈顶。这样所有问题都解决了。下面定义了几个宏,去访问参数。下面是具体的代码。
#define __va_rounded_size(TYPE)\ //__cdecl(C语言默认的函数调用方法)入栈操作针对的是一个字
((sizeof(TYPE)+sizeof(int)-1)&~(sizeof(int)-1))
typedef char * va_list;
#define va_start(AP,LASTARG)\//返回可变参数的第一个参数。
(AP=((char *)&(LASTARG)+__va_rounded_size(LASTARG)))
#define va_end(AP)
#define va_arg(AP,TYPE)\//返回AP所指的参数,并使AP指向下一个参数,
(AP+=__va_roun