当前位置:网站首页>Implement printf function by yourself
Implement printf function by yourself
2020-11-09 15:25:00 【shzwork】
origin:https://www.e-learn.cn/content/qita/716071
First of all, let's take a look at the basics .
printf The format characters are as follows ,
Format characters |
explain |
d |
Output integers in signed decimal form ( Integers do not output symbols ) |
u |
Output integers in unsigned decimal form |
x |
Output an integer in hexadecimal unsigned form ( Don't output preamble 0x), use x Then output hexadecimal number of a~f In lower case |
c |
Output in character form , Only one character is output |
s |
Output string |
stay C In language , Not only is the type of the parameter variable , And the number of parameters is also variable . in other words , In the formal parameter list, you can not explicitly specify the number and type of parameters to be passed , As mentioned above printf That's what functions do . This function is called a variable parameter function . The number and type of parameters of variable length parameter function are variable , But its design principle is consistent with that of fixed parameter function , We have a way to tell the variable parameter function the number and type of parameters that are not specified .
printf The statement of :
int printf(const char *format, ...);
format: Fixed parameter
... : Variable parameters ( Variable parameter )
stay C In language , The declaration of the variable parameter function is placed in atdarg.h In the standard library , Of course, you can include it directly and use it , But we define it here ( Refer to the macro definition of the header file ).
typedef char * va_list;
/* When sizeof(n)=1/2/4 when ,_INTSIZEOF(n)=4 */
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
//#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
//#define va_arg(ap,t) (ap = ap + _INTSIZEOF(t), *(t *)(ap - _INTSIZEOF(t)))
/* The meaning of the following words is , First point to the address of the next variable , And then again ( reduce ) Come back , Finally, take the value in its original address */
#define va_arg(ap,t) (*(t *)(ap = ap + _INTSIZEOF(t), ap - _INTSIZEOF(t)))
/* When the pointer runs out, it points to 0 Address , Prevent the appearance of wild pointer */
#define va_end(ap) ( ap = (va_list)0 )
There's a little bit of caution here #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) -1) & ~(sizeof(int) - 1) ), It may not be easy to understand , Here is a knowledge point : Because in x86(32 Bit machine ) Under the platform ,GCC By default, the compiler presses 4 Byte alignment , So when sizeof(n)=1/2/4 when ,_INTSIZEOF(n)=4 When the variable type is char,unsigned int,int, That's not enough 4 All bytes are in accordance with 4 Byte completion .
Here's how My_printf.c
#include "my_printf.h"
//==================================================================================================
typedef char * va_list;
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
//#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
#define va_arg(ap,t) ( *(t *)( ap=ap + _INTSIZEOF(t), ap- _INTSIZEOF(t)) )
#define va_end(ap) ( ap = (va_list)0 ) // There is no explanation here , It's not difficult to understand.
//==================================================================================================
unsigned char hex_tab[]={'0','1','2','3','4','5','6','7',\
'8','9','a','b','c','d','e','f'}; // Output characters in various bases
static int outc(int c)
{
__out_putchar(c); // there _out_putchar In fact, that is putchar, stay .h In the definition of
return 0;
}
static int outs (const char *s) // Output string
{
while (*s != '\0')
__out_putchar(*s++);
return 0;
}
static int out_num(long n, int base,char lead,int maxwidth)
{
unsigned long m=0;
char buf[MAX_NUMBER_BYTES], *s = buf + sizeof(buf); // sizeof It's the ending '\0' ,strlen not
int count=0,i=0; // Note that there s Point to buf The end of , As for why to keep looking down
*--s = '\0'; // First --, At the end of assignment , because sizeof Count the length inside the terminator
if (n < 0){
m = -n; // If the output is a negative number, it is negated
}
else{
m = n;
}
do{
*--s = hex_tab[m%base];
count++;
}while ((m /= base) != 0); // The number to be printed is stored in the array from bits to bits buf in , If it doesn't point to buf end ,
if (n < 0)
*--s = '-'; // If it's negative, add a minus sign
return outs(s);
}
/*reference : int vprintf(const char *format, va_list ap); */
static int my_vprintf(const char *fmt, va_list ap)
{
char lead=' ';
int maxwidth=0;
for(; *fmt != '\0'; fmt++)
{
if (*fmt != '%') { // Order search judgment , encounter % On the launch , Otherwise, continue to loop out the output
outc(*fmt);
continue;
}
fmt++;
if(*fmt == '0'){ // encounter ‘0’ Explain that the preamble is 0
lead = '0';
fmt++;
}
while(*fmt >= '0' && *fmt <= '9'){ // The next number is the length , Calculate the specified length
maxwidth *=10;
maxwidth += (*fmt - '0');
fmt++;
}
switch (*fmt) { // Determine the format output
case 'd': out_num(va_arg(ap, int), 10,lead,maxwidth); break;
case 'o': out_num(va_arg(ap, unsigned int), 8,lead,maxwidth); break;
case 'u': out_num(va_arg(ap, unsigned int), 10,lead,maxwidth); break;
case 'x': out_num(va_arg(ap, unsigned int), 16,lead,maxwidth); break;
case 'c': outc(va_arg(ap, int )); break;
case 's': outs(va_arg(ap, char *)); break;
default:
outc(*fmt);
break;
}
}
return 0;
}
//reference : int printf(const char *format, ...);
int printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
my_vprintf(fmt, ap);
va_end(ap);
return 0;
}
int my_printf_test(void)
{
printf("My_printf test\n\r") ;
printf("test char =%c,%c\n\r", 'A','a') ;
printf("test decimal number =%d\n\r", 123456) ;
printf("test decimal number =%d\n\r", -123456) ;
printf("test hex number =0x%x\n\r", 0x55aa55aa) ;
printf("test string =%s\n\r", "yoyoyo") ;
printf("num=%08d\n\r", 12345);
printf("num=%8d\n\r", 12345);
printf("num=0x%08x\n\r", 0x12345);
printf("num=0x%8x\n\r", 0x12345);
printf("num=0x%02x\n\r", 0x1);
printf("num=0x%2x\n\r", 0x1);
printf("num=%05d\n\r", 0x1);
printf("num=%5d\n\r", 0x1);
return 0;
}
The experimental results are as follows :
版权声明
本文为[shzwork]所创,转载请带上原文链接,感谢
边栏推荐
- [operation and maintenance thinking] how to do a good job in cloud operation and maintenance services?
- Data consistency of cache
- 【分享】接口测试如何在post请求中传递文件
- MES system plays an important role in the factory production management
- I heard that you changed your registered residence overnight. How can you help yourself if you work like ping?
- 「代码整洁之道-程序员的职业素养」读书笔记
- HomeLede 2020.11.08 v5.4.72内核 UPnP+NAS+多拨+网盘+DNS优化+帕斯沃 无缝集成+软件包
- ImmutableMap的put方法问题
- iOS中的内嵌汇编
- International top journal radiology published the latest joint results of Huawei cloud, AI assisted detection of cerebral aneurysms
猜你喜欢
Openyurt in depth interpretation: how to build kubernetes native cloud edge efficient collaborative network?
5 minutes get I use GitHub's 5-year summary of these operations!
Arthas Install 快速安装文档
乘风破浪的技术大咖再次集结 | 腾讯云TVP持续航行中
Embedded assembly in IOS
要我说,多线程事务它必须就是个伪命题!
5分钟GET我使用Github 5 年总结的这些骚操作!
In depth analysis of the multi-user shopping mall system from search to create a profit point
CAD2020下载AutoCAD2020下载安装教程AutoCAD2020中文下载安装方法
什么是网站【新四化】?
随机推荐
CCF BDCI hot topic: privacy information recognition in unstructured business text information
高质量的缺陷分析:让自己少写 bug
Spark Learning (3) -- memory management and performance tuning
Interview series 2: concurrent programming
融云完成数亿人民币 D 轮融资,将持续打造全球云通信能力
AutoCAD 2020 installation package & Installation Tutorial
A quick start to Shell Scripting
5分钟GET我使用Github 5 年总结的这些骚操作!
Android byte beat one side, was hanged by the interviewer! Fortunately, we got the offer from three sides
Get this template, double your salary
To me, multithreading transaction must be a pseudo proposition!
iOS中的内嵌汇编
博士在读时,把暗恋的师兄变成了老公是种怎样的体验?
瞧瞧,这样的『函数』才叫 Pythonic
详解三种不同的身份验证协议
Low power Bluetooth single chip helps Internet of things
微服务框架 Go-Micro 集成 Nacos 实战之服务注册与发现
布客·ApacheCN 编程/后端/大数据/人工智能学习资源 2020.11
Programmers before and after buying a house, after reading has cried blind
5分钟GET我使用Github 5 年总结的这些骚操作!