从单片机基础到程序框架(全集 2019pdf版).pdf - 第99页

第 7 个数 十进制:4 十六进制:4 二进制:100 第 8 个数 十进制:4 十六进制:4 二进制:100 分析: 通过实验结 果,发现 在单片机上的 计算结果和 我们的分 析是一致的。 【22.4 如何在单片机上练习本章节 C 语言程序?】 直接复制前 面章节中第十 一节的模板程 序, 练习代码时只需 要更改 “ C 语言学习区 域” 的 代码就可 以了, 其它 部分的 代码 不要动 。编 译后, 把程 序下 载进带 串口的 51…

100%1 / 836
View(g); //把第 7 个数 g 发送到电脑端的串口助手软件上观察。
View(h); //把第 8 个数 h 发送到电脑端的串口助手软件上观察。
while(1)
{
}
}
/*---C 语言学习区域的结束。-----------------------------------------------*/
在电脑串口助手软件上观察到的程序执行现象如下:
开始...
1 个数
十进制:50
十六进制:32
二进制:110010
2 个数
十进制:39
十六进制:27
二进制:100111
3 个数
十进制:53
十六进制:35
二进制:110101
4 个数
十进制:59
十六进制:3B
二进制:111011
5 个数
十进制:35
十六进制:23
二进制:100011
6 个数
十进制:19
十六进制:13
二进制:10011
7 个数
十进制:4
十六进制:4
二进制:100
8 个数
十进制:4
十六进制:4
二进制:100
分析:
通过实验结果,发现在单片机上的计算结果和我们的分析是一致的。
【22.4 如何在单片机上练习本章节 C 语言程序?】
直接复制前面章节中第十一节的模板程序,练习代码时只需要更改C 语言学习区域”代码就可以了,
其它部分的代码不要动。编译后,把程序下载进带串口的 51 学习板,通过电脑端的串口助手软件就可以
察到不同的变量数值,详细方法请看第十一节内容。
第二十三节:减法溢出与假想借位。
【23.1 减法溢出与假想借位
英文“unsigned”的中文意思就是”无符号的”,延伸含义是“无负号无负数”的意思,所以 unsigned
char ,unsigned int ,unsigned long 这三种类型数据都是无负号无负数的,取值只能是 0 和正数,那么问
题来了,当被减数小于减数的时候,运算结果会是什么样子,有什么规律?这就是本节要研究的减法溢出。
第一个例子:
unsigned char a;
a=0-1;
分析:
左边“保量”a 的数长度 1 字节 8 a=0-1 成是进制 a=0x00-0x01
0x00 0x01 小,所以假想一下需要向高位借位,借位后成了 a=0x100-0x01。所 a 的最终结果是 0xff(十
进制是 255),这个“假想一下需要向高位借”的过程就是本节制造的新概念“假想借位”。根据“假想
位”个规 b unsigned char 型, b=2-5 当于 b=0x102-0x05, b
等于 0xfd(十进制是 253)。
第二个例子:
unsigned int c;
c=0-1;
分析:
左边的“保存变量”c 的数据长度是 2 个字节 16 位,c=0-1 可以看成是十六进制的 c=0x0000-0x0001。
由于 0x0000 0x0001 小,所以假想一下需要向高位借位,借位后成了 c=0x10000-0x0001。所以 c 的最终结
果是 0xffff(十进制是 65535)。根据“假想借位这个规律,如果 d 也是 unsigned int 类型那么 d=2-5
自然就相当 d=0x10002-0x0005,运算结果 d 等于 0xfffd(十进制是 65533)。
综合分析:
为什么上述例子中会出现数据越减越大的奇葩现象?是因为减法溢出,是因为“假想借位”中的“借”
是“光借不还。一句话,根本问题就是溢出问题。
【23.2 因为减法溢出,所以加减顺序......】
第三个例子:请分析下面例子中 e f 因加减运算顺序不同而引发什么问题。
unsigned char e;
unsigned char f;
e=1-6+7;
f=1+7-6;
用两种思路分析:
第一种思路:只看过程不看结果。加减法的运算优先级是从左到右,e 先减法后加法,1 6 就有溢
出了,所以过程有问题。 f 先加法后减法,整个过程没有问题。
第二种思路先看结果再分析过程。e 的运算结果居然 2,f 的运算结果也是 2。好奇怪,既然 e
程有问题,为什么运算结果却没有问题?其实 e 发生两次溢出,第一次是减法溢出,第二次是加法溢出,所
“溢溢得正”(这句话是开玩笑的)。1-6“假想借位”后相当于 0x101-0x06,运算结果等于 0xfb(十进
251)然后 0xfb 再加 0x07 等于 0x102,因为 e unsigned char 类型只有 1 个字节,据加法溢出的
规律,最后只保留了低 8 位的一个字节 0x02,所以运算结果就是十进制的 2。