|
4.6 变量作用域 |
在程序中,我们往往需要使用多个变量。不同存储类型的变量及不同位置定义的变量具有不同的代码有效范围,也就是变量的作用域。除了一些特殊存储结构的变量外,变量的作用域基本和标准C语言类似。
在C51语言中,复合语句内部定义的变量仅作用于该复合语句内部。这一点是从标准C语言中继承而来的,读者最为熟悉。复合语句是任何以花括号“{”和“}”括起来的一段程序,也称为一个块结构。例如if语句、while语句、自定义的函数等。
【范例4-6】 示例代码4-6是一个变量作用域的示例程序。
示例代码4-6
【运行结果】使用Keil μVision3编译程序可以完成该程序的编译和仿真操作。该程序运行时输出如下结果:
ch=A,i=34
ch=a
【代码解析】在该程序中,在块结构外部和内部均定义了字符型变量ch,并分别赋值了字符a和A。由于作用域不同,因此在块结构内部的语句将输出字符A,而在块结构外部的语句将输出字符a。而整型变量i定义在块结构内部,因此在块结构外部的printf语句会提示出错,因为找不到i定义。
注意: 复合语句内定义的变量与外部定义的变量可以具有相同的变量名,它们之间不冲突,因为它们具有不同的作用域。
在单片机程序中,按照变量的存储类型,可以分为自动变量、全局变量、静态变量和寄存器变量4种类型。这4种变量具有不同的作用域范围。
1.自动变量
自动变量是以关键字auto标识的变量类型,一般是在函数的内部或者复合语句中使用。自动变量的定义格式为“auto 类型声明符 变量标识符,变量标识符……”。自动型变量的作用域范围是函数或者复合语句的内部。
注意: 在C51中,函数或复合语句内部定义自动变量时,关键字auto可以省略,即默认为自动型变量。
在程序执行过程中,自动变量是动态分配存储空间的。当程序执行到该变量声明语句时,根据变量类型自动为其分配存储空间。当该函数或复合语句执行完毕后,该变量的存储空间将立刻自动取消,即该自动变量失效。因此,在函数或者复合语句外部将不能使用该变量。
【范例4-7】 示例代码4-7是一个自动变量作用域的示例程序。
示例代码4-7
【运行结果】使用Keil μVision3编译程序可以完成该程序的编译和仿真操作。该程序运行时输出如下结果:
inside if block i=1
outside if block i=80
【代码解析】在该程序中,所有定义的变量均为自动变量。在主函数中定义了整型变量i,其作用域为整个main函数。当程序执行到if复合语句时外部定义的变量i将被屏蔽,自动创建内部变量i的存储空间,当if语句结束时将自动销毁创建的内部变量,外部变量i重新起作用。
2.全局变量
在C51语言中,全局变量的概念和标准C语言一致。如果一个变量定义在所有函数的外部,即整个程序文件的最前面,那么这个变量便是全局变量。全局变量有时也称为外部变量。
全局变量的作用域是整个程序文件,即全局变量可以被该程序文件中的任何函数使用。在编译程序时,全局变量将被静态地分配适当的存储空间。该变量一旦分配空间,在整个程序运行过程中便不会消失。因此,全局变量对整个程序文件都有效。
【范例4-8】 示例代码4-8是一个全局变量作用域的示例程序。
示例代码4-8
【运行结果】使用Keil μVision3编译程序可以完成该程序的编译和仿真操作。该程序运行时输出如下结果:
the area is 12.560000
the length is 12.560000
【代码解析】在该程序中,定义了两个全局变量PI和r,在自定义函数circle()、length()及main主函数内部均有效。在main主函数中初始化半径r,然后分别调用两个自定义函数计算圆的面积和周长。从这个例子可以看出,由于全局变量是永久性的,因此使用外部变量,可以在不同函数间传递和共享参数。
3.静态变量
对于前面介绍的两类变量,自动型变量离开其作用域后便自动销毁,只有全局变量可以在整个程序运行中占有存储空间。C51语言中还可以使用静态变量,来使其永久占用存储空间。静态变量以关键字static定义,其定义格式为“static类型声明符 变量标识符,变量标识符……”。静态变量的声明示例如下:
static char ch;
static float f;
static int count;
从变量作用域来看,静态变量和自动变量类似,作用域只是定义该变量的函数内部。如果静态变量定义在函数外部,将具有全局的作用域。而从内存占用的角度,静态变量和全局变量类似,其始终占有内存空间。
另外,在C51语言中允许将自定义函数定义为静态类型的。此时,只有同一程序文件中的其他函数才能调用这个静态型函数,同一工程项目中的其他文件不能访问。这样带来的好处是既有利于程序的模块化设计,又可以避免不同文件中函数重名的情况。
4.寄存器变量
前面介绍的变量一般都保存在单片机的RAM中,而单片机的CPU寄存器中也可以保存少量的变量,这种变量称为寄存器变量。寄存器变量以关键字register声明,声明格式为“register类型声明符 变量标识符,变量标识符……”。示例如下:
register char ch1;
register int pt;
由于单片机对CPU寄存器的读写十分快,因此寄存器变量的操作速度要远高于其他类型的变量。寄存器变量常用于某一变量名频繁使用的情况,这样做可以提高系统的运算速度。
注意: 由于单片机资源有限,程序中只允许同时定义两个寄存器变量。如果多于两个,在编译时会自动地将其他的寄存器变量当做非寄存器变量来处理。