【0】README


【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的一种实现原理简要分析的更多相关文章

  1. stm32_f103使用gcc编译的环境下printf打印函数的实现

    前记   gcc编译使用的printf打印函数需要的底层函数是和其他编译器不同的,以前的是无法使用的,这里有两种方法,一种是使用gcc库里面的printf函数,自己实现底层IO函数_write.另外一 ...

  2. 嵌入式操作系统---打印函数(printf/sprintf)的实现

    一.打印函数简介 作用:将“给定的内容”按照“指定的格式”输出到“指定目标内”. 打印函数的基本格式: char print_buf[BUF_SIZE]; void printf(const char ...

  3. Linux使用标准IO的调用函数,分3种形式实现

    /*根据cp命令的格式要求,设计一个类cp的功能程序,要求使用标准IO的调用函数,分3种形式实现,字符,行,块.并注意函数功能的分层*/ #include<stdio.h> #includ ...

  4. Objective-C与Swift下的自定义打印函数(Debug和Release)

    1.Objective-C 在使用Objective-C进行开发的过程中,为了Debug会不断的设置打印函数.如下图是我们经常用的,用来测试监听方法的实现与否: NSLog(@"%s&quo ...

  5. Visual Studio C++ MFC界面常用参数更改(改变图标,添加控件,调试打印函数等等)

    背景 需要使用Visual Studio C++做一些界面.此篇文章既是记录Visual Studio C++在调整界面时常常遇见的问题. 正文 一.如何更改窗体图标,以及生成的.exe图标 更改窗体 ...

  6. scala函数定义的四种方式

    最近开始接触scala编程语言,觉得还是比较新的一个东西,虽然说和java比较像,是java的继承者,兼顾面向对象编程和函数式编程的优点,但是,终究是一个新的东西,还是要从最基本的学起.而这当中,函数 ...

  7. 【三支火把】---一份程序看懂C程序printf()的几种常用用法

    闲来继续巩固我的学习之路,今天略微整理了一下,C程序中Printf()的一些常用用法,虽然自己以前好像会,但是不够系统,今天大致整理了一些,先贴上来看看,以后在看到其他,继续补充,希望能帮到一些像我一 ...

  8. IOS学习笔记07---C语言函数-printf函数

    IOS学习笔记07---C语言函数-printf函数 0 7.C语言5-printf函数 ------------------------- ----------------------------- ...

  9. java 打印空心菱形的两种实现

    第一种实现方式: //打印给定行数的空心菱形 public static void draw(int size){ if (size % 2 == 0) //如果是偶数行变为奇数 { size++; ...

随机推荐

  1. Oracle创建自增长主键

    Oracle主键常用的分为UUID和自增长int两种,下面简单说下各自的优缺点: UUID的优点 1.生成方便,不管是通过sys_guid() 还是java的uuid都能很方便的创建UUID. 2.适 ...

  2. android日期时间选择器

    android原生的日期时间控件,因为是原生的总有其满足不了我们需求的时候,Android 手机版本那么多,用户弹出来的控件五花八门.因为项目需要,在网上找了一 些demo看了看,感觉有些写的很好,很 ...

  3. nfc是什么?nfc功能是什么?

    http://android.tgbus.com/lab/software/201208/447420.shtml nfc是什么?nfc功能是什么?出现在我们手机上的nfc功能怎么用?下面请看今天小编 ...

  4. Linux系统日常运维-修改IP地址

    分享下高手写的很好的文章 IP地址.子网掩码.网络号.主机号.网络地址.主机地址 step 0: check the iptables.selinux service iptables iptable ...

  5. Wordpress笔记:背景音乐

    想要在blog首页加上自动播放的背景音乐,能找到的插件与方法基本上都是讲在文章里添加的.侧边栏里添加文本的方法也总有美观等等这样那样的问题,折腾了几种之后终于搞定了.用的是Audio player插件 ...

  6. List与set

    1,List与set的区别? List:元素是有序的,元素可以重复,因为集合体系有索引 set:元素是无序的,元素不可以重复,集合体系没有索引 2,list里面特有的方法: 在制定的位置添加元素add ...

  7. Delphi通过管道执行外部命令行程序(cmd)并获取返回结果

    该代码片段来自于: http://www.sharejs.com/codes/delphi/8999,发现好多代码,想用的时候找不到,记录一下备用 function RunDosCommand(Com ...

  8. tomcat启动项目,起不起来

    右键tomcat 选择publish

  9. c语言单链表实现

    /************************************************************************* > File Name: singleLin ...

  10. SGU 231 Prime Sum 求&lt;=n内有多少对素数(a,b)使得a+b也为素数 规律题

    题目链接:contest=0&problem=231">点击打开链接 题意: 求<=n内有多少对素数(a,b)使得a+b也为素数 思路: 我们发现全部素数间隔都是> ...