前景知识:
头文件 #include<stdarg.h>,用于实现可变参数函数的功能。
va_list,用来获取不确定个数的参数,va_list ap,定义参数列表
va_start,获取可变参数列表中第一个参数的地址
va_start(ap,v),ap是类型为va_list的指针,v是可变参数最左边的参数
va_arg,获取可变参数的当前参数,描述当前类型获取对应的参数 va_arg(ap,t),t为类型
例如:const char* s = va_arg(ap,const char*);
va_end,清空va_list可变参数列表 va_end(ap)
简单使用一下函数:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
int myprintf(const char* fmt, ...)
{
va_list ap;//定义参数列表
va_start(ap, fmt);//获取可变参数列表中第一个参数的地址
const char* s = va_arg(ap, const char*);
int d = va_arg(ap, int);//获取可变参数当前的参数 描述当前类型获取对应的参数
//va_arg(ap,t) t为类型
printf("first:%s\n", s);
printf("second:%d\n", d);
va_end(ap);//清空可变参数列表
return 1;
}
int main()
{
myprintf("hello %s %d", "abc", 18);
}
最终版:支持%d、%s、%x打印,尚不完善。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
int myprintf(const char* fmt, ...)
{
const char* s = "";
int d;
char buf[100];
va_list ap;//定义参数列表
va_start(ap, fmt);//获取可变参数列表中第一个参数的地址
while (*fmt)
{
//判断%
if (*fmt != '%')
{
putchar(*fmt++);
continue;
}
//是% 看下一位是s d...
switch (*++fmt)
{
case's':
s = va_arg(ap, const char*);
for (; *s != '\0'; ++s)
{
putchar(*s);
}
break;
case'd':
d = va_arg(ap, int);
_itoa(d, buf, 10);//int转为十进制字符串存在于buf中
for (s = buf; *s != '\0'; ++s)
{
putchar(*s);
}
break;
case'x':
d = va_arg(ap, int);
_itoa(d, buf, 16);//int转为十进制字符串存在于buf中
for (s = buf; *s != '\0'; ++s)
{
putchar(*s);
}
break;
default:
putchar(*(fmt-1));
putchar(*fmt);
break;
}
fmt++;
}
va_end(ap);//清空可变参数列表
return 1;
}
int main()
{
myprintf("hello %s %d 0x%x %%\n", "abc", 18,0x100);
myprintf("%s %d 0x%x %%\n", "abc", 18, 0x100);
myprintf("%s\n","good");
}