当前位置:网站首页>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]所创,转载请带上原文链接,感谢
边栏推荐
- Native地图与Web融合技术的应用与实践
- 谈谈敏捷开发概念和迭代开发方案
- 腾讯云服务器搭建wordpress网站的两种方式(详细图文新手版)
- 深入探索 Android Gradle 插件的缓存配置
- 程序员买房前后对比,看完后已哭瞎...
- 微服务框架 Go-Micro 集成 Nacos 实战之服务注册与发现
- 毕业一年后接私活赚了10w,还拿了几家大厂offer!
- To me, multithreading transaction must be a pseudo proposition!
- A certification and authorization solution based on. Net core - hulutong 1.0 open source
- Notes for csp-j / s 2020
猜你喜欢

5分钟GET我使用Github 5 年总结的这些骚操作!

OpenYurt 深度解读:如何构建 Kubernetes 原生云边高效协同网络?

你这么不努力,怎么做年薪40W的大数据打工人?

Cad2016 download autocad2016 download installation detailed tutorial CAD Download

Flink的安装和测试

高质量的缺陷分析:让自己少写 bug

Leetcode algorithm (1)

Full link stress testing of moral integrity -- the evolution of corpus intelligence

Do programmers pay too much to work overtime? Should programmer's salary be reduced? Netizen: let go of other hard pressed programmers

Data consistency of cache
随机推荐
Autocad2020 full version installation text course, registration activation cracking method
Two ways for Tencent cloud server to build WordPress website
国际顶刊Radiology发表华为云最新联合成果,AI辅助检测脑动脉瘤
我叫Mongo,收了「查询基础篇」,值得你拥有
5 minutes get I use GitHub's 5-year summary of these operations!
Explore cache configuration of Android gradle plug-in
One year after graduation, I took private jobs to earn 10 W and got offers from several big factories!
5分钟GET我使用Github 5 年总结的这些骚操作!
Spark Learning (2) -- job scheduling and shuffle analysis
岗位内推 | 微软亚洲研究院智能多媒体组招聘计算机视觉算法实习生
我在传统行业做数字化转型(1)预告篇
要我说,多线程事务它必须就是个伪命题!
Booker · apachecn programming / back end / big data / AI learning resources 2020.11
决策树算法-理论篇
Low power Bluetooth single chip helps Internet of things
腾讯云服务器搭建wordpress网站的两种方式(详细图文新手版)
Using GaN based oversampling technique to improve the accuracy of model for mortality prediction of unbalanced covid-19
H5 official account listens to events in the closed browser (left fork).
In depth analysis of the multi-user shopping mall system from search to create a profit point
5 minutes get I use GitHub's 5-year summary of these operations!