printf()函数大家已经很熟悉了,它的转换符在打印数据的时候也会经常使用,比如%c,%d,%f等。那么为什么打印的时候一定需要转换符呢?系统难道不能自动识别吗?转换符存在的意义又是什么?

  下面就通过一个简单的例子来看一下,转换符存在的意义,在8位单片机上通过不同的转换符打印两个整数。

通过不同的转换符打印两个整数,一个正整数,一个负整数。核心代码如下:

short num1 = 666;
short num2 = -32700;printf( "num1: short --- %6hd, unsigned short --- %6hu \r\n", num1, num1 );printf( "num2: short --- %6hd, unsigned short --- %6hu \r\n", num2, num2 );printf( "num1: int   --- %6d, char --- %6c \r\n", num1, num1 );printf( "num2: int   --- %6d, char --- %6c \r\n\r\n\r\n", num2, num2 );

在打印结果之前,先看一下short类型的数据范围是多少。

在8位单片机中short数据类型的范围是 -32768 到 32768,程序中的正整数为666,负整数为-32700,说明程序中的数据都在有效数据范围内。

下面看程序打印的结果

通过short和unsigned short打印num1时,输出的结果是正确的。但是通过unsigned short打印num2时输出的结果是32836,。通过字符型打印两个数字的时候,都出现了一个字符。那么这些打印错误的结果是从哪里来的?为什么又是这样的结果呢?

直接在内存中看看,这两个数字是如何存储的。

通过直接查看单片机的内存可以发现,数字666存储的位置是在0x00000C位置开始的,数字-32700 存储的位置是从 0x00000E位置开始的,short类型是16位,占两个字节。所以内存中 02 和 9a 就代表的是数字666,80和44就代表数字-32700.

下面通过进制转换看看这两个数字对应的16进制数字是什么?


数字666对应的16进制数字的原码、反码、补码,都是029A。


数字-32700 对应的16进制补码是8044,难道负整数在内存中存储的是它的补码吗?

确实是这样的,对于有符号的整数,系统是通过二进制的补码来表示。数字 0 — 32767 代表它们本身,而数字32768 — 65535 则表示负数,其中65535表示-1,65534表示-2。所以-32700对应保存的数字就是 65536-32767=32836。


通过进制转换可以看出,32836对应的16进制刚好是8044。

  当通过转换符“%hu”告诉printf函数要打印一个无符号的十进制整数时,系统检测到内存中存贮的这个32836刚好在无符号整数范围内,所以就直接打印出来了。 而当通过转换符“%hd”告诉printf函数要打印一个有符号的十进制整数时,系统检测到内存中存储的这个32836大于有符号整数的最大值32767,那么系统就知道了,这个数字肯定是个负数,它是以反码存储的,那么它的正确值就应该是-(65536-32836)=-32700。所以通过“%hd”转换符打印出来的就是-32700,而通过“%hu”打印出来的就是32836。

  那么后面的通过“%c”打印出来的这个字符又是怎么来的呢?
在系统中当使用“%c”的时候,系统就会认为这是一个字符设备,那么它的值范围就是一个ASCII码表,也就是0 - 255,如果这个值超过了255,系统就会用这个数字对256取余,也就是在内存中只取两个字节的后一个字节。

这样系统在通过“%c”打印数字666的时候,就只取内存中的9a,打印-32700的时候,就只取内存中的44。这两个数字对应的ASCII码表是多少呢?

9a对应的字符是 š,44对应的字符是 D,但是9a对应的这个字符在串口工具上打印不出来,所以打印的是?,44对应的是字母D,所以打印出来的就是字母D。

  通过上面的例子可以看出,printf()函数在内存中读取数据的时候,是通过转换符来判断要读取几位数据,该从内存中哪个位置去取数据,如果转换符设置的不正确,那么printf()函数去内存中读取数据的时候就会读错。

下面再通过一个简单的例子测试一下,测试代码如下:

int n1=0x0102;
int n2=0x0304;
int n3=0x0506;
int n4=0x0708;printf( "%ld,%ld,%ld,%ld \r\n\r\n\r\n", n1,n2,n3,n4 );

这个例子很简单,定义了四个整数,这四个整数各占两个字节,但是打印数据的时候,使用“%ld”,也就是一个字符占4个字节。输出结果如下:

打印的数字都非常大,那么这些数字是怎么来的?直接去内存中查看。

在内存中可以看出01到08依次在内存中按顺序存贮,如果使用“%ld”打印的时候,那么print()函数在读取n1的值时,就会直接在内存中取出4个位作为n1的值,也就是取出n1的值是 0x01020304,可以使用进制转换查看一下。

16909060转换成你的16进制果然是01020304

对应的n2取出来的值就是0x05060708

84281096转换成16进制果然是05060708

通过这个例子可以明显的看出,转换符对于printf()函数读取数据是非常重要的。转换符如果设置的不对,那么读取的数据肯定就会出现错误。

C语言小知识---printf()函数转换符的意义相关推荐

  1. C语言小知识---printf()函数

      说起printf()函数,写代码的同学肯定都很熟悉,这是C语言中标准的打印函数,在调试代码或者信息输出的时候会经常用到. 其中printf函数的转换说明如下: 转换说明修饰符 printf()中的 ...

  2. c语言--余数正负判断,printf函数占位符

    1.余数正负判断 负数求模的规则是,结果的正负号由第一个运算数的正负号决定的. 11%-5->>1 -11%-5->>-1 -11%5->>-1 第一个运算数的正负 ...

  3. 纸上得来终觉浅(c语言小知识总结)

    纸上得来终觉浅(c语言小知识总结) 1.数组的初始定义 对于一个初始定义的数组,内部的值是随机的,若用{}(哪怕其中没有元素)也会让数组内元素初始化,默认为0. 若是用循环语句进行赋值,在一个长度为2 ...

  4. 黑马程序员--C语言基础之--printf函数

    ------IOS培训期待与您交流! ------- 上一篇介绍了C语言中scanf函数的用法,接下来让我们来进一步地认识了解一下printf函数. 一.printf函数的用法: 首先让我们来看一下其 ...

  5. C语言程序设计中用printf函数输出数据

    文章目录 前言 一.创建C语言项目 二.printf函数介绍 总结 前言 记录暑假期间自学C语言的小问题和总结 一.创建C语言项目 这里使用的是Visual Studio 2019 首先新建一个C++ ...

  6. android将字符串中间几个字用*代替,【Android技巧之相见恨晚系列】-TextView/string.xml冷门小技巧:占位转换符%1$s、%1$d等的用法...

    技巧比较冷门,我今天用到才了解到,以前都没接触过...然而却发现这是很早就已经有的技巧... 引子: 如果一段文字需要多段TextView拼接而成,比如:"我叫XXX,今年XX岁了,身高X. ...

  7. eem二级c语言题库哪种比较好,c语言小知识,供初学者参考

    1 用预处理指令 define 声明一个常数 用以表明 1 年中有多少秒 忽略闰年问题 define SECONDS PER YEAR 60 60 24 365 UL 2 写一个 标准 宏 MIN 这 ...

  8. C语言小知识---奇葩的小数

      看到这个标题,好多人可能会想,小数有什么奇葩的,这不和整数一样,加减乘除计算起来也没啥区别呀?奇葩在哪里?   下面通过一个简单的例子来看一看,定义一个小数一个整数,然后打印出来. 核心代码其实只 ...

  9. 【C语言基础】printf函数

    一.printf函数 1.printf函数被设计用来显示格式串的内容,并且在该格式串中的指定位置插入可能的值. printf函数的一般形式为: printf(格式串,表达式1,表达式2,...): 格 ...

最新文章

  1. TensorFlow2.0正式版发布,极简安装TF2.0(CPUGPU)教程
  2. Linux之查看目录命令
  3. PHP编译安装时常见错误解决办法,php编译常见错误
  4. Linux入门之运维(1) 系统监控 vmstat top
  5. IT工程师必备的认证
  6. 云炬随笔20211016(2)
  7. AAAI 独家 | 腾讯AI Lab 现场陈述论文:使众包配对排名聚合信息最大化的 HodgeRank
  8. 20个最佳WordPress SEO插件
  9. 深入解析:MySQL对分布式事务 XA Transactions 的支持
  10. 适合节日促销的海报设计PSD分层模板|夜晚烟花,浓浓喜庆氛围
  11. Linux中出现 -bash: unzip: command not found
  12. Clipy 让苹果Mac复制粘贴发挥更强大的功能
  13. (详解)----冒泡排序---(图解)
  14. cad老是弹出命令中发生异常_打开CAD是时出现错误报告怎么解决?
  15. 浅析数据结构-图的基本概念
  16. 微信网页设置标题title
  17. 【UE4 C++】角色拾取、替换武器(下)
  18. 对python课程的建议_python听课的感悟与建议
  19. 模拟仿真最终利用计算机,基于计算机仿真模拟实验的应用分析
  20. 如何将IE10降到IE9

热门文章

  1. CentOS 7 安装及设置
  2. 透过WebGL 3D看动画Easing函数本质
  3. Unity3d之求物体体积
  4. perl常用正则表达式集合
  5. 诗歌,一路走来...
  6. Oracle中无法解析TNS的陷阱
  7. 201671030107 胡文艳 实验十四 团队项目评审课程项目总结
  8. #tomcat#内部结构和处理一个请求的过程(一)
  9. 【python】matplotlib生成散点矩阵图
  10. [单选题]对下面的表达式描述正确的是: (T/t)(M/m)