C打印函数printf的一种实现原理简要分析
【0】README
- 0.1)本文旨在对 printf 的 某一种 实现 原理进行分析,做了解之用;
- 0.2) vsprintf 和 printf.c 的源码,参见
https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/p309
【1】printf函数代码分析:
https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/p309/printf.c
- P1)line66: va_list arg = (va_list)((char*)(&fmt) + 4); 要知道,对于C函数的调用,压栈顺序是从右参数往左边参数压栈,最右边参数最先压栈,最左边参数最后压栈;当然, (&fmt+4)指向的是 printf参数列表中 “…” 的首地址, 而“…” 代表的是参数列表(低地址到高地址,因为压栈顺序就是从高地址到低地址压栈):MAG_CH_ASSERT, exp, file, base_file, line ;
- P2)结合以上叙述,我们得到 buf 就是个字符串数组(可以看做缓冲区)、 fmt = “%c assert(%s) failed: file: %s, base_file: %s, ln%d” 、arg = MAG_CH_ASSERT, exp, file, base_file, line 五个参数列表(即长度为5的20字节数组,每个地址4个字节);
【2】vsprintf 函数代码分析:
https://github.com/pacosonTang/dataStructure-algorithmAnalysis/blob/master/p309/vsprintf.c
V1)line68: 调用 vsprintf 函数,同样的,参数压栈顺序是从右往左压栈, 我们看看vsprintf 的源码, 结合源码,我们的分析如下:
- V1.1)line57~60 :非找到 fmt 中的 % 不可(%是定义输出格式的标识符), 且fmt 的字符是一个一个copy 到buf 的;
- V1.2)line87~113:从参数列表 p_next_arg = args 中 抽取出 格式字符串,用q = inner_buf 来存储这些参数值;(显然,i2a()函数是 数字输出的不同进制的转换,16进制、10进制等),p_next_arg += 4; p_next_arg 为什么自加4 ,不用我多说了吧;
- V1.3)line119~122:用inner_buf 存储的格式输出值 去填充 %定义的格式输出;
V2)再看看 vsprintf 对于 输出格式宽度是如何处理的?如%10d,等等;
- V2.1)line62 :将align_nr 初始化为 0;
- V2.2)line67~77: 是在 对 %下一个字符出现的可能情况的处理: 如果有两个 %% 并排,则表明输出为%、如果为0,待会cs=0、如果是其他情况,cs=空格;
- V2.3)line78~82: 是在对 % 下一个字符是数字(打印宽度)的处理;
- V2.4)line115~118:将cs 的值赋给 缓冲区 buf, 这里应该是把空格赋值过去,以填充打印宽度(说实话,这里我也没有好懂, 不过printf 的 实现步骤的大致方向清楚了);
版权声明:本文为博主原创文章,未经博主允许不得转载。
C打印函数printf的一种实现原理简要分析的更多相关文章
- stm32_f103使用gcc编译的环境下printf打印函数的实现
前记 gcc编译使用的printf打印函数需要的底层函数是和其他编译器不同的,以前的是无法使用的,这里有两种方法,一种是使用gcc库里面的printf函数,自己实现底层IO函数_write.另外一 ...
- 嵌入式操作系统---打印函数(printf/sprintf)的实现
一.打印函数简介 作用:将“给定的内容”按照“指定的格式”输出到“指定目标内”. 打印函数的基本格式: char print_buf[BUF_SIZE]; void printf(const char ...
- Linux使用标准IO的调用函数,分3种形式实现
/*根据cp命令的格式要求,设计一个类cp的功能程序,要求使用标准IO的调用函数,分3种形式实现,字符,行,块.并注意函数功能的分层*/ #include<stdio.h> #includ ...
- Objective-C与Swift下的自定义打印函数(Debug和Release)
1.Objective-C 在使用Objective-C进行开发的过程中,为了Debug会不断的设置打印函数.如下图是我们经常用的,用来测试监听方法的实现与否: NSLog(@"%s&quo ...
- Visual Studio C++ MFC界面常用参数更改(改变图标,添加控件,调试打印函数等等)
背景 需要使用Visual Studio C++做一些界面.此篇文章既是记录Visual Studio C++在调整界面时常常遇见的问题. 正文 一.如何更改窗体图标,以及生成的.exe图标 更改窗体 ...
- scala函数定义的四种方式
最近开始接触scala编程语言,觉得还是比较新的一个东西,虽然说和java比较像,是java的继承者,兼顾面向对象编程和函数式编程的优点,但是,终究是一个新的东西,还是要从最基本的学起.而这当中,函数 ...
- 【三支火把】---一份程序看懂C程序printf()的几种常用用法
闲来继续巩固我的学习之路,今天略微整理了一下,C程序中Printf()的一些常用用法,虽然自己以前好像会,但是不够系统,今天大致整理了一些,先贴上来看看,以后在看到其他,继续补充,希望能帮到一些像我一 ...
- IOS学习笔记07---C语言函数-printf函数
IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...
- java 打印空心菱形的两种实现
第一种实现方式: //打印给定行数的空心菱形 public static void draw(int size){ if (size % 2 == 0) //如果是偶数行变为奇数 { size++; ...
随机推荐
- EL与OGNL
EL表达式: >>单纯在jsp页面中出现,是在四个作用域中取值,page,request,session,application. >>如果在struts环境中,它除了有在上 ...
- 移动电子商务:五个技术标准与Trustonic TEE解决方案【转】
转自:http://www.vonwei.com/post/mobileTrustonicTEE.html 转载申明:本站原创,欢迎转载.但转载时请保留原文地址.原文地址:http://www.von ...
- hdu 1452(因子和+逆元)
Happy 2004 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- Java IO 学习(零)概述
参考文献 Doug Lea的 <Scalable IO in Java> Java NIO trick and trap IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇) 网络编程释疑 ...
- 从客户端(ExportContent="...ontinuous <br />Pass Count":13...")中检测到有潜在危险的 Request.Form 值。
mvc中,用chrome浏览器导出excel提示如题错误的解决办法. <system.web> <httpRuntime requestValidationMode="2. ...
- Using Blocks in iOS 4: The Basics
iOS 4 introduces one new feature that will fundamentally change the way you program in general: bloc ...
- C语言实现的水仙花数
#include <stdio.h>void main(){ int ge,shi,bai; for (int i =100; i < 1000; i++) { ...
- 实例化Spring容器的两种常用方式
//在类路径下寻找配置文件来实例化容器 ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"b ...
- 出自 HTML4 规范的可用颜色字符串值列表(常用颜色名称及对应的十六进制值)
据称由于 HTML5 没有修改专属的颜色,HTML4 的颜色都可以在 HTML5 中正确显示. 出自 HTML4 规范的可用颜色字符串值列表如下,此表来源是 http://www.lovean.com ...
- Java Jsoup Spider抓取数据入库
这里从车商网上进行数据抓取,请保持良好的职业道德不要将数据用于商业途径.工信部官网有汽车方面的公告目录,那里有最全的pdf或word数据,鉴于word和pdf解析的繁琐和耗时,我暂时用这个网站的数据进 ...