购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.2.3 变量及其存储模式

变量是一种在程序执行过程中其值能不断变化的量。在使用一个变量之前,必须进行定义,用一个标识符作为变量名并指出它的数据类型和存储模式,以便编译系统为它分配相应的存储单元。在C51中对变量进行定义的格式如下:

[存储种类] 数据类型 [存储器类型] 变量名表;

其中,“存储种类”和“存储器类型”是可选项。变量的存储种类有四种:自动(auto)、外部(extern)、静态(static)和寄存器(register)。定义一个变量时如果省略存储种类选项,则该变量将为自动(auto)变量。定义一个变量时除了需要说明其数据类型之外,Keil C51编译器还允许说明变量的存储器类型。Keil C51编译器完全支持8051系列单片机的硬件结构和存储器组织,对于每个变量可以准确地赋予其存储器类型,使之能够在单片机系统内准确地定位。表2-5列出了Keil C51编译器所能识别的存储器类型。

表2-5 Keil C51编译器所能识别的存储器类型

定义变量时如果省略“存储器类型”选项,则按编译时使用的存储器模式SMALL、COMPACT或LARGE来规定默认存储器类型,确定变量的存储器空间,函数中不能采用寄存器传递的参数变量和过程变量也保存在默认的存储器空间。Keil C51编译器的三种存储器模式(默认的存储器类型)对变量的影响如下。

1.SMALL

变量被定义在8051单片机的片内数据存储器中,对这种变量的访问速度最快。另外,所有的对象,包括堆栈,都必须位于片内数据存储器中,而堆栈的长度是很重要的,实际上栈长取决于不同函数的嵌套深度。

2.COMPACT

变量被定义在分页寻址的片外数据存储器中,每一页片外数据存储器的长度为256字节。这时对变量的访问是通过寄存器间接寻址(MOVX@Ri)进行的,堆栈位于8051单片机片内的数据存储器中。采用这种编译模式时,变量的高8位地址由P2口确定,低8位地址由R0或R1的内容决定。采用这种模式的同时,必须适当改变启动配置文件STARTUP.A51中的参数:PDATASTART和PDATALEN;在用BL51进行链接时还必须采用链接控制命令“PDATA”对P2口地址进行定位,这样才能确保P2口为所需要的高8位地址。

3.LARGE

变量被定义在片外数据存储器中(最大可达64KB),使用数据指针DPTR来间接访问变量(MOVX@DPTR)。这种访问数据的方法效率是不高的,尤其是对于2个以上字节的变量,用这种方法相当影响程序的代码长度。

需要特别指出的是,变量的存储种类与存储器类型是完全无关的。例如:

8051系列单片机具有多种内部寄存器,其中一些是特殊功能寄存器,如定时器方式控制寄存器TMOD、中断允许控制寄存器IE等。为了能够直接访问这些特殊功能寄存器,Keil C51编译器扩充了关键字sfr和sfr16,利用这种扩充关键字可以在C语言源程序中直接对8051单片机的特殊功能寄存器进行定义。定义方法如下:

sfr特殊功能寄存器名=地址常数;

例如:

这里需要注意的是,在关键字sfr后面必须跟一个标识符作为寄存器名,名字可任意选取,但应符合一般习惯。等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(0x80~0xFF)。在新一代的8051单片机中,特殊功能寄存器经常组合成16位来使用。采用关键字sfr16可以定义这种16位的特殊功能寄存器。例如,对于8052单片机的定时器T2,可采用如下的方法来定义:

这里T2为特殊功能寄存器名,等号后面是它的低字节地址,其高字节地址必须在物理上直接位于低字节之后。这种定义方法适用于所有新一代的8051单片机中新增加的特殊功能寄存器。

在8051单片机应用系统中经常需要访问特殊功能寄存器中的某些位,Keil C51编译器为此提供了一个扩充关键字sbit,利用它定义可位寻址对象。定义方法有如下三种。

(1)sbit位变量名=位地址

这种方法将位的绝对地址赋给位变量,位地址必须位于0x80~0xFF之间。例如:

(2)sbit位变量名=特殊功能寄存器名^位位置

当可寻址位位于特殊功能寄存器中时可采用这种方法,“位位置”是一个0~7之间的常数。例如:

(3)sbit位变量名 = 字节地址 ^ 位位置

这种方法以一个常数(字节地址)作为基地址,该常数必须在0x80H~0xFF之间。“位位置”是一个0~7之间的常数。例如:

当位对象位于8051单片机片内存储器中可位寻址区时称之为“可位寻址对象”。Keil C51编译器提供了一个bdata存储器类型,允许将具有bdata类型的对象放入8051单片机片内可位寻址区。例如:

使用关键字sbit可以独立访问可位寻址对象中的某一位。例如:

采用这种方法定义可位寻址变量时要求基址对象的存储器类型为bdata,操作符“^”后面“位位置”的最大值取决于指定的基地址类型,对于char类型来说是0~7;对于int类型来说是0~15;对于long类型来说是0~31。

需要注意的是,sbit是一个独立的关键字,不要将它与关键字bit相混淆。关键字bit是Keil C51编译器的一种扩充数据类型,用来定义一个普通位变量,它的值是二进制数的0或1。一个函数中可以包含bit类型的参数,函数的返回值也可为bit类型。例如:

如果在函数中禁止使用中断(#pragma disable)或者函数中包含明确的寄存器组切换(using n),则该函数不能返回型值,否则在编译时会产生编译错误。另外,不能定义位指针,也不能定义位数组。

上面介绍了变量及其定义方法,这在编写C语言程序时是十分重要的。从变量的作用范围来看,还有全局变量和局部变量之分。全局变量是指在程序开始处或各个功能函数的外面定义的变量,在程序开始处定义的全局变量对于整个程序都有效,可供程序中所有函数共同使用;而在各功能函数外面定义的全局变量只对从定义处开始往后的各个函数有效,只有从定义处往后的那些功能函数才可以使用该变量,定义处前面的函数则不能使用。

局部变量是指在函数内部或以花括号{}围起来的功能块内部所定义的变量,局部变量只在定义它的函数或功能块以内有效,在该函数或功能块以外则不能使用。局部变量可以与全局变量同名,但在这种情况下局部变量的优先级较高,而同名的全局变量在该功能块内被暂时屏蔽。

从变量的存在时间来看,又可分为静态存储变量和动态存储变量两种。

静态存储变量是指该变量在程序运行期间其存储空间固定不变;动态存储变量是指该变量的存储空间不确定,在程序运行期间根据需要动态地为该变量分配存储空间。一般来说,全局变量为静态存储变量,局部变量为动态存储变量。

在进行程序设计的时候经常需要给一些变量赋以初值,C语言允许在定义变量的同时给变量赋初值。下面是一些变量定义的例子。 tbAB0k6er6scAtHjpVDVm7DwaPIUnqNNy5zHPu/n1AIObASL5jLu8pqBw1xryowA

点击中间区域
呼出菜单
上一章
目录
下一章
×