转换说明

printf是我们最常用的的一个c语言的库函数之一,printf打印数据的指令要与待打印数据的类型相匹配,例如打印整数时要用%d,打印字符要用%c。这些符号被称为转换说明
常见的转换说明:

%a 浮点数、十六进制数和p计数法
%c 单个字符
%d 有符号十进制整数
%e 浮点数,e计数法
%f 浮点数、十进制计数法
%p 指针
%s 字符串
%o 无符号八进制数
%u 无符号十进制数
%x 无符号十六进制数,使用十六进制数0f

转换说明修饰符

标记

例如:-、+、空格、#和0

数字

如果该字段不能容纳待打印的数字或字符串,系统回使用更宽的字段

.数字

精度

  • 对于%e、%E和%f转换,表示小数点右边数字的位数
  • 对于%s转换,表示待打印字符的最大数量
  • 对于整型转换,表示待打印数字的最小位数

h

和整型转换说明一起使用,表示short int和unsigned short int类型的值

hh

和整型转换说明一起使用,表示signed char和unsigned char类型的值

l

和整型转换说明一起使用,表示long int和unsigned long int类型的值

L

和浮点转换说明一起使用,表示long double 类型的值

代码示例:

#include<stdio.h>
int main()
{int a = 5;printf("%5d\n", a);printf("%.5d\n", a);printf("%05d\n", a);printf("%-5d\n", a);printf("%-05d\n", a);return 0;
}

运行结果:

转换说明的意义

转换说明把以二进制格式储存再计算机中的值转换成一系列字符(字符串)以便显示

转换很容易被人错误的理解为原始值换成转换后的值。实际上,转换说明时翻译说明,%的意思是“把给定的值翻译成十进制整数文本打印出来”,也就是把机器的语言翻译成目标值并打印出来,所以即使在某些情况下,转换不匹配,打印出来的值和转换符的类型相同,实际上转换符决定了打印出来的值。

转换不匹配

整型与整型

正常的认知都认为,转换说明应该与待打印值得类型相匹配。例如打印 int类型用%d %x %o,打印char 类型用%c、转换说明与待打印类型不匹配会怎么样?


#include<stdio.h>
int main()
#define pages 336
#define words 65618 //这里用define是因为define定义的变量类型是未知的,所以下面使用就不用声明相应类型的变量了
{short num = pages;        //0000 0001 0101 0000short mnum = -pages;      //1111 1110 1011 0000printf("num as short and unsigned short:%hd %hu\n",num,num);  //0000 0001 0101 0000printf("mnum as short and unsigned short:%hd %hu\n",mnum,mnum);  //1111 1110 1011 0000  printf("num as int and char %d %c\n", num, num);  //1111 1111 1111 1111 1111 1110 1011 0000 和 0101 0000=80 查ASCII码对照表可知结果printf("words as int ,short ,char:%d,%hd,%c", words, words, words);return 0;}
//如果要用%d打印就要发生整型提升,二进制位会提升为32位,规则为有符号补符号位,无符号补零
//1111 1111 1111 1111 1111 1110 1011 0000
//1000 0000 0000 0000 0000 0001 0101 0000//words
//%d 0000 0000 0000 0001 0000 0000 0101 0010 //转型提升
//%hd  0000 0000 0101 0010       // 截断
}

运行结果

如果对这块内存二进制码不太了解的可以参考这个——0.0
实际上整型与整型在打印时也就用到了两点:

  1. 整型提升——涉及两种类型的运算,两个值会分别转换成两种类型的更高级别
  2. 截断

整型与浮点型

#include<stdio.h>
int main()
{float n1 = 3.0;double n2=3.0;long n3 = 2000000000;long n4 = 1234567890;printf("%.le %.le %.le %.le\n", n1, n2, n3, n4);printf("%ld %ld \n", n3, n4);printf("%ld %ld %ld %ld\n",n1,n2,n3,n4);return 0;
}

代码结果:

打印第一行:n1和n2被正确的打印出来了,但是n3和n4就打印错误了,这是因为转换符%e告诉printf函数要以浮点型类型打印,但实际上传过去的时一个整型,浮点型有八个字节,而整型只有四个字节,所以整型后面的四个字节也会被读取,组成八个字节并强行把他解释为浮点型。
还有一点要注意给printf出传递参数时,c编译器会把float自动转换成double类型,所以n1会被强制扩展成八个字节
打印第二行:类型与传的值相匹配打印正确!

打印第三行:
如果我们想知道为什么会出现这种结果,就必须额了解函数的传参

printf("%ld %ld %ld %ld\n",n1,n2,n3,n4);

函数printf()在栈上开辟空间,并把n4,n3,n2,n1传入进去。n1和n2时double类型为八个字节,n3和n4是整型为四个字节,放入栈时开辟内存的大小与转换符类型无关,只与变量类型有关。然后转到printf函数,printf函数根据转换符读取数据,%ld说明printf()应该每次读取四个字节,并将其解释为long int类型。
当读取n1时由于一次只能读取四个字节,所以n1被拆开成两段,前四个字节被读取,并且别强行解释为long int类型,接下来%ld读取剩下的四个字节,也就是n1的后四个字节。

所以到最后即使n3,n4的类型与打印的类型相符合,结果也是一堆乱码。

printf函数的类型转换问题相关推荐

  1. 关于C语言中printf函数“输出歧视”的问题

    目录 关于C语言中printf函数"输出歧视"的问题 问题描述 探索问题原因 另一种研究方法 问题结论 关于C语言中printf函数"输出歧视"的问题 问题描述 ...

  2. C中printf函数的实现原理

    一.printf函数的实现原理 在C/C++中,对函数参数的扫描是从后向前的.C/C++的函数参数是通过压入堆栈的方式来给函数传参数的(堆栈是一种先进后出的数据结构),最先压入的参数最后出来,在计算机 ...

  3. 带你学C带你飞 | printf函数 | 变量 | 常量和宏定义 | 数据类型 | 取值范围 | 字符串 | 运算符

    文章目录 一.printf函数 1.printf函数 2.printf函数课后作业 二.变量 1.变量 2.变量课后作业 三.常量和宏定义 1.常量和宏定义 2.常量和宏定义的课后作业 四.数据类型 ...

  4. C语言printf()函数的使用

    printf()函数是C语言标准I/O中最常用的控制台输出函数,除了我们最常见的%d,%c,%s和%f以外 printf()和%说明符还提供很多功能丰富的输出形式,以下是一个demo程序,可以复制到你 ...

  5. C方式格式化输出(printf 函数详解)

    本篇将重点介绍C语言的格式化输出函数 printf.当然该函数在C++程序中也可以使用. 目录 printf 函数构成及标准函数语句 格式字符种类的介绍 printf 函数的具体细节实现 格式符数量与 ...

  6. c语言自定义char*函数返回值是乱码_[每日C语言」printf()函数的修饰符和返回值...

    在上一个小demo<printf()函数(1)>中主要说了一下printf()函数的转换说明符,这些转移说明符是可以被修饰的.我们可以在%d和定义的转义字符之间通过插入修饰符对基本的转换说 ...

  7. c程序设计语言中printf,编程序 用getchar函数读入两个字符c1和c2,然后分别用putchar和printf函数输出这两个字符。请问...

    编程序,用getchar函数读入两个字符给c1和c2,然后分别用putchar和printf函数输出这两个字符.请问: 1. 变量C1,C2应定义为字符型或整型?或二者皆可? 答:在这个题目里,变量C ...

  8. php 格式化评论量函数,深入剖析PHP中printf()函数格式化使用

    printf()函数优点在于可以格式化输出! printf的格式控制的完整格式: % - 0 m.n l或h 格式字符 下面对组成格式说明的各项加以说明: ①%:表示格式说明的起始符号,不可缺少. ② ...

  9. STM32中关于串口通信的printf()函数重定向问题

    在STM32串口通信程序中使用printf()函数发送数据非常方便,但是需要先进行简单的配置,下面介绍两种配置方法. 方法一.对工程属性进行配置 第1步:在main.c中包含"stdio.h ...

最新文章

  1. cordova 安装ssl证书_cordova环境配置(android)
  2. 对代码生成器的一点想法
  3. 【转】刨根究底字符编码之九——字符编码方案的演变与字节序
  4. CSS3径向渐变radial-gradient实现波浪边框和内倒角
  5. java中关于时间的格式化
  6. html页面图片延迟加载,实现图片懒加载的几种方法
  7. 小红伞的WAF一个绕过方法
  8. 化工人员定位安全管理系统解决方案
  9. codewars练习(javascript)-2021/1/19
  10. 去掉Excel 单元格里的字符后面的空格
  11. docker logs命令查看日志
  12. Snipaste不容易被注意到的小技巧
  13. 企业管理者谦虚_为什么谦虚是优秀开发者最重要的特征
  14. PKPM学习:板生成的问题
  15. 安卓禁用硬件加速_开/关大不同 Android4.0 GPU硬件加速实测
  16. 行人重识别(ReID) ——数据集描述 DukeMTMC-reID
  17. 9.5 考试 第三题 奇袭题解(codeforce 526f)
  18. i春秋“网络内生安全试验场”CTF答题夺旗赛(第四季)部分题目WP
  19. 1.JDBC的使用-添加数据
  20. GB/T 18655-2018 用于保护车载接收机的限值和测量方法 学习思维导图

热门文章

  1. 中性SNP的突变年龄评估(estimate the average age of a neutral two-allele polymorphism)
  2. 重型卡车主减速器及差速器的设计
  3. 微信接口开发,errcode 45047
  4. 智能OCR文字识别训练平台
  5. python for item in items_Python中items()系列函数的用法详解
  6. 图像处理中Normalization的应用
  7. MagicalRecord
  8. “数聚上海 共赢未来” 上海大数据产业高端峰会 Cloudera让大数据实现更多价值...
  9. Solidity语言学习笔记————20、函数修饰符
  10. Jqprint实现页面打印