模拟实现printf
看代码:
// 打印时根据字符串所访问的值为‘%’时,开始进行判断类型。
//这块用switch结构判断‘%’下一个字符确定类型,若为‘d’
//则为整形,为‘s’为字符串
#include<stdio.h>
#include<windows.h>
#include<stdarg.h>
#include<assert.h>
void my_printf(char*format, ...);
void myPutInt(int a);
int main()
{
int a = 10;
char b = 'F';
char*str = "hello,bit!";
my_printf("a=%d\nb=%c\n*str=%s\n", a, b, str);
system("pause");
return 0;
}
//定义my_prinf,实现打印3种类型 int char 字符串
void my_printf(char*format, ...)
{
assert(format);
va_list arg_list;
va_start(arg_list, format);
const char*start = format;
while (*start != '\0')
{
if (*start == '%')
{
start++;
switch (*start)
{
case 'd':
{
int _int =va_arg(arg_list, int);
myPutInt(_int);
start++;
break;
}
case 'c':
{
char _char = va_arg(arg_list, char);
putchar(_char);
start++;
break;
}
case 's':
{
char* _string = va_arg(arg_list, char*);
while (* _string)
{
putchar(*_string++);
}
start++;
break;
}
}
}
else
{
putchar(*start);
start++;
}
}
va_end(arg_list);
}
//定义打印整形的函数
void myPutInt(int a)
{
int prev = a / 10;
if (prev)
{
myPutInt(prev);
}
putchar(a % 10 + '0');
}
总结:
1.可变参数列表是通过宏来实现的,这些宏定义于stdarg.h头⽂件中,它是标准库的⼀部分。这个头⽂件声明⼀个类型va_list 和三个宏va_start、va_arg和va_end。
我们可以声明⼀个类型为va_list的变量,与这⼏个宏配合使⽤,访问参数
2.声明⼀个va_list 类型的变量arg_list,它⽤于访问参数列表的未确定部分。
这个变量是调⽤va_start来初始化的。它的第⼀个参数是va_list的变量名,第2个参数是省略号前最后⼀个有名字的参数。
3.初始化过程把arg_list变量设置为指向可变参数部分的第⼀个参数。
4.为了访问参数,需要使⽤va_arg,这个宏接受两个参数:va_list变量和参数列表中下⼀个参数的类型。
5.访问完毕最后⼀个可变参数之后调⽤va_end。