从单片机基础到程序框架(全集 2019pdf版) - 第228页
直接复制前 面章节中第十 一节的模板程 序, 练习代码时只需要 更改 “ C 语言学习区 域” 的 代码就可 以了, 其它 部分的 代码 不要动 。编 译后 ,把程 序下 载进带 串口 的 51 学 习板, 通过 电脑 端的串 口助 手软件 就可 以观 察到不同的 变量数值,详 细方法请看第 十一节 内容。

语句 4;
【53.4 例程练习和分析。】
现在编写一个练习程序来体验一下函数的使用。
程序代码如下:
/*---C 语言学习区域的开始。-----------------------------------------------*/
void HanShu(void); //子函数声明的第一区域
unsigned char a; //全局变量定义的第二区域
void HanShu(void) //子函数定义的第三区域
{
a++; //子函数的代码语句
}
void main() //主函数
{
a=0;
a++;
HanShu() ; //子函数被调用的第四区域
a++;
View(a); //把第 1 个数 a 发送到电脑端的串口助手软件上观察。
while(1)
{
}
}
/*---C 语言学习区域的结束。-----------------------------------------------*/
在电脑串口助手软件上观察到的程序执行现象如下:
开始...
第 1 个数
十进制:3
十六进制:3
二进制:11
分析:
变量 a 为 3。单片机从 main 主函数进来,主函数里有 2 条“a++”,再加上子函数里也有 1 条“a++”,因
此累加了 3 次,从 0 变成了 3.
【53.5 如何在单片机上练习本章节 C 语言程序?】
直接复制前面章节中第十一节的模板程序,练习代码时只需要更改“C 语言学习区域”的代码就可以了,
其它部分的代码不要动。编译后,把程序下载进带串口的 51 学习板,通过电脑端的串口助手软件就可以观
察到不同的变量数值,详细方法请看第十一节内容。

第五十四节: 从全局变量和局部变量中感悟“栈”为何物。
【54.1 本节阅读前的名词约定。】
变量可以粗略的分成两类,一类是全局变量,一类是局部变量。如果更深一步精细划分,全局变量还可
以分成“普通全局变量”和“静态全局变量”,局部变量也可以分成“普通局部变量”和“静态局部变量”,
也就是说,若精细划分,可以分成四类。其中“静态全局变量”和“静态局部变量”多了一个前缀“静态”,
这个前缀“静态”是因为在普通的变量前面多加了一个修饰关键词“static”,这部分的内容后续章节会讲
到。本节重点为了让大家理解内存模型的“栈”,暂时不考虑“静态变量”的情况,人为约定,本节所涉及
的“全局变量”仅仅默认为“普通全局变量”,“局部变量”仅仅默认为“普通局部变量”。
【54.2 如何判定全局变量和局部变量?】
全局变量就是在函数外面定义的变量,局部变量就是在函数内部定义的变量,这是最直观的判定方法。
下面的例子能很清晰地说明全局变量和局部变量的判定方法:
unsigned char a; //在函数外面定义的,所以是全局变量。
void main() //主函数
{
unsigned char b; //在函数内部定义的,所以是局部变量。
b=a;
while(1)
{
}
}
【54.3 全局变量和局部变量的内存模型。】
单片机内存包括 ROM 和 RAM 两部分,ROM 存储的是单片机程序中的指令和一些不可更改的常量数据,而
RAM 存放的是可以被更改的变量数据,也就是说,全局变量和局部变量都是存放在 RAM,但是,虽然都是存
放在 RAM,全局变量和局部变量之间的内存模型还是有明显的区别的,因此,分了两个不同的 RAM 区,全局
变量占用的 RAM 区称为“全局数据区”,局部变量占用的 RAM 区称为“栈”,因为我后面会用宾馆来比喻“栈”,
为了方便记忆,大家可以把“栈”想象成 “客栈”来记忆。它们的内存模型到底有什么本质的区别呢?“全
局数据区”就像你自己家的房间,是唯一的,一个房间的地址只能你一个人住(假设你还没结婚的时候),
而且是永久的,所以说每个全局变量都有唯一对应的 RAM 地址,不可能重复的。而“栈”就像宾馆客栈,一
年下来每天晚上住的人不一样,每个人在里面居住的时间是有期限的,不是长久的,一个房间的地址一年下
来每天可能住进不同的人,不是唯一的。“全局数据区”的全局变量拥有永久产权,“栈”区的局部变量只能
临时居住在宾馆客栈,地址不是唯一的,有期限的。全局变量像私人区,局部变量像公共区。“栈”的这片
公共区,是给程序里所有函数内部的局部变量共用的,函数被调用的时候,该函数内部的每个局部变量就会
被分配对应到“栈”的某个 RAM 地址,函数调用结束后,该局部变量就失效,因此它对应的“栈”的 RAM 空
间就被收回以便给下一个被调用的函数的局部变量占用。请看下面这个例子,我借用“宾馆客栈”来比喻局
部变量所在的“栈”。
void HanShu(void); //子函数的声明