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

} /*---C 语言 学习区域的结 束。----- ----------- ---------- ----------- ---------- */ 在电脑串口 助手软件上观察 到的程序执行 现象 如下: 开始... 第 1 个数 十进制:255 十六进制:F F 二进制:111 11111 第 2 个数 十进制:3 十六进制:3 二进制:11 第 3 个数 十进制:3 十六进制:3 二进制:11 第 4 个数 十进制:9 十六进制:…

100%1 / 836
赋值语句与 ROM 的关系。赋值语句是行为的一种,所以编译会把赋值这个行为翻译成对应的指令,这些
指令在下载程序时最终也是以数据的形式存储在 ROM 里,指令也是以字节为单(字节是一种单位,后面
节会讲到)。本教程的编译环境是以 AT89C52 芯片为准,AT89C52 这个单片机有 8K ROM 容量,也就是有 8192
个字节的 ROM(8 1024 8192但是并不意味着程序就一定要全部占用这 ROM。程序需要占用
ROM,完全是根据程序的行为程度决定,也就是通常所说的你的程序容量有多大,有多少行代码。多说一
句,在单片机或者我们常说的计算机领域里,存储容量是以字节为单位,而每 K 之间的进制不是我们日常所
用的 1000,而 1024,所以刚才所说 8K 不是 8000,而 8192,这个是初学者很容易迷惑的地方。刚才
提到,赋值语句是行为,凡是程序的行为指令都存储在单片机的 ROM 区。C 编译器会把一条赋值语句翻译
对应的一条或者几条机器码,机器码指令也是以字节为单位的。下载程序的时候这些机器码就会被下载
单片机的 ROM 区。比如以下这行赋值语句:
unsigned char a;
unsigned char b=3;
a=b;
经过 C 编译器编译后会生成以字节为单位的机器码。这些机器码记录着这些信息:变量 a RAM 地址,
变量 b RAM 地址和初始化时的预存数据 3,以及 b 变量的内容赋值给 a 变量的这个行为。所有这些信息,
不管是“数据”还是“行为,本质都是以“数据”(或称数字,数码都可以)的形式存储记录的,单位是字
节。
【12.5 例程的分析和练习。
接下来练习一个程序实例。直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C 语言
学习区域”的代码就可以了,其它部分的代码不要动。编译后,把程序下载进带串口的 51 学习板,通过
脑端的串口助手软件就可以观察到不同的变量数值,详细方法请看第十一节内容。本章节在“C 语言学习区
域”练习的代码如下:
/*---C 语言学习区域的开始。-----------------------------------------------*/
void main() //主函
{
unsigned char a; //定义的变量 a 被分配了一个字节 RAM 空间,保存的数据是不确定的默认值。
unsigned char b; //定义的变量 b 被分配了一个字节 RAM 空间,保存的数据是不确定的默认值。
unsigned char c; //定义的变量 c 被分配了一个字节 RAM 空间,保存的数据是不确定的默认值。
unsigned char d=9; //定义的变量 d 被分配了一个字节 RAM 空间,保存的数据被初始化成 9.
b=3; //把 3 赋值给变量 b,b 由原来不确定的默认数据变成了 3。
c=b; //把变 b 的内容复制一份赋值给左边的变量 c,c 从不确定的默认值变成了 3。
View(a); //把第 1 个数 a 发送到电脑端的串口助手软件上观察。
View(b); //把第 2 个数 b 发送到电脑端的串口助手软件上观察。
View(c); //把第 3 个数 c 发送到电脑端的串口助手软件上观察。
View(d); //把第 4 个数 d 发送到电脑端的串口助手软件上观察。
while(1)
{
}
}
/*---C 语言学习区域的结束。-----------------------------------------------*/
在电脑串口助手软件上观察到的程序执行现象如下:
开始...
1 个数
十进制:255
十六进制:FF
二进制:11111111
2 个数
十进制:3
十六进制:3
二进制:11
3 个数
十进制:3
十六进制:3
二进制:11
4 个数
十进制:9
十六进制:9
二进制:1001
分析:
1 个数 a 居然 255,这个 255 从哪来?因 a 我们一直没有给它初始值,也没有给它赋值,所以它
是不确定的默认值,这个 255 就是所谓的不确定的默认值,是编译器在定义变 a 时分配的,带有不确定的
随机性,不同的编译器可能分配的默认值都会存在差异。根据我的经验,unsigned char 类型定义的默认
往往是 0 或者 255(255 是十六进制 0xff,十六进制的内容后续章节会讲到)
第十三节:赋值语句的覆盖性。
【13.1 什么是赋值语句的覆盖性?】
a=b;
上述代码,执行完这条赋值语句后,会把右边变 b 数值复制一份给左边变 a,a 获得了跟 b 一样
的数值,但是 a 原来自己的数值却丢失了,为什么会丢失?就是因为被 b 复制过来的新数据给覆盖了,这就
是赋值语句的覆盖性。
【13.2 例程的分析和练习。
既然赋值语句有覆盖性的特点,那么如何让两个变量相互交换数值?假设 a 来的数据是 1,b 原来的
数据是 5,交换数据后,a 的数据应该变为 5b 的数据应该变为 1怎么做?很多初学者刚看到这么简单的
目,会马上根据日常生活的思路,你把你的东西给我,我把我的东西给你,就两个步骤而已,看似很简单,
现在按这个思路编写一段程序看看会出什么问题,代码如下:
/*---C 语言学习区域的开始。-----------------------------------------------*/
void main() //主函
{
unsigned char a=1; //定义的变量 a 被分配 1 个字节的 RAM 空间,保存的数据被初始化成 1。
unsigned char b=5; //定义的变量 b 被分配 1 个字节的 RAM 空间,保存的数据被初始化成 5。
b=a; //第一步:为了交换,先把 a 的数赋值给 b。
a=b; //第二步:为了交换,再把 b 的数赋值给 a。
View(a); //把第 1 个数 a 发送到电脑端的串口助手软件上观察。
View(b); //把第 2 个数 b 发送到电脑端的串口助手软件上观察。
while(1)
{
}
}
/*---C 语言学习区域的结束。-----------------------------------------------*/
在电脑串口助手软件上观察到的程序执行现象如下:
开始...
1 个数
十进制:1