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

临时的“栈” 区的,寄生 在 main 函数内部。 再看下面第 二个例子: /*---C 语言 学习区域的开 始。----- ----------- ---------- ----------- ---------- */ void H anShu(void); //函数声明 unsigned c har a=5; //此处 第 1 个 a 是全局变量 。 void H anShu(void) //函数 定义 { unsigned c …

100%1 / 836
第三个疑问
问:函数内部所定义的局部变量总数不超过单片机的“栈”区的 RAM 数量,那,万一超过了“栈”
RAM 数量,后果严重吗?
答:后果特别严重。这种情况,专业术语叫“爆栈”程序会出现异常,而且是莫名其妙的异常。为了
避免这种情况,一般在编写程序的时候,函数内部都不能定义大数组的局部变量,局部变量的数量不能定
太多太大,尤其要避免刚才所说的定义开辟大数组局部变量这种情况。大数组的定义应该定义成全局变量,
或者定义成“静态的局部变量静态”这部分相关的内容后面章节会讲到有一些 C 编译器,遇到“
栈”的情况,会好心跟你提醒让你编译不过去,但是也有一 C 编译器可能就不会给你提醒,所以大家以后
做项目写函数的时候,要对“爆栈”心存敬畏。
【54.5 全局变量和局部变量的优先级。
刚才说到全局变量的作用域是永久性并且不受范围限制的,而局部变量的作用域就是它所在函数的
部范围,那么问题来,假如局部变量和全局变量的名字重名了,此时函数内部执行的变量到底是局部变量还
是全局变量?这个问题就涉及到优先级。注意当面对同名的局部变量和全局变量时,函数内部执行的变
是局部变量,也就是局部变量在函数内部要比全局变量的优先级高。为了深刻理解“全局变量和局部变量的
优先级”,强烈建议大家必须仔细看完下面列举的三个练习例子。
【54.6 例程练习和分析。
请看下面第一个例子:
/*---C 语言学习区域的开始。-----------------------------------------------*/
unsigned char a=5; //此处 1 a 是全局变量
void main() //主函
{
unsigned char a=2; //此处第 2 a 是局部变量。跟上面全局变量的 1 a 重名了!
View(a); //把 a 发送到电脑端的串口助手软件上观察。
while(1)
{
}
}
/*---C 语言学习区域的结束。-----------------------------------------------*/
分析:
上述例子, 2 个变量重名了!其中一个是全局变量,另外一个是局部变量。此时输出显示的结果是 5
还是 2?正确的答案是 2。因为在函数内部,函数内部的局部变量比全局变量的优先级更加高。此时 View(a)
是第 2 局部变量的 a,而不是第 1 个全局变量 a。虽然这里的两 a 名了,但是它们的内存模型不
样, 1 个全局变量的 a 是分配在“全局数据区是具有唯一的地址的,而第 2 个局部变量的 a 是被分配在
临时的“栈”区的,寄生 main 函数内部。
再看下面第二个例子:
/*---C 语言学习区域的开始。-----------------------------------------------*/
void HanShu(void); //函数声明
unsigned char a=5; //此处 1 a 是全局变量
void HanShu(void) //函数定义
{
unsigned char a=3; //此处第 2 a 是局部变量。
}
void main() //主函
{
unsigned char a=2; //此处第 3 a 也是局部变量。
HanShu(); //子函数被调
View(a); //把 a 发送到电脑端的串口助手软件上观察。
while(1)
{
}
}
/*---C 语言学习区域的结束。-----------------------------------------------*/
分析:
上述例子, 3 个变量重名了!其中一个是全局变量,另外两个是局部变量。此时输出显示的结果是 5
还是 3 2?正确的答案 2。因为,HanShu 个子函数是被调用结束之后,才执行 View(a)的,就意味
HanShu ( 2 a)执行 View(a)候就在了
View(a)的 a 是第 3 个局部变量的 a(在 main 函数内部定义的局部变量 a)
再看下面第三个例子:
/*---C 语言学习区域的开始。-----------------------------------------------*/
void HanShu(void); //函数声明
unsigned char a=5; //此处 1 a 是全局变量
void HanShu(void) //函数定义
{
unsigned char a=3; //此处第 2 a 是局部变量。
}
void main() //主函
{
HanShu(); //子函数被调
View(a); //把 a 发送到电脑端的串口助手软件上观察。
while(1)
{
}
}
/*---C 语言学习区域的结束。-----------------------------------------------*/
分析:
上述例子, 2 个变量重名了!其中一个是全局变量,另外一个是局部变量。此时输出显示的结果是 5
还是 3?正确的答案是 5。因为,HanShu 这个子函数是被调用结束之后,才执行 View(a)的,就意味 HanShu
函数内部的局部变量(第 2 个局部变量)是在执行 View(a)语句的时候就消亡不存在了,同时,因为此时 main
函数内部也没有定义 a 的局部变量,所以此时 View(a)的 a 是必然只能是第 1 个全局变量的 a main 函数
外面定义的全局变量的 a)
【54.7 如何在单片机上练习本章节 C 语言程序?】
直接复制前面章节中第十一节的模板程序,练习代码时只需要更改C 语言学习区域”代码就可以了,
其它部分的代码不要动。编译后,把程序下载进带串口 51 习板,通过电脑端的串口助手软件就可以观
察到不同的变量数值,详细方法请看第十一节内容。