您的位置:首页 > 其它

模拟实现printf函数

2017-08-20 10:57 225 查看


模拟实现 printf()函数

如果要想解决这个问题 ,就要 知道一个知识点 ,可变参数列表  ,
可变参数列表是通过宏来实现的,这些宏定义于stdarg.h头文件中,它是标准库的一部分。这个头文件声明
个类型va_list 和三个宏va_start、va_arg和va_end。
转到定义处 查看一下这几个宏和类型 

typedef char *  va_list;

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )

#define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )

#define _crt_va_end(ap)      ( ap = (va_list)0 )
从上 面可以看出  va_list 表示的是 一个 char*的指针 

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
_INSIZEOF( n) 表示 的 是将 一个类型 如果该类型的空间字节数为"1 2 3 4"  都将它进位 为4字节 

                                                             如果该类型的空间字节数为"5 6 7 8 " 都将它进位 为8字节 

#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
表示的是 将 ap跳过第一个参数 v ,指向下一个 

#define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )


表示的是 要计算的参数,但是此时的 ap指向的是下一个参数,这样就可以为下一个参数的使用做好基础

#define _crt_va_end(ap)      ( ap = (va_list)0 )
结束 后 将 ap  赋值为 \0;

下面是我写的一个简单 的printf()函数 

代码实现

#define  _CRT_SECURE_NO_WARENINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>
void  Puts(const char *src)//我自己定义的puts 函数 输出时不会输出‘\n’
{
while(*src)
{
putchar(*src);
src++;
}
}
void My_printf(const char *src,...)
{
va_list arg;
va_start(arg,src);
while(*src)//判断 字符串是否 结束
{
if(*src =='s')
{
Puts(va_arg(arg,char*));//在这块不能使用puts()函数 ,因为会多输出一个 '\n'
}
else if(*src == 'c')
{
putchar(va_arg(arg,char));
}
else   //如果不是类型名 就 原型输出
putchar(*src);
src++;
}
va_end(arg);
}
int main()
{
My_printf("s\n ccc.\n","hello",'b','i','t');
system("pause");
return 0 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息