你会写 printf 吗?
关于 vsprintf
今天花了很长的时间去理解 vsprintf
这个函数并且自己把它实现了一遍。果然,比对着书打难多了。不过,确实是收获特别多,而且自己实现的话,能够加深理解,而不仅仅是从书上理解那么片面。
先说一下 vsprintf()
这个函数的作用。它是 printf()
的一个处理函数,接受 3 个变量:buf 是用来存放处理完的字符串,或者是说,将 printf
的第一个参数里面的 %d
啊, %s
等用后面对应的参数替换之后的字符串。fmt
很明显,就是 printf()
的第一个参数。arg
这个参数,是指向 printf()
第二个参数以及后面参数的一个指针。理解这一点很重要。
然后这个函数的流程就是这样的,不断地扫描 fmt
,如果不是 %
,则直接赋给 buf
;如果是 %
的话,那么就看他的下一位是什么,是 %
的话,说明只是 %
的一个转义符,直接赋给 buf
。否知,如果是非零的数字,那么说明是一个 宽度说明 ,就必须计算宽度的长度。之后肯定就是控制格式符号 c
,s
,x
等了。在这些控制格式符中,d
和 x
由于存在进制的转换,所以要有相应的函数来处理进制转换,i2a()
就实现了这一个功能。这个函数,不得不说,是一个十分优美的实现,采用了递归。相当于先从低位到高位依次入栈,然后在依次弹栈,并不难理解,不过,我想说一点的是,这个函数的第三个参数:char **ps, 这是一个二级指针。里面的一句
*(*ps)++ = remain;
这一句一开始老是理解不了,高级次的指针真的有点难以理解。不过,最后总算是理解了:
这一句的作用就是改变
ps
这个指针的指针指向的指针,或者说,指向的字符串
没错,指针真的十分的优美!不过,指针也十分的危险,所以,只有正确地理解并且运用,才能发挥指针的强大功能!
Author: simowce
Permalink: https://blog.simowce.com/chapter-8-printf/
本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。