C语言printf函数详解..

news2024/11/25 1:06:07

1.printf函数解析

前面我们有讲过printf函数的格式为:
printf(“占位1 占位2 占位3……”, 替代1, 替代2, 替代3……);
今天我们进一步深入的解析一下这个函数

2.printf函数的特点

1.printf函数是一个变参函数(即参数的数量和类型都不确定)
2.printf函数的第一个参数是字符串
3.printf函数的第一个字符串参数中的具体内容就是需要打印的字符以及需要被替代的占位符
4.printf函数第一个参数之后的参数依次替代占位符
5.printf函数中占位和替代的数量和类型对应

3.变参函数

int main(){
    printf("%c\n", 'a');// a
    printf("%c %d\n", 'b', 10);// b 10
    return 0;
}

4.第一个参数必须是字符串

int main(){
    printf("the first argument must be string\n");
    return 0;
}

5.第一个参数包含输出字符以及占位符

int main(){
    printf("the first argument includes %s and %s\n", "character", "placeholder");
    return 0;
}

后续的两个特点我就不一一阐述了

2.整型占位符

1.有符号整型的类型提升

在C语言中 有符号整型遵循一元数字提升的原则 即比int类型小的类型诸如char和short类型的一元数字都会自动提升为int类型
下面这段代码中 char类型的字节原本为1 但是由于进行了一元数字提升 导致变成了int类型 所以打印的结果是为4

int main(){
    char a = 'a';
    printf("%zu\n", sizeof(+a));// 4
    return 0;
}

但是还有一个疑问 就是在visual studio中 long和int类型占用的字节数是一致的 既然这些小于等于int类型的类型都使用%d作为占位符的话 那么long这种等于int的类型适合使用%d作为占位符吗 其实是不妥当的
因为前面讲过C标准没有明确规定类型占用的字节数 所以不同的平台和编译器有着自己的标准 long类型占用的字节数在不同平台和编译器下是不尽相同的
为了体现程序的可移植性 防止代码打印结果产生偏差 我们对于long类型的占位符尽量使用%ld

int main(){
    long l = 11;
    printf("%ld\n", l);
    return 0;
}

2.无符号整型的类型提升

其实他也同有符号整型的类型提升一样遵循一元数字提升 只不过区别在于说无符号整型涵盖的范围就是无符号的整数 而有符号整型涵盖的范围就是有符号的整数
说白了就是 比unsigned int小的无符号整型会自动提升为unsigned int类型 诸如unsigned char、unsigned short在内的一元数字会自动提升为unsigned int类型
下面这段代码可以体现无符号整型的一元数字提升

int main(){
    unsigned char ch = 'a';
    printf("%zu\n", sizeof(+ch));// 4
    return 0;
}

下面这段代码则体现了无符号整型的占位符

int main(){
    unsigned char ch = 'a';
    unsigned int i = 11;
    unsigned long l = 11;
    unsigned long long ll = 11;
    printf("%u %u %lu %llu\n", ch, i, l, ll);
    return 0;
}

3.转换规范

其实占位符这种说法并不准确 较为准确的说法是转换规范 我们称%d这种形式的叫做转换规范
我可以就此举一个例子:% -#0 12 .4 l d
我们可以发现真正的转换规范包含了很多东西 不仅仅是一个字母

1.转换规范的组成

转换规范以%开头 然后依次跟着以下这些元素:
1.零个或者多个标志字符 比如:- # 0
2.一个可选的十进制整型常量表示的最小字符宽度
3.一个可选的.开头的精度 后跟十进制整形常量
4.一个可选的长度指示符
5.一个字符包含的转换操作 诸如:d u f这些字符

2.转换操作

转换操作会根据不同的转换方式 截取n个字节的二进制数据 转换成不同类型的字符或者字符串
在这里插入图片描述
我们从中就可以解释前面的一个疑惑:
double和float类型都可以使用占位符%f 原因在于%f是截取sizeof(double)字节的二进制数据 然后转换为双精度浮点型的字符

1.转换操作d

对于char、short类型的整型来说 通过转换操作d是可以被正确打印的 但是对于long或者long long类型来说 由于他们可能存在int类型范围之外的数据 所以通过这个转换操作显然是不能够被正确打印的 所以对于这种比int大的整型来说 采用他们各自相应的转换操作才是最合适的做法

int main(){
    char c1 = 127;// char类型的最大数据
    short s1 = 32767;// short类型的最大数据
    char c2 = -128;// char类型的最小数据
    short s2 = -32768;// short类型的最小数据
    long long ll1 = 2200000000;// 超出int类型范围的数据
    long long ll2 = 2100000000;// 包含在int类型范围的数据
    printf("%d\n", c1);// 127
    printf("%d\n", s1);// 32767
    printf("%d\n", c2);// -128
    printf("%d\n", s2);// -32767
    printf("%d\n", ll1);// -2094967296
    printf("%d\n", ll2);// 2100000000
    return 0;
}

2.转换操作u

int main(){
    unsigned char c1 = 255;// unsigned char的最大数据
    unsigned short s1 = 65535;// unsigned short的最大数据
    unsigned char c2 = 0;// unsigned char的最小数据
    unsigned short s2 = 0;// unsigned short的最小数据
    unsigned long long ll1 = 4294967295;// unsigned long long类型中包含在unsigned int类型中的数据
    unsigned long long ll2 = 4300000000;// unsigned long long类型中不包含在unsigned int类型中的数据
    printf("%u\n", c1);// 255
    printf("%u\n", s1);// 65536
    printf("%u\n", c2);// 0
    printf("%u\n", s2);// 0
    printf("%u\n", ll1);// 4294967295
    printf("%u\n", ll2);// 5032704
    return 0;
}

3.转换操作d和u的错误搭配

由于有符号int和无符号int的取值范围不一致 导致当我们错误搭配他们的时候 可能会产生不符合预期的结果
如果当错误搭配时 数据处于两者的共同范围之内 那么打印结果符合预期
但是如果不处于两者的共同范围之内的话 那么打印的结果就不符合预期

int main(){
    unsigned int u1 = 2100000000;// 该数据处于有符号int和无符号int的共同范围之内
    unsigned int u2 = 2200000000;// 该数据并不处于两者的共同范围之内
    printf("%d\n", u1);// 2100000000
    printf("%d\n", u2);// -2094967296
    return 0;
}

4.注意数据类型的取值范围

如果数据超出了类型本身的取值范围 那么无论如何打印 都无法获取正确结果

int main(){
    char ch = 200;// 200超出了char类型本身的数据范围 -128~127
    printf("%d\n", ch);// -56
    return 0;
}

5.转换操作c

打印ASCII码表中数值对应的字符

int main(){
    char ch = 65;
    short s = 66;
    int i = 67;
    long l = 68;
    long long ll = 69;
    printf("%c %c %c %c %c\n", ch, s, i, l, ll);
    return 0;
}

6.转换操作f、e、E

截取sizeof(double)个字节的二进制数据 然后转换为双精度浮点型的字符

int main(){
    float f = 12.34;
    double d = 12.34;
    printf("%f\n", f);// 12.34
    printf("%f\n", d);// 12.34
    printf("%e\n", f);// 1.234000e+01
    printf("%E\n", f);// 1.234000e+01
    return 0;
}

7.转换操作o、x、X

截取sizeof(int)个字节的二进制数据 然后将其转换为无符号八进制、十六进制形式整数的字符

int main(){
    unsigned int i = 20;
    printf("%u %o %x %X", i, i, i, i);// 20 24 14 14
    return 0;
}

8.转换操作s

截取sizeof(char*)个字节的二进制数据 即地址值占用的字节数 接着以这个地址开始输出字符串

int main(){
    printf("%s\n", "Hello World!");
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1445375.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux笔记之xhost +和docker的关系以及GDK_SCALE和GDK_DPI_SCALE详解

Linux笔记之xhost 和docker的关系以及GDK_SCALE和GDK_DPI_SCALE详解 ——2024-02-11 code review! 文章目录 Linux笔记之xhost 和docker的关系以及GDK_SCALE和GDK_DPI_SCALE详解xhost 的作用xhost 与 Docker 的关系 -e GDK_SCALE 和 -e GDK_DPI_SCALE详解GDK_SCALEGDK_DPI_SC…

Java集合 LinkedList

目录 LinkedList实例 LinkedList LinkedList是Java中的一个重要的数据结构,它实现了List接口,提供了链表数据结构的实现。LinkedList类中包含了各种常用的链表操作,如添加、删除、查找等。 LinkedList的特点是元素可以动态地添加到链表的任…

【转载】原生社区交友婚恋视频即时通讯双端APP源码 ONE兔2.0版

原生社区交友婚恋视频即时通讯双端APP源码下载ONE兔2.0版 包含后端、H5源码源码,Android源码,IOS源码

恒创科技:怎么看云主机的性价比

随着云计算技术的不断发展,云主机已经成为越来越多企业和个人用户的首选计算资源。然而,在选择云主机时,性价比是一个非常重要的考虑因素。那么,怎么看云主机的性价比呢? 通常来说,云主机的成本主要包括硬…

【调试】pstore原理和使用方法总结

什么是pstore pstore最初是用于系统发生oops或panic时,自动保存内核log buffer中的日志。不过在当前内核版本中,其已经支持了更多的功能,如保存console日志、ftrace消息和用户空间日志。同时,它还支持将这些消息保存在不同的存储…

模拟发送 Ctrl+Alt+Del 快捷键

目录 前言 一、在 XP 系统上模拟 SAS 二、在不低于 Vista 的系统上模拟 SAS 2.1 一些细节 2.2 实现原理和应用 三、完整实现代码和测试 3.1 客户端控制台程序 3.2 服务程序 3.3 编译&测试程序 四、总结&更新 参考文献 前言 对于开启了安全登陆的窗口工作站…

FFmpeg中的Color颜色参数解析、转码和HDR

前言 视频中帧的颜色信息非常重要,表示着编码时用到的标准,意味着解码时也要对应上,或者要使用正确的转换函数,否则就会带来色差问题。 关于FFmpeg中的颜色参数,有下边几个重要的结构体: 颜色参数相关的结…

基于SSM的图书馆预约占座系统(有报告)。Javaee项目。ssm项目。

演示视频: 基于SSM的图书馆预约占座系统(有报告)。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring…

seatunnel数据集成(四)转换器使用

seatunnel数据集成(一)简介与安装seatunnel数据集成(二)数据同步seatunnel数据集成(三)多表同步seatunnel数据集成(四)连接器使用 seatunnel除了丰富的连接器类型,其转换…

【大厂AI课学习笔记】【1.6 人工智能基础知识】(3)神经网络

深度学习是机器学习中一种基于对数据进行表征学习的算法。观测值(例如一幅草莓照片)可以使用 多种方式来表示,如每个像素强度值的向量,或者更抽象地表示成一系列边、特定形状的区域等。 深度学习的最主要特征是使用神经网络作为计算模型。神经网络模型 …

python+flask+django医院预约挂号病历分时段管理系统snsj0

技术栈 后端:python 前端:vue.jselementui 框架:django/flask Python版本:python3.7 数据库:mysql5.7 数据库工具:Navicat 开发软件:PyCharm . 第一,研究分析python技术&#xff0c…

《UE5_C++多人TPS完整教程》学习笔记8 ——《P9 访问 Steam(Acessing Steam)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P9 访问 Steam(Acessing Steam)》 的学习笔记,该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版,UP主(也是译者&…

使用UMAP降维可视化RAG嵌入

大型语言模型(LLMs)如 GPT-4 已经展示了出色的文本理解和生成能力。但它们在处理领域特定信息方面面临挑战,比如当查询超出训练数据范围时,它们会产生错误的答案。LLMs 的推理过程也缺乏透明度,使用户难以理解达成结论…

Win10截图的四种方式

截图不一定要依靠通讯软件,现在系统自己就带有这些功能。 1.Win Shift S组合键:选择微信截图,部分截图,随心所欲; 2.Win W组合键:呼出屏幕右侧的工作区,选择屏幕草图,支持裁剪、编辑…

flask+python高校学生综合测评管理系统 phl8b

系统包括管理员、教师和学生三个角色; 。通过研究,以MySQL为后端数据库,以python为前端技术,以pycharm为开发平台,采用vue架构,建立一个提供个人中心、学生管理、教师管理、课程类型管理、课程信息管理、学…

网络安全工程师技能手册(附学习路线图)

关键词:网络安全入门、渗透测试学习、零基础学安全、网络安全学习路线 安全是互联网公司的生命,也是每位网民的基本需求。现在越来越多的人对网络安全感兴趣,愿意投奔到网络安全事业之中,这是一个很好的现象。 很多对网络安全感…

线程池7个参数描述

所谓的线程池的 7 大参数是指&#xff0c;在使用 ThreadPoolExecutor 创建线程池时所设置的 7 个参数&#xff0c;如以下源码所示&#xff1a; public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable&…

游泳时可以听歌的耳机有哪些?戴游泳耳机有哪些好处?

游泳和跑步在某种程度上相似&#xff0c;特别是在短距离冲刺时&#xff0c;大脑似乎变得空白&#xff0c;而在中长距离的有氧运动中&#xff0c;身体感到疲劳&#xff0c;但大脑却异常清晰&#xff0c;时间却显得格外漫长。如何打发时间&#xff0c;让游泳锻炼变得不无聊&#…

「深度学习」dropout 技术

一、工作原理 1. 正则化网络 dropout 将遍历网络的每一层&#xff0c;并设置消除神经网络中节点的概率。 1. 每个节点保留/消除的概率为0.5: 2. 消除节点&#xff1a; 3. 得到一个规模更小的神经网络&#xff1a; 2. dropout 技术 最常用&#xff1a;反向随机失活 "…

Ubuntu Desktop - Terminal 输出全部选中 + 复制

Ubuntu Desktop - Terminal 输出全部选中 复制 1. Terminal2. Terminal 最大化3. Edit -> Select All4. Copy & PasteReferences 1. Terminal 2. Terminal 最大化 3. Edit -> Select All 4. Copy & Paste Edit -> Copy or Shift Ctrl C Edit -> Paste…