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://xiahunao.cn/news/2780187.html

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

相关文章

【MySQL】——数值函数的学习

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-Z1fAnfrxGD7I5gqp {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

bugku 1

Flask_FileUpload 文件上传 先随便传个一句话木马 看看回显 果然不符合规定 而且发现改成图片什么的都不行 查看页面源代码,发现提示 那应该就要用python命令才行 试试ls 类型要改成图片 cat /flag 好像需要密码 bp爆破 根据提示,我们先抓包 爆破 …

ChatGPT高效提问—prompt常见用法(续篇九)

ChatGPT高效提问—prompt常见用法(续篇九) ​ 如何准确地向大型语言模型提出问题,使其更好地理解我们的意图,从而得到期望的答案呢?编写有效的prompt的技巧,精心设计的prompt,获得期望的的答案。 1.1 增加条件 ​ 在各种prompt技巧中,增加条件是最常用的。在prompt中…

MOMENTUM: 1

攻击机 192.168.223.128 目标机 192.168.223.146 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -sV -p- -A 192.168.223.146 开启了22 80端口 看一下web界面 随便打开看看 发现这里有个参数id,sql尝试无果,发现写入什么,网页显示…

【数据结构】11 堆栈(顺序存储和链式存储)

定义 可认为是具有一定约束的线性表,插入和删除操作都在一个称为栈顶的端点位置。也叫后入先出表(LIFO) 类型名称:堆栈(STACK) 数据对象集: 一个有0个或者多个元素的有穷线性表。 操作集&#…

Obsidian Publish的开源替代品Perlite

前几天就有网友跟我说,freenom 的免费域名不可用了,10 号的时候老苏进后台看了一下,还有一半的域名显示为 ACTIVE,似乎是以 2024年6月 为限。但到 11 号,老苏发现博客 (https://laosu.cf) 已经访问不了了,这…

【Linux】信号保存与信号捕捉处理

信号保存与信号捕捉 一、信号保存1. 信号的发送2. 理解信号保存(1)信号保存原因(2)信号保存概念 3. 信号保存系统接口(1)sigset_t(2)sigprocmask()(3)sigpend…

GraphicsMagick 的 OpenCL 开发记录(三十七)

文章目录 如何写ScaleImage()的硬件加速函数&#xff08;十一&#xff09; <2022-05-06 周五> 如何写ScaleImage()的硬件加速函数&#xff08;十一&#xff09; “如何写ScaleImage()的硬件加速函数&#xff08;十&#xff09;”这里的代码写得比较随意&#xff0c;其中…

vscode远程连接失败

目录 解决方案尝试1解决方案尝试2 解决方案尝试1 最近通过vscode一直使用腾讯云的服务器作为远程开发环境&#xff0c;以前一直很好用。 直到最近重装了系统之后&#xff0c;发现vscode没法对云服务器进行连接了&#xff0c;即使在远程主机添加了本地的公钥也不行。直接报错:…

python-自动化篇-终极工具-用GUI自动控制键盘和鼠标-pyautogui

文章目录 用GUI自动控制键盘和鼠标pyautogui 模块鼠标屏幕位置——移动地图——pyautogui.size鼠标位置——自身定位——pyautogui.position()移动鼠标——pyautogui.moveTo拖动鼠标滚动鼠标 键盘按下键盘释放键盘 开始与结束通过注销关闭所有程序 用GUI自动控制键盘和鼠标 在…

springboot178智能学习平台系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

正则可视化工具:学习和编写正则表达式的利器

引言 正则表达式是一种强大的文本匹配和处理工具&#xff0c;但对于初学者和非专业开发者来说&#xff0c;编写和理解正则表达式可能是一项具有挑战性的任务。为了帮助人们更好地学习和编写正则表达式&#xff0c;正则可视化工具应运而生。本文将探讨正则可视化工具的优点&…

Infuse通过Alist添加115网盘资源

说明 通过Alist代理管理115网盘&#xff0c;Infuse再添加Alist代理的115网盘的WebDAV 准备一台Linux服务器安装Alist 我这里用的华为云CentOS7&#xff0c;使用Docker容器 安装Alist docker run -d --restartalways -v /etc/alist:/opt/alist/data -p 5244:5244 -e PUID0 …

Javaweb之SpringBootWeb案例之事务进阶的详细解析

1.3 事务进阶 前面我们通过spring事务管理注解Transactional已经控制了业务层方法的事务。接下来我们要来详细的介绍一下Transactional事务管理注解的使用细节。我们这里主要介绍Transactional注解当中的两个常见的属性&#xff1a; 异常回滚的属性&#xff1a;rollbackFor 事…

Days28 ElfBoard 板]修改开机动画

1.可能需要安装的库 elfubuntu:~/work/psplash$ sudo apt-get install build-essential libncurses5-dev elfubuntu:~/work/psplash$ sudo apt-get install libtool elfubuntu:~/work/psplash$ sudo apt-get install gettext elfubuntu:~/work/psplash$ sudo apt-get install l…

Tied Block Convolution: 具有共享较薄滤波器的更简洁、更出色的CNN

摘要 https://arxiv.org/pdf/2009.12021.pdf 卷积是卷积神经网络&#xff08;CNN&#xff09;的主要构建块。我们观察到&#xff0c;随着通道数的增加&#xff0c;优化后的CNN通常具有高度相关的滤波器&#xff0c;这降低了特征表示的表达力。我们提出了Tied Block Convolutio…

服务器解析漏洞及任意文件下载

1.服务器文件解析漏洞 文件解析漏洞,是指Web容器&#xff08;Apache、nginx、iis等&#xff09;在解析文件时出现了漏洞,以其他格式执行出脚本格式的效果。从而,黑客可以利用该漏洞实现非法文件的解析。 &#xff08;1) Apache linux系统中的apache的php配置文件在/etc/apac…

电气器件系列四十九:室内加热器(取暖器)

这个的注意事项有好大一堆&#xff0c;有几个地方挺有意思的&#xff0c;可以了解一下。 第2条&#xff0c;查了一下&#xff0c;小太阳是真的可以把旁边的东西烤到很高的温度并起火 4、可能造成开关的损坏和发热管的损坏&#xff0c;插入异物可能吧加热管搞坏 5、小太阳是发…

【数据结构】哈希表的开散列和闭散列模拟实现

哈希思想 在顺序和树状结构中&#xff0c;元素的存储与其存储位置之间是没有对应关系&#xff0c;因此在查找一个元素时&#xff0c;必须要经过多次的比较。 顺序查找的时间复杂度为0(N)&#xff0c;树的查找时间复杂度为log(N)。 我们最希望的搜索方式&#xff1a;通过元素…

python coding with ChatGPT 打卡第20天| 二叉搜索树:搜索、验证、最小绝对差、众数

相关推荐 python coding with ChatGPT 打卡第12天| 二叉树&#xff1a;理论基础 python coding with ChatGPT 打卡第13天| 二叉树的深度优先遍历 python coding with ChatGPT 打卡第14天| 二叉树的广度优先遍历 python coding with ChatGPT 打卡第15天| 二叉树&#xff1a;翻转…