前言:C语言中可变参数的函数会被经常使用,而printf是最常用的可变参数的事例,在掌握堆栈结构的基础上,我们可以自己运用整一个printf
printf的代码基础用法如下例
printf("xxxx");
printf("%b", 3);
printf("%b, %c", 3, 'a');
第一个参数是运用格式化参数,第二个参数开始就是变量的地址
所以我们需要知晓第一个参数的地址,随后便可以通过循环来解析%b, %c这一类型,没当这些类型时,就可以通过第一个参数的地址然后加上这个类型对应的大小便可找到下一个参数的地址
如例:
printf("%b, %c", 3, 'a');
"%b, %c"是printf的第一个参数, 这样我们用一个循环来解析它, 如果它碰到%b时, 那就说明printf的第2个参数是一个int类型的, 通过指针加sizeof(int), 就可以定位到第2个参数,依此往后推, 来解析所有的参数。
以下是取自结合参考及自己的编写的一个操作系统内核,来实现了一个printf的部分功能
printk.h:
#define va_list char*
#define va_start(arg, fortmat) (arg = (char *)&format + sizeof(format))
#define va_arg(arg, format) (*(format *)((arg += sizeof(format)) - sizeof(format)))
#define va_end(arg) *(char *)arg = 0
int printk(char *format, ...)
{
va_list arg;
va_start(arg, format);
return vfprintf(format, arg);
}
va_list就是一个char *指针的宏定义。
va_start用来取得第2个参数的地址, 第一个参数地址是format, 它是printf的格式化参数。
va_arg向后递归一个参数
谢谢