3-1. printf函数详细解析

  • 学习人数 30K+
  • 适合所有人群学习
avatar
林耿亮

你好编程主讲老师

1. printf函数使用公式

在前几篇文章中,我们已经使用过很多次printf函数了。

这一节,我们先复习一下printf的使用公式,然后再来详细讨论一下它。

printf函数的使用公式:


printf("XXX占位1 XXX 占位2 XXX占位3", 替换1, 替换2, 替换3);


根据公式,我们写出以下示例代码。

#include <stdio.h>
int main()
{
    int a = 1;
    float b = 2.345;
    char c = 'a';
    printf("整型a为%d 浮点b为%f 字符c为%c 字符c对应的ASCII码为%d", a, b, c, c);
    return 0;
}

printf示例代码运行结果

让我们从以下5点详细分析一下printf的用法:

  1. printf是一个变参函数。(参数的数量和类型不确定)
  2. printf的第一个参数是字符串。
  3. printf的第一个参数是需要输出的字符以及需要被替换的占位符。
  4. printf的第二及后续参数将依次替换占位符。
  5. 占位符的类型和数量需要与后续的参数类型和数量对应。

1.1 printf是一个变参函数

关于printf是一个变参函数的事实,我们在前面对printf的使用中,已经充分验证过了。

它的参数个数是不确定的,同时参数类型也是不确定的。

printf("%d", 1);                    //  两个参数
printf("%d %f", 1, 2.3);            //  三个参数
printf("%d %f %c", 1, 2.3, 'H');    //  四个参数

1.2 第一个参数必须字符串

printf第一个参数为字符串

1.3 第一个参数包含需要输出的字符以及需要被替换的占位符

printf第一个参数包含需要输出的字符以及需要被替换的占位符

这个字符串包含了需要输出的字符,以及需要被替换的占位符。

1.4 第二及后续参数将依次替换占位符

第二及后续参数将依次替换占位符

1.5 占位符的类型和数量需要与后续的参数类型和数量对应

占位符的类型和数量需要与后续参数类型和数量对应

2. 整型类型的占位符

在前面的printf函数的使用当中,我们一直将%d作为整型int类型的占位符。对于其他的整型类型,它们的占位符分别都是什么呢?

printf是一个可变参数函数,在C语言中将参数传入函数的可变参数中,变量会发生自动类型提升。

2.1 有符号整型的类型提升

对于有符号位的整型charshort,传入printf的可变参数时,会被提升为int。而比int更高级的整型则不发生变化。

比int低级的被提升为int

所以,在处理charshortint时,均可使用%d来占位。

而在Visual Studio中intlong的范围一致,按理来说也可以使用%d来占位。

但是为了程序的可移植性,在切换到别的平台下时,intlong有可能不一致。

所以,请使用%ld来为long占位。更高级的long long则需要使用%lld来占位。


结论: char,short,int使用%d。 long使用%ld。 long long使用%lld


2.2 无符号整型的类型提升

对于无符号位的整型unsigned charunsigned short,传入printf的可变参数时,会被提升为unsigned int

而比unsigned int更高级的整型则不发生变化。

比uint低级的被提升为uint

对于无符号整型,需要将d替换成u表明最高位不被看作符号位,而是数据位。


结论: unsigned char,unsigned short,unsigned int使用%u。 unsigned long使用%lu。 unsigned long long使用%llu


2.3 浮点类型的类型提升

float会被提升为doubledouble不发生变化。


结论: float,double均使用%f