- 1、本文档共23页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
printf函数实现机制;printf函数(格式化的输出函数〕
作用是向终端〔或系统隐含指定的输出设备〕,输出假设干个指定类型的数据。
printf函数的一般格式
一般格式:printf(格式控制,输出表列);
格式说明:由“%”和格式字符组成,如%d,%f等
普通字符:原样输出的字符
输出列表:需要输出的数据,可以是常量、变量或表达式;例如:
printf(“%d,%c”,i,c);
printf(“HelloWorld!”);
问题:;由于printf是函数,因此“格式控制”字符串和“输出列表”实际上都是函数的参数。其一般的函数表示形式为:
printf(参数1,参数2,参数3,…,参数n)
需要解决的问题
1.怎样让printf函数知道传递了多少参数?
2.printf函数怎样访问这些参数?
;什么是可变参函数
所谓含有变长参数的函数是指该函数可以接受可变数目的形参。
如何实现可变参函数
三个宏和一个栈
va_start
va_arg
va_end;2.可变参函数;函数调用栈
对于c语言,它的调用规那么遵循_cdecl调用规那么:
1.参数从右到左依次入栈
2.调用者负责清理堆栈
3.参数的数量和类型不会导致编译阶段的错误;第一个宏:va_start
参数:ap为va_list类型指针,v是最后一个确定的参数,最后一个确定的参数的含义是指它以后的参数都是可变参数。
功能:获取参数列表中的第一个可变参数的内存地址,结果存放在ap中。
注:_INTSIZEOF()宏是为了实现地址对齐的
;第一个宏:va_start
;第二个宏:va_arg
参数:ap为va_list类型的指针,它指向当前需要获取的参数,t是当前参数的类型
功能:获取ap当前所指向的参数的指针,并将其类型强制转化t*,然后将ap指向下一个变长参数
;第三个宏:va_end
参数:ap为va_list类型指针
功能:将指针指向空,说明不再使用该指针
注:C标准要求在同一个函数中va_start和va_end要配对出现;2.可变参函数;可变长参数函数的一般实现方法:
1.声明原型,形如voiddemo(char*msg,...),注意变长参数的原型声明中至少要含有一个确定参数;
2.用va_list定义保存函数参数的数据结构,可以理解为一个指针变量;
3.用va_start将上一步定义的变量指向第一个可变参数;
4.用va_arg遍历所有的可变参数;
5.用va_end将指针变量持有的地址值置为0。;在Linux内核中printf函数被封装成下面的代码:;实现过程
在vsprintf函数中,依次扫描format的每个字符,遇到%那么调用va_arg取参数并移动参数栈指针,否那么原样打印
printf(参数1,参数2,参数3,…,参数n);printf转换控制字符串的一般形式如下:
%[flags][width][.prec][type]
flags:附加格式说明字符,如:-(左对齐),0(补零)
width:域宽,如果宽度域中是数值那么直接取其为宽度值。如果宽度域中是字符*,表示下一个参数指定宽度。
prec:正整数的最小位数
???????????在浮点数中表示的小数位数
????????????%g格式表示有效为的最大值
????????????%s格式表示字符串的最大长度
????????????假设为*符号表示下个参数值为最大长度
type:格式字符,如:d,c,f,s,o,x;核心代码结构vsprintf(sprint_buf,fmt,args);;;;;整个printf的工作过程是
1.先声明两个变量,一个是“变参类型”,一个是整型变量〔记录字符个数,留待返回〕
2.根据固定参数确定变参起始位置
3.根据每个变参的位置和类型〔长度〕,通过va_arg算出下一个变参的地址
4.令“变参类型”指向NULL,并返回字符个数
主线是format
根据format中用户指定的格式及数据类型,将参数栈中的参数按顺序依次读出〔利用va_arg宏〕,并输出。;printf的工作过程
printf(“%8.3f,%d\n”,a,b);
;谢谢!!
文档评论(0)