模拟实现 printf()函数
如果要想解决这个问题 ,就要 知道一个知识点 ,可变参数列表 ,
可变参数列表是通过宏来实现的,这些宏定义于stdarg.h头文件中,它是标准库的一部分。这个头文件声明
个类型va_list 和三个宏va_start、va_arg和va_end。
个类型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 ; }