没有合适的资源?快使用搜索试试~ 我知道了~
printf()函数是格式化输出函数, 一般用于向标准输出设备按规定格式输出信息。 printf()函数的调用格式为: printf("<格式化字符串>", <参量表>)。 格式输出,它是c语言中产生格式化输出的函数(在 stdio.h 中定义)。用于向终端(显示器、控制台等)输出字符。格式控制由要输出的文字和数据格式说明组成。要输出的的文字除了可以使用字母、数字、空格和一些数字符号以外,还可以使用一些转义字符表示特殊的含义。
资源推荐
资源详情
资源评论






















内核printf源代码分析.
打开Source Insight来阅读EduOS的源代码,我们在stdio.c里找到了printf的实现代码.首先看看对printf的定义:
[code]
int printf (const char *cntrl_string, ...)
[/code]
第一个参数cntrl_string是控制字符串,也就是平常我们写入%d,%f的地方.紧接着后面是一个变长参数.
看看函数头部的定义:
[code]int pos = 0, cnt_printed_chars = 0, i;
unsigned char* chptr;
va_list ap;[/code]
马上晕!除了ap我们可以马上判断出来是用来读取变长参数的,i用于循环变量.其他变量都不知道是怎么回事.不要着急,我们边看代码边分析.代码的第一行必然是
[code]va_start (ap, cntrl_string);[/code]
用来初始化变长参数.
接下来是一个while循环
[code]while (cntrl_string[pos]) {
...
}[/code]
结束条件是cntrl_string[pos]为NULL,显然这个循环是用来遍历整个控制字符串的.自然pos就是当前遍历到的位置了.进入循环首先闯入视线的是
[code] if (cntrl_string[pos] == '%') {
pos++;
...
} [/code]
开门见山,上来就当前字符是否办断是否%.一猜就知道如果成立pos++马上取出下一个字符在d,f,l等等之间进行判断.往下一看,果真不出所料:
[code]switch (cntrl_string[pos]) {
case 'c':
...
case 's':
...
case 'i':
...
打开Source Insight来阅读EduOS的源代码,我们在stdio.c里找到了printf的实现代码.首先看看对printf的定义:
[code]
int printf (const char *cntrl_string, ...)
[/code]
第一个参数cntrl_string是控制字符串,也就是平常我们写入%d,%f的地方.紧接着后面是一个变长参数.
看看函数头部的定义:
[code]int pos = 0, cnt_printed_chars = 0, i;
unsigned char* chptr;
va_list ap;[/code]
马上晕!除了ap我们可以马上判断出来是用来读取变长参数的,i用于循环变量.其他变量都不知道是怎么回事.不要着急,我们边看代码边分析.代码的第一行必然是
[code]va_start (ap, cntrl_string);[/code]
用来初始化变长参数.
接下来是一个while循环
[code]while (cntrl_string[pos]) {
...
}[/code]
结束条件是cntrl_string[pos]为NULL,显然这个循环是用来遍历整个控制字符串的.自然pos就是当前遍历到的位置了.进入循环首先闯入视线的是
[code] if (cntrl_string[pos] == '%') {
pos++;
...
} [/code]
开门见山,上来就当前字符是否办断是否%.一猜就知道如果成立pos++马上取出下一个字符在d,f,l等等之间进行判断.往下一看,果真不出所料:
[code]switch (cntrl_string[pos]) {
case 'c':
...
case 's':
...
case 'i':
...
case 'd':
...
case 'u':
...[/code]
用上switch-case了. 快速浏览一下下面的代码.
首先看看case 'c'的部分
[code]case 'c':
putchar (va_arg (ap, unsigned char));
cnt_printed_chars++;
break;[/code]
%c表示仅仅输出一个字符.因此先通过va_arg进行参数的类型转换,之后用putchar[1]输出到屏幕上去.之后是
cnt_printed_chars++,通过这句我们就可以判断出cnt_printed_chars使用来表示,已经被printf输出的字符个数的.
再来看看 case 's':
[code] case 's':
chptr = va_arg (ap, unsigned char*);
i = 0;
while (chptr [i]) {
cnt_printed_chars++;
putchar (chptr [i++]);
}
break;[/code]和case 'c',同出一辙.cnt_printed_chars++放在了循环内,也证明了刚才提到的他的作用.另外我们也看到了cnptr是用来在处理字符串时的位置指针.到此为止,我们清楚的所有变量的用途,前途变得更加光明了.
接下来:
[code]// PartI
case 'i':
case 'd':
cnt_printed_chars += printInt (va_arg (ap, int));
break;
case 'u':
cnt_printed_chars += printUnsignedInt (va_arg (ap, unsigned int));
break;
...
case 'u':
...[/code]
用上switch-case了. 快速浏览一下下面的代码.
首先看看case 'c'的部分
[code]case 'c':
putchar (va_arg (ap, unsigned char));
cnt_printed_chars++;
break;[/code]
%c表示仅仅输出一个字符.因此先通过va_arg进行参数的类型转换,之后用putchar[1]输出到屏幕上去.之后是
cnt_printed_chars++,通过这句我们就可以判断出cnt_printed_chars使用来表示,已经被printf输出的字符个数的.
再来看看 case 's':
[code] case 's':
chptr = va_arg (ap, unsigned char*);
i = 0;
while (chptr [i]) {
cnt_printed_chars++;
putchar (chptr [i++]);
}
break;[/code]和case 'c',同出一辙.cnt_printed_chars++放在了循环内,也证明了刚才提到的他的作用.另外我们也看到了cnptr是用来在处理字符串时的位置指针.到此为止,我们清楚的所有变量的用途,前途变得更加光明了.
接下来:
[code]// PartI
case 'i':
case 'd':
cnt_printed_chars += printInt (va_arg (ap, int));
break;
case 'u':
cnt_printed_chars += printUnsignedInt (va_arg (ap, unsigned int));
break;
剩余5页未读,继续阅读
资源评论


Aase_asd
- 粉丝: 0
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 合肥学院Web实验二HTMLCSS实验实验报告.doc
- 2023年河南监理工程师网络继续教育考试试题参考答案.doc
- 信息化给财务内控带来的挑战【2017-2018最新会计实务】.doc
- 新版基因工程的应用.pptx
- 统考计算机模拟题库.doc
- 液压自动化爬升模板系统结构设计复核计算书.doc
- 软件工程作业及答案.doc
- 网络营销策略整体实施解决方案.doc
- 数模论文写作与软件使用.ppt
- 小户型白领公寓网络行销推广方案.doc
- 计算机专业的求职意向.doc
- (源码)基于ESP32和LoRa的蔬菜花园土壤湿度监测系统.zip
- 基于单片机设计的脉搏测量仪.docx
- 试验(SPSS-Excel-SAS)-.doc
- 智能家居可行性研究报告.doc
- 网络工程设计设计任务书.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制
