从单片机基础到程序框架(全集 2019pdf版).pdf - 第55页
赋值语句与 ROM 的关系。 赋值语句是行为的 一种, 所以编译会把赋值 这个行为翻 译成对应的指 令, 这些 指令 在下载 程序 时最终 也是 以数 据的形 式存 储在 RO M 里,指令 也是 以字 节为单 位 (字节 是一种 单位 ,后面 章 节会讲到)。 本教程的 编译环 境是以 AT89C52 芯片 为准, AT89C52 这个 单片机有 8 K 的 ROM 容量, 也就是有 8192 个字 节的 RO M(8 乘 以 102…

要求臣民避讳皇帝的名字有点像。哪些名字是合法的,哪些名字是不合法的?现在举一些例子说明:
unsigned char 3a; //不合法,第一个字符不能是数字。
unsigned char char; //不合法,char 是编译器已征用的关键字。
unsigned char a b; //不合法,ab 是一个变量名,a 与 b 的中间不能有空格。
unsigned char a,b; //合法,a 和 b 分别是一个独立的变量名,a 与 b 的中间可以用逗号隔开。
unsigned char a; //合法。
unsigned char abc; //合法。
unsigned char _ab; //合法。
unsigned char _3ab; //合法。
unsigned char a123; //合法。
unsigned char a12ced; //合法。
定义变量与 RAM 的内在关系。当我们定义一个变量时,相当于向单片机申请了一个 RAM 空间。C 编译器
会自动为这个变量名分配一个 RAM 空间,每个字节的 RAM 空间都有一个固定唯一的地址。把每个字节的 RAM
空间比喻成房间,这个地址就是房号。地址是纯数字编号,不利于我们记忆,C 语言编译器为了降低我们的
工作难度,不用我们记每个变量的地址,只需要记住这个变量的名称就可以了。操作某个变量名,就相当于
操作某个对应地址的 RAM 空间。变量名与对应地址 RAM 空间的映射关系是 C 编译器暗中悄悄帮我们分配好的。
比如:
unsigned char a; //a 占用一个字节的 RAM 空间,这个空间的地址由 C 编译自动分配。
unsigned char b; //b 占用一个字节的 RAM 空间,这个空间的地址由 C 编译自动分配。
unsigned char c; //c 占用一个字节的 RAM 空间,这个空间的地址由 C 编译自动分配。
上述 a,b,c 三个变量各自占用一个字节的 RAM 空间,同时被 C 编译器分配了 3 个不同的 RAM 空间地址。
变量定义的初始化。变量定义之后,等于被 C 编译器分配了一个 RAM 空间,那么这个空间里面存储的数
据是什么?如果没有刻意给它初始化,RAM 空间里面存储的数据是不太确定的,是默认的。有些场合,需要
在给变量分配 RAM 空间时就给它一个固定的初始值,这就是变量定义的初始化。变量初始化的语法格式由 3
部分组成:关键字,变量名赋值,分号。比如:
unsigned char a=9;
其中 unsigned char 就是关键字。
其中 a=9 就是变量名赋值。a 从被 C 编译器分配 RAM 空间那一刻起,就默认是预存了一个 9 的数据。
分号“;”就是一条语句的结束符号。
【12.4 变量的赋值。】
赋值语句的含义。把右边对象的内容复制一份给左边对象。赋值语句有一个很重要的特性,就是覆盖性,
左边对象原来的内容会被右边对象复制过来的新内容所覆盖。比如,左边对象是变量 a,假设原来 a 里面存
的数据是 3,右边对象是数据 6,执行赋值语句后,会把右边的 6 赋值给了对象 a,那么 a 原来的数据 3 就被
覆盖丢失了,变成了 6。
赋值语句的格式。赋值语句的语法格式由 4 部分组成:左边对象,关键字,右边对象,分号。比如:
a=b;
其中 a 就是左边对象。
其中“=”就是关键字。写法跟我们平时用的等于号是一样,但是在 C 语言里不是等于的意思,而是代
表赋值的意思,它是代表中文含义的“给”,而不是用于判断的“等于”,跟等于号是两码事(C 语言的等于
号是“==”,这个后面章节会讲到)。
其中 b 就是右边对象。
其中分号“;”代表一条语句的结束符。

赋值语句与 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,十六进制的内容后续章节会讲到)。