| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1080 人关注过本帖
标题:对有预处理的printf()有一点比较疑惑
只看楼主 加入收藏
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
printf()是一个库函数,所谓库函数,是用C语言写好的一些函数,供程序员使用的,它本身不是C语言内置的东西,但体现C语言的特色,我们学库函数,是体会语言如何实践的,即了解语言写出来的东西“原来可以是这样的”。

printf()函数的处理过程其实是这样:首先照原样输出格式字符串,逐个字符用putchar()輸出,当它遇到'%'号,就开始警惕了,此时不輸出,先看下一个字符是什么,如果是约定的一些控制格式符,比如是d,那么就意味着,它需要輸出一个十进制表示的字符串(不再是原样输出),于是它到参数列表中,按顺序提出与%d对应的那个数据,视为十进制整数(其实是不管那个数据是不是真的十进制整数都当作是十进制整数),(用大家都学过的那种转换算法)转换为字符串,填在%d的位置;如此不断遍历第一个参数字符串的所有字符,不断处理,直到结束。

授人以渔,不授人以鱼。
2015-07-03 10:37
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
接着11楼,现在看看printf()是怎么处理字符串%s輸出的。如前所述,printf()函数会扫描格式字符串(只限于参数表的第一个参数,它不会拿第二个以后的参数当作格式控制串来处理),如果发现到%s,它会把对应的参数视为一个字符数组的入口地址,从那个入口开始循环提取字符并輸出直至遇到'\0'。

明白了这个,就明白printf()当需要輸出字符串时,为什么要求参数是一个指向字符的指针(char*类型)变量了,这与其他数据类型的輸出不同,是因为C语言对字符串有一种特定的约定——C语言把一个带有'\0'字符的字符数组当作是字符串!这种“字符串”概念是一种处理手段(约定),並非C语言本身真有字符串这种数据类型,这是必须要明白的道理。往后学,很多问题都与此相关,解答也在这里。

授人以渔,不授人以鱼。
2015-07-03 10:58
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
请注意并记住:我反反复复地使用“视为”的字眼!!!

[ 本帖最后由 TonyDeng 于 2015-7-3 11:01 编辑 ]

授人以渔,不授人以鱼。
2015-07-03 10:58
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
C语言的“字符串”,是一种对有特定约定的字符数组的处理手段,这种“字符串”术语称之为cz串,意思是以零(z是zero,'\0'就是zero)为结束标志的字符流。而C++以及其他语言的字符串(string),是一种真正的数据类型,其实现机制与此不同,是不能混淆的。有些学过C的人,会自以为理解C++的string,其实很多理解都是错的,原因就是没有把C忘掉而带入了C++中,跳跃性的读书,结果理解似是而非。

[ 本帖最后由 TonyDeng 于 2015-7-3 11:14 编辑 ]

授人以渔,不授人以鱼。
2015-07-03 11:12
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
C的字符串处理效率很低,这是众所周知的,原因正是它在涉及求取字符串长度的场合,都需要遍历查找'\0'标志,而溢出和越界错误,往往也是因此而来。C++的string和BASIC的字符串效率都比cz高,原因是它们不用约定结束标志,而是直接储存有串的真实长度数据,string对象取长度的方法str.size()是返回结构体的一个字段值,这个值是在对字符串进行编辑和修改时动态维护的,不用像C那样遍历搜寻(在C中调用strlen()求串长度实际上执行了一个循环动作,所以很多介绍C编程技巧的书都教人先用strlen()獲得長度放在变量中再用于for()循环,道理就在这里),在大量使用串长度、或串的字符数动态变化的场合,cz的那种循环机制当然比简单地读取長度变量值的效率低,何况C串动态改变空间尺寸时还涉及内存管理的开销,哪是某些人以为的凡用C就高效那样简单。C的高效在于它整块整块地处理数据!

[ 本帖最后由 TonyDeng 于 2015-7-3 11:28 编辑 ]

授人以渔,不授人以鱼。
2015-07-03 11:12
hjx1120
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:李掌柜
等 级:贵宾
威 望:41
帖 子:1314
专家分:6927
注 册:2008-1-3
收藏
得分:0 
原来如此!多谢解惑
2015-07-03 11:24
宫九
Rank: 1
等 级:新手上路
帖 子:4
专家分:0
注 册:2015-6-30
收藏
得分:0 
2015-07-03 13:06
快速回复:对有预处理的printf()有一点比较疑惑
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.031432 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved