在之前介绍输入输出函数的文章中,有提到格式化输入输出函数都有包含一种特殊的符号——格式符号。
那篇文章中关于格式符号也只是一笔带过,没有进行深入挖掘。本篇文章主要对输出函数(printf)中的一些常用格式符号进行详细补充。
1、介绍
格式占位符%加上特定的数字、字母,组成格式符号。
其作用是在字符串中占位,等后面传入的参数来进行替换。
printf函数中,字符串里如果有格式符号,可变参数列表中就得有相应的参数(变量、常量、表达式等)。
如果不提供参数,打印的结果就会出现意料外的数据(随机值)。
且格式字符匹配是按顺序的一个一个填进去。
2、整型
%d是用来输出十进制的整数,对应的数据类型是int。
%u也是用来输出十进制的整数,对应的数据类型是unsignedint。和%d的区别在于,%d可以输出负数,%u只能输出正数。
表示整数的格式符号,还有%o和%x,分别输出8进制和16进制的整数。
其中%x中的x如果是小写的,输出结果中的字母也全都是小写;反之,X是大写的,输出结果的字母也都是大写的。
同样,这两种格式符号也是输出没有符号的整数结果。和%u一样,当给定的是一个负数参数,结果虽然不是预期的,但也是有结果。至于这个结果怎么得到的,就涉及到二进制码的反码和补码,这里就不做具体展开。
无论是int,还是其他整型,如short、long、longlong类型,只要数值在int的范围内,也是能正常输出数值。
但如果数值大于int的最大范围,比如longlong类型,就会出现意外结果。
比如在2位的编译器中,int类型占4个字节,而longlong类型占8个字节。用以上这些符号,只会识别前4个字节的内,后面4个字节的内容就会被舍弃掉,从而得出一个错误的值。
那么想要正常输出long或者longlong类型的数值,就需要使用相应的格式符号。
long类型对应的格式符号:%ld。
longlong类型对应的格式符号:%lld。
、浮点型
从定义上来看,%f是用来输出单精度浮点数float类型,%lf是用来输出双精度浮点数double类型。
但在实际测试中,符号的使用似乎对数据的精度不会产生影响。无论是%f还是%lf,都是可以输出两种类型的值。
而对精度有最直接的影响是发生在定义中。
众所周知,2/是一个无限循环小数。但在计算机中是不可能存在无限循环的概念,最后都会有一个终止的时候。
而计算到什么时候才终止,就取决于数据类型所对应的内存空间能存储多少。
正常使用%f和%lf,是默认保留小数点后六位,然后输出到屏幕上。但为了方便观察不同浮点数类型的精度缺失问题,于是多扩展到小数点后2位。
表现方式为%.nf或者%.nlf,其中n必须是正整数,不能为负数。n为多少,就保留到小数点后n位,同时进行四舍五入。
从结果中可以发现,无论%f符号还是%lf符号,最终的输出结果对精度并没有直接的影响。
精度的影响是从变量定义开始的。
变量a2虽然是double类型的,但是后面的表达式中得出的是float类型的结果,而后再转变为double类型赋给变量a2。
变量a的表达式虽然计算后是double类型,但在赋值给变量a的时候进行类型转换,从高到低的类转换,精度就会发生缺失。
4、字符和字符串
%c在屏幕上输出一个字符,对应的是char类型。
%s在屏幕上输出一连串的字符(字符串),对应的是char*指针类型。
字符这一对和上面的整型和浮点型不一样。
上面的两种类型,只要数值在范围内,同一个格式符号,输出不同类型的数据,也是能够正常显示。
但字符就不一样的,%c对应的参数能用字符串吗?反之,%s可以用单字符吗?
当使用%c格式符号,传入的参数是字符串,输出是可以输出,但得到的会是一个未知的符号。例如我运行后获得一个问号:
而使用%s格式符号,传入的参数是char类型的数据就会引发异常。
关于%c输入还有一个比较好玩的,有时候两个%c,传入的参数是两个任意的整数,会构成一个新的字符,可能是汉字,或者其他字符。
5、指针
指针,C新手的终点,C高手的起点。
C语言中很多操作都是依赖指针来进行的,而指针是直接对内存进行操作。
%p符号中的p即pointer,指针。顾名思义,该符号是用来向屏幕输出指针数据,即内存地址。
而内存地址,一般是以十六进制展现的。但和%x不同,%p展示的格式是特定的。一般为8位,右对齐,结果不足自动补0。
每一个内存都包含两个信息,一个是内存的地址,另一个是内存中存储的数据。
直接调用基本数据类型(如整型、浮点型、字符型、指针等),获取的是内存中存储的数据。而要调用其所对应的内存地址,就需要通过寻址运算符()。
例如,直接调用变量a,输出的结果为。
直接调用指针变量p虽然打印的也是内存地址,但这不是它自身的地址,而是变量a的地址。因此,本质上还是调用了内存中所存储的数据。
数组是一连串相同类型的不同元素,如果直接调用数组变量arr,系统不知道你需要的是数组中的哪一个数据。
因此,数组变量往往存的是数组中第一个元素的内存地址。从结果中也可以看出。
而想要获取数组中具体某一个元素的内存地址,此时已经拆分成基本的数据类型,就要通过寻址运算符来获取。
文末
趁着周末休息的时间写一写文章,本来已经罗列了大纲,准备一口气详细整理下格式化输入输出函数中的格式符号。
在写作的过程中,新的问题不断地涌现,就又得去研究学习。单单就输出函数的格式符号一小部分内容就够衍生许多知识,因此只挑了几个常用的讲,其中可能还是不够全面。
如果全部输出,估计得上万了,且时间就得花费更多,所以一些内容留待后面再更新。
内容太多一来看起来比较累,二来消化起来也不容易。
最后写写改改,才输出这篇文章。写到后面有些昏了头,文中可能出现一些描述的不恰当,不够细致,或者有错误的地方,希望大家能够不吝指点一下,万分感谢。
最后,如果您觉得本篇文章对您有用,点个赞支持一下呗!
转载请注明:http://www.0431gb208.com/sjszjzl/4767.html