C语言printf函数详解..

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');// aprintf("%c %d\n", 'b', 10);// b 10return 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));// 4return 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));// 4return 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);// 127printf("%d\n", s1);// 32767printf("%d\n", c2);// -128printf("%d\n", s2);// -32767printf("%d\n", ll1);// -2094967296printf("%d\n", ll2);// 2100000000return 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);// 255printf("%u\n", s1);// 65536printf("%u\n", c2);// 0printf("%u\n", s2);// 0printf("%u\n", ll1);// 4294967295printf("%u\n", ll2);// 5032704return 0;
}

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

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

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

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

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

int main(){char ch = 200;// 200超出了char类型本身的数据范围 -128~127printf("%d\n", ch);// -56return 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.34printf("%f\n", d);// 12.34printf("%e\n", f);// 1.234000e+01printf("%E\n", f);// 1.234000e+01return 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 14return 0;
}

8.转换操作s

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

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

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

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

相关文章

使用 FFmpeg 将视频转换为 GIF 动画的技巧

使用 FFmpeg 将视频转换为 GIF 动画 FFmpeg 可以将视频转换为 GIF 动画,方法如下: 1. 准备工作 确保您已经安装了 FFmpeg。 熟悉 FFmpeg 的命令行使用。 了解 GIF 动画的基本知识。 2. 基本命令 ffmpeg -i input.mp4 output.gif 3. 参数说明 -i in…

JPEG图像格式加速神经网络训练--使用DCT训练CNN

JPEG图像格式加速神经网络训练 JPEG图像格式加速神经网络训练工作原理DCT系数与JPEG直接利用DCT系数阶段 1: 数据准备步骤 1: 读取JPEG文件结构步骤 2: 提取量化表和Huffman表步骤 3: 解析图像数据步骤 4: 反量化步骤 5: 获取DCT系数 阶段 2: 输入处理预处理 1: 正规化&#xf…

解决Spring Boot Configuration Annotation Processor not configured的问题

1. 问题描述 使用ConfigurationProperties()注解时&#xff0c;IDE突然爆出警告Spring Boot Configuration Annotation Processor not configured&#xff0c;好在不影响项目运行&#xff0c;强迫症患者表示很不舒服。 2. 问题解决 1. 引入configuration-processor的依赖 <…

bert-vits2本地部署报错疑难问题汇总

环境&#xff1a; bert-vits2.3 win 和wsl 问题描述&#xff1a; bert-vits2本地部署报错疑难问题汇总 解决方案&#xff1a; 问题1: Conda安装requirements里面依赖出现ERROR: No matching distribution found for opencc1.1.6 解决方法 需要在 Python 3.11 上使用 Op…

巴尔加瓦算法图解:算法运用(上)

目录 树反向索引傅立叶变换 并行算法MapReduce函数 树 如果能将用户名插入到数组的正确位置就好了&#xff0c;这样就无需在插入后再排序。为此&#xff0c;有人设计了一种名为二叉查找树(binary search tree)的数据结构。 每个node的children 都不大于两个。对于其中的每个…

认识webSocket长连接

1&#xff0c;webSocket是什么 WebSocket 是HTML5开始提出的一种在单个 TCP 连接上进行全双工通讯的协议。用于在web端实现长连接的需求&#xff0c;如在线聊天室&#xff0c;弹幕&#xff0c;实时资讯更新等等 2&#xff0c;什么情形下需要使用websocket? 短链接是通过客户…

openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存

文章目录 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存217.1 查看内存状况217.2 性能参数分析 openGauss学习笔记-217 openGauss性能调优-确定性能调优范围-硬件瓶颈点分析-内存 获取openGauss节点的CPU、内存、I/O和网络资源使用情况&…

二分查找算法案例

折半查找&#xff08;二分查找&#xff09;是一种常见且高效的查找算法&#xff0c;适用于有序数组。其基本思想是首先将数组按照中间位置折半&#xff0c;然后判断待查找元素与中间元素的大小关系&#xff0c;从而确定待查找元素在左半部分还是右半部分。通过不断折半和判断&a…

使用 C++23 从零实现 RISC-V 模拟器(1):最简CPU

本节实现一个最简的 CPU &#xff0c;最终能够解析 add 和 addi 两个指令。如果对计算机组成原理已经有所了解可以跳过下面的内容直接看代码实现。 完整代码在这个分支&#xff1a;lab1-cpu-add&#xff0c;本章节尾有运行的具体指令。 1. 冯诺依曼结构 冯诺依曼结构是现代计…

怎么把视频音乐提取成mp3?分享详细工具和方法!

在数字媒体时代&#xff0c;音乐已经成为我们生活中不可或缺的一部分。有时候&#xff0c;我们会在社交媒体、视频分享网站或在线视频平台上看到一些非常喜欢的视频音乐&#xff0c;想要将其保存为MP3格式以便随时随地聆听。那么&#xff0c;如何从视频中提取音乐并转换为MP3格…

python+flask+django医院预约挂号系统6nrhh

医院预约挂号系统主要有管理员、用户和医生三个功能模块。以下将对这三个功能的作用进行详细的剖析。 技术栈 后端&#xff1a;python 前端&#xff1a;vue.jselementui 框架&#xff1a;django/flask Python版本&#xff1a;python3.7 数据库&#xff1a;mysql5.7 数据库工具…

【Spring框架】Spring事务同步

目录 一、什么是Spring事务同步 二、 事务同步管理器 2.1 TransactionSynchronizationManager事务同步管理器 2.1.1 资源同步 2.1.2 事务同步 2.1.3 总结 三、事务同步管理器保障事务的原理 四、spring事务为何使用TransactionSynchronizationManager spring源码实现 …

力扣_字符串5—解码方法

题目 一条包含字母 A-Z 的消息通过以下映射进行了 编码 &#xff1a; ‘A’ -> “1”‘B’ -> “2”…‘Z’ -> “26” 要 解码 已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&#xff08;可能有多种方法&#xff09;。例如&…

第二十七天| 39. 组合总和 、40.组合总和II、131.分割回文串

Leetcode 39. 组合总和 题目链接&#xff1a;39 组合总和 题干&#xff1a;给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序…

【网络】:序列化和反序列化

序列化和反序列化 一.json库 二.简单使用json库 前面已经讲过TCP和UDP&#xff0c;也写过代码能够进行双方的通信了&#xff0c;那么有没有可能这种通信是不安全的呢&#xff1f;如果直接通信&#xff0c;可能会被底层捕捉&#xff1b;可能由于网络问题&#xff0c;一方只接收到…

JavaScript中的for循环和map方法

JavaScript中的for循环和map方法 在JavaScript中&#xff0c;循环是一种常见的编程技巧&#xff0c;用于重复执行一段代码。for循环和map方法都可以用于循环操作&#xff0c;但它们在语法和应用场景上存在一些区别。本文将详细讲解JavaScript中的for循环和map方法&#xff0c;以…

【Linux技术宝典】Linux入门:揭开Linux的神秘面纱

文章目录 官网Linux 环境的搭建方式一、什么是Linux&#xff1f;二、Linux的起源与发展三、Linux的核心组件四、Linux企业应用现状五、Linux的发行版本六、为什么选择Linux&#xff1f;七、总结 Linux&#xff0c;一个在全球范围内广泛应用的开源操作系统&#xff0c;近年来越来…

c++中的模板(2)-- 函数模板(及模板函数)

目录 函数模板: 语法: 分析: 函数调用: 怎么实现: 模板函数: 函数模板: 其实就是在函数中使用模板&#xff0c;我们前面的swap函数就是一个函数模板。 语法: template <typename 类型名1,typename 类型名2 ...> template <typename T> void Sw…

【MySQL】-17 MySQL综合-3(MySQL创建数据库+MySQL查看数据库+MySQL修改数据库+MySQL删除数据库+MySQL选择数据库)

MySQL创建数据库查看数据库修改数据库删除数据库选择数据库 一 MySQL创建数据库实例1&#xff1a;最简单的创建 MySQL 数据库的语句实例2&#xff1a;创建 MySQL 数据库时指定字符集和校对规则 二 MySQL查看或显示数据库实例1&#xff1a;查看所有数据库实例2&#xff1a;创建并…

go常见问题

1、go : 无法将“go”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写&#xff0c;如果包括路径&#xff0c;请确保路径正确&#xff0c;然后再试一次。 所在位置 行:1 字符: 1 解决方式&#xff1a;$env:Path [System.Environment]::GetEnvironmentVa…