C 语言格式化输出函数中常用的格式符号

大神们,打扰一下,C 语言格式化输出函数中常用的格式符号
最新回答
无色的海

2024-10-14 07:22:56

在先前的输入输出函数介绍中,提到了格式化输入输出函数包含一种特殊符号——格式符号。

之前关于格式符号的介绍只是简要提及,并未深入探讨。

本文将详细介绍输出函数(printf)中的一些常用格式符号。

1、介绍

格式占位符 % 与特定的数字、字母结合,形成格式符号。

它们在字符串中占位,等待后面传入的参数进行替换。

printf 函数中,字符串内若有格式符号,可变参数列表中就得有相应的参数(变量、常量、表达式等)。

若不提供参数,打印结果可能出现意外数据(随机值)。

且格式字符匹配是按照顺序一个接一个填充。

2、整型

%d 用于输出十进制的整数,对应数据类型为 int。

%u 同样用于输出十进制的整数,对应数据类型为 unsigned int。

与 %d 的区别在于,%d 可输出负数,而 %u 只能输出正数。

表示整数的格式符号还有 %o 和 %x,分别输出 8 进制和 16 进制的整数。

其中 %x 中的 x 若是小写,输出结果中的字母也全为小写;反之,X 是大写的,输出结果的字母也全为大写。

这两种格式符号也是输出无符号整数结果。

当给定负数参数时,结果虽然不是预期的,但仍有结果。

至于这个结果如何得到,就涉及到二进制码的反码和补码,这里不做具体展开。

无论是 int,还是其他整型,如 short、long、long long 类型,只要数值在 int 范围内,也能正常输出数值。

但如果数值大于 int 的最大范围,比如 long long 类型,就会出现意外结果。

比如在 32 位的编译器中,int 类型占 4 个字节,而 long long 类型占 8 个字节。

用以上这些符号,只会识别前 4 个字节的内,后面 4 个字节的内容就会被舍弃掉,从而得出一个错误的值。

那么想要正常输出 long 或 long long 类型的数值,就需要使用相应的格式符号。

long 类型对应的格式符号:%ld。

long long 类型对应的格式符号:%lld。

3、浮点型

从定义上看,%f 用于输出单精度浮点数 float 类型,%lf 用于输出双精度浮点数 double 类型。

但在实际测试中,符号的使用似乎对数据的精度没有影响。

无论是 %f 还是 %lf,都可以输出两种类型的值。

对精度影响最直接的是变量定义。

众所周知,2 / 3 是一个无限循环小数。

但在计算机中不可能存在无限循环的概念,最后都会有一个终止的时候。

而计算到什么时候才终止,就取决于数据类型所对应的内存空间能存储多少。

正常使用 %f 和 %lf,默认保留小数点后六位,然后输出到屏幕上。

但为了方便观察不同浮点数类型的精度缺失问题,于是扩展到小数点后 32 位。

表现方式为 %.nf 或者 %.nlf,其中 n 必须是正整数,不能为负数。

n 为多少,就保留到小数点后 n 位,同时进行四舍五入。

从结果中可以发现,无论 %f 符号还是 %lf 符号,最终的输出结果对精度没有直接影响。

精度的影响是从变量定义开始的。

变量 a2 虽然是 double 类型的,但是后面的表达式中得出的是 float 类型的结果,而后再转变为 double 类型赋给变量 a2。

变量 a3 的表达式虽然计算后是 double 类型的,但在赋值给变量 a3 的时候进行类型转换,从高到低的类转换,精度就会发生缺失。

4、字符和字符串

%c 在屏幕上输出一个字符,对应的是 char 类型。

%s 在屏幕上输出一连串的字符(字符串),对应的是 char * 指针类型。

字符这一对与上面的整型和浮点型不同。

上面的两种类型,只要数值在范围内,同一个格式符号,输出不同类型的数据,也能正常显示。

但字符就不一样了,%c 对应的参数能用字符串吗?反之,%s 可以用单字符吗?

当使用 %c 格式符号,传入的参数是字符串,输出是可以输出,但得到的会是一个未知的符号。

而使用 %s 格式符号,传入的参数是 char 类型的数据就会引发异常。

关于 %c 输入还有一个比较好玩的,有时候两个 %c,传入的参数是两个任意的整数,会构成一个新的字符,可能是汉字,或者其他字符。

5、指针

指针,C 新手的终点,C 高手的起点。

C 语言中很多操作都是依赖指针来进行的,而指针是直接对内存进行操作。

%p 符号中的 p 即 pointer,指针。

顾名思义,该符号是用来向屏幕输出指针数据,即内存地址。

而内存地址,一般是以十六进制展现的。

但与 %x 不同,%p 展示的格式是特定的。

一般为 8 位,右对齐,结果不足自动补 0。

每一个内存都包含两个信息,一个是内存的地址,另一个是内存中存储的数据。

直接调用基本数据类型(如整型、浮点型、字符型、指针等),获取的是内存中存储的数据。

而要调用其所对应的内存地址,就需要通过寻址运算符(&)。

例如,直接调用变量 a,输出的结果为 00000001。

直接调用指针变量 p 虽然打印的也是内存地址,但这不是它自身的地址,而是变量 a 的地址。

因此,本质上还是调用了内存中所存储的数据。

数组是一连串相同类型的不同元素。

如果直接调用数组变量 arr,系统不知道你需要的是数组中的哪一个数据。

因此,数组变量往往存的是数组中第一个元素的内存地址。

从结果中也可以看出。

而想要获取数组中具体某一个元素的内存地址,此时已经拆分成基本的数据类型,就要通过寻址运算符来获取。

文末

趁着周末休息的时间写一写文章,本来已经罗列了大纲,准备一口气详细整理下格式化输入输出函数中的格式符号。

在写作的过程中,新的问题不断地涌现,就又得去研究学习。

单单就输出函数的格式符号一小部分内容就够衍生许多知识。

因此只挑了几个常用的讲,其中可能还是不够全面。

如果全部输出,估计得上万了,且时间就得花费更多。

所以一些内容留待后面再更新。

内容太多一来看起来比较累,二来消化起来也不容易。

最后写写改改,才输出这篇文章。

写到后面有些昏了头,文中可能出现一些描述的不恰当,不够细致,或者有错误的地方。

希望大家能够不吝指点一下,万分感谢。

最后,如果您觉得本篇文章对您有用,点个赞支持一下呗!