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

/*---C 语言学习区域的开始。-----------------------------------------------*/
void main() //主函数
{
unsigned char a=0x01;
unsigned char b=0x01;
unsigned char c=0x02;
unsigned char d=0x02;
a=(a<<2)+5; //a 左移 2 位后变成 4,再加 5 等于 9
b=b<<(2+5); //2 加 5 等于 7,b 再左移动 7 位等于 128
c=(1+3)*c; //1 加 3 等于 4,再乘以变量 c 等于 8
d=1+(3*d); //3 乘以 d 等于 6,再加 1 等于 7
View(a); //把第 1 个数 a 发送到电脑端的串口助手软件上观察。
View(b); //把第 2 个数 b 发送到电脑端的串口助手软件上观察。
View(c); //把第 3 个数 c 发送到电脑端的串口助手软件上观察。
View(d); //把第 4 个数 d 发送到电脑端的串口助手软件上观察。
while(1)
{
}
}
/*---C 语言学习区域的结束。-----------------------------------------------*/
在电脑串口助手软件上观察到的程序执行现象如下:
开始...
第 1 个数
十进制:9
十六进制:9
二进制:1001
第 2 个数
十进制:128
十六进制:80
二进制:10000000
第 3 个数
十进制:8

十六进制:8
二进制:1000
第 4 个数
十进制:7
十六进制:7
二进制:111
分析:
通过实验结果,发现在单片机上的实验结果和我们的分析是一致的。
【36.5 如何在单片机上练习本章节 C 语言程序?】
直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C 语言学习区域”的代码就可以了,
其它部分的代码不要动。编译后,把程序下载进带串口的 51 学习板,通过电脑端的串口助手软件就可以观
察到不同的变量数值,详细方法请看第十一节内容。

第三十七节:单字节变量赋值给多字节变量的疑惑。
【37.1 不同类型变量的赋值疑惑。】
之前讲过,多字节变量赋值给单字节变量时,多字节变量的低 8 位直接覆盖单字节变量,这个很容易理
解,比如:
unsigned long a=0x12345678; //多字节变量
unsigned char t=0xab; //单字节变量
t=a; //多字节赋值给单字节变量,t 的结果由原来的 0xab 变成了 0x78
那么,问题来了,如果调换过来,单字节赋值给多字节变量,多字节变量除了低 8 位被单字节变量所直
接覆盖之外,其它剩余的位会是什么状态?会被 0 覆盖吗?还是会保持原来的数值不变?这个就是本节将要
解开的疑惑。比如:
unsigned long a=0x12345678; //多字节变量
unsigned char t=0xab; //单字节变量
a=t; //单字节赋值给多字节变量,此时,a 到底是 0x123456ab?还是 0x000000ab?疑惑中......
想解开此疑惑,只要亲自上机测试一下就知道结果。经过在 keil 平台下的 C51 编译器测试后,发现结
果是这样子的:a 是 0x000000ab!也就是说,多字节变量其余高位是默认被 0 覆盖的。但是,我还有一个疑
惑,是不是所有的 C 编译器都是这样默认处理,会不会在不同的 C 编译器平台下,会有不同的结论?所以,
下面我再介绍两种比较可靠的办法给大家。
【37.2 我以前用的办法。】
我以前做项目的时候,每逢遇到这个疑惑,在不同变量赋值之前,我都多插入一行清零的代码,这行代
码就是先把多字节变量通过直接赋值 0 来清零,因为我确信常量赋值都是直接覆盖的(其余高位都直接用 0
填充)。比如:
unsigned long a=0x12345678; //多字节变量
unsigned char t=0xab; //单字节变量
a=0; //赋值之前先清零,这是我以前用的办法。
a=t; //单字节赋值给多字节变量
现在反省了一下,这种办法虽然可靠实用,但是显得过于保守。
【37.3 我现在用的办法:C 语言类型的强制转换。】
前面章节提到,括号在 C 语言中有强制的意思,可以强制改变优先级,也可以强制促进不同变量类型的
匹配。比如:
unsigned long a=0x12345678; //多字节变量
unsigned char t=0xab; //单字节变量
a=(unsigned long)t; //此处的括号就是强制把 t 先转变成 unsigned long 类型,然后再赋值。
这是我现在所使用的办法,推荐大家用这种。
【37.4 例程练习和分析。】
现在编写一个程序来验证刚才讲到的主要内容: