单⽚机C语⾔C51的变量和常量
常量
常量是指在程序执⾏过程中其值不能改变的量。在C51中⽀持整型常量、浮点型常量、字符型常量和字符串型常量。
⼀.整型常量
整型常量也就是整型常数,根据其值范围在计算机中分配不同的字节数来存放。在C51中它可以表⽰成以下⼏种形式:
⼗进制整数。如234、-56、0等。
⼗六进制整数。以0x开头表⽰,如0x12表⽰⼗六进制数12H。
长整数。在C51中当⼀个整数的值达到长整型的范围,则该数按长整型存放,在存储器中占四个字节,另外,如⼀个整数后⾯加⼀个字母L,这个数在存储器中也按长整型存放。如123L在存储器中占四个字节。
⼆.浮点型常量
浮点型常量也就是实型常数。有⼗进制表⽰形式和指数表⽰形式。
⼗进制表⽰形式⼜称定点表⽰形式,由数字和⼩数点组成。如  0.123、34.645等都是⼗进制数表⽰形式的浮点型常量。
指数表⽰形式为: [±] 数字 [.数字] e [±]数字
例如:123.456e-3、-3.123e2等都是指数形式的浮点型常量。
三.字符型常量
字符型常量是⽤单引号引起的字符,如‘a’、‘1’、‘F’等。可以是可显⽰的ASCII字符,也可以是不可显⽰的控制字符。对不可显⽰的控制字符须在前⾯加上反斜杠“\”组成转义字符。利⽤它可以完成⼀些特殊功能和输出时的格式控制。常⽤的转义字符如下表所⽰。
四.字符串型常量
字符串型常量由双引号“”括起的字符组成。如“D”、“1234”、“ABCD”等。注意字符串常量与字符常量是不⼀样,⼀个字符常量在计算机内只⽤⼀个字节存放,⽽⼀个字符串常量在内存中存放时不仅双引号内的字符⼀个占⼀个字节,⽽且系统会⾃动的在后⾯加⼀个转义字符“\o”作为字符串结束符。因此不要将字符常量和字符串常量混淆,如字符常量‘A’和字符串常量“A”是不⼀样的。
变量
变量是在程序运⾏过程中其值可以改变的量。⼀个变量由两部分组成:变量名和变量值。
在C51中,变量在使⽤前必须对变量进⾏定义,指出变量的数据类型和存储模式。以便编译系统为它分配相应的存储单元。定义的格式如下:
[存储种类]  数据类型说明符  [存储器类型]  变量名1[=初值],变量名2[初值]…;
⼀.数据类型说明符
在定义变量时,必须通过数据类型说明符指明变量的数据类型,指明变量在存储器中占⽤的字节数。可以是基本数据类型说明符,也可以是组合数据类型说明符,还可以是⽤typedef定义的类型别名。
在C51中,为了增加程序的可读性,允许⽤户为系统固有的数据类型说明符⽤typedef起别名,格式如下:
typedef  c51固有的数据类型说明符  别名;
定义别名后,就可以⽤别名代替数据类型说明符对变量进⾏定义。别名可以⽤⼤写,也可以⽤⼩写,为了区别⼀般⽤⼤写字母表⽰。
【例】 typedef的使⽤。
typedef  unsigned  int  WORD;
typedef  unsigned  char  BYTE;
BYTE  a1=0x12;
WORD  a2=0x1234;
⼆.变量名
变量名是C51区分不同变量,为不同变量取的名称。在C51中规定变量名可以由字母、数字和下划线三
种字符组成,且第⼀个字母必须为字母或下划线。变量名有两种:普通变量名和指针变量名。它们的区别是指针变量名前⾯要带“*”号。
三.存储种类
存储种类是指变量在程序执⾏过程中的作⽤范围。C51变量的存储种类有四种,分别是⾃动(auto)、外部(extern)、静态(static)和寄存器(register)。
1.auto:
使⽤auto定义的变量称为⾃动变量,其作⽤范围在定义它的函数体或复合语句内部,当定义它的函数体或复合语句执⾏时,C51才为该变量分配内存空间,结束时占⽤的内存空间释放。⾃动变量⼀般分配在内存的堆栈空间中。定义变量时,如果省略存储种类,则该变量默认为⾃动(auto)变量。
2.extern:
使⽤extern定义的变量称为外部变量。在⼀个函数体内,要使⽤⼀个已在该函数体外或别的程序中定义过的外部变量时,该变量在该函数体内要⽤extern说明。外部变量被定义后分配固定的内存空间,在程序整个执⾏时间内都有效,直到程序结束才释放。
3.static:
使⽤static定义的变量称为静态变量。它⼜分为内部静态变量和外部静态变量。在函数体内部定义的静态变量为内部静态变量,它在对应的函数体内有效,⼀直存在,但在函数体外不可见,这样不仅使变量在定义它的函数体外被保护,还可以实现当离开函数时值不被改变。外部静态变量上在函数外部定义的静态变量。它在程序中⼀直存在,但在定义的范围之外是不可见的。如在多⽂件或多模块处理中,外部静态变量只在⽂件内部或模块内部有效。
指针变量的定义格式
4.register:
使⽤register定义的变量称为寄存器变量。它定义的变量存放在CPU内部的寄存器中,处理速度快,但数⽬少。C51编译器编译时能⾃动识别程序中使⽤频率最⾼的变量,并⾃动将其作为寄存器变量,⽤户可以⽆需专门声明。
四.存储器类型
存储器类型是⽤于指明变量所处的单⽚机的存储器区域情况。存储器类型与存储种类完全不同。C51编译器能识别的存储器类型有以下⼏种,见表所⽰。
定义变量时也可以省“存储器类型”,省时C51编译器将按编译模式默认存储器类型,具体编译模式的情况在后⾯介绍。
【例】变量定义存储种类和存储器类型相关情况。
char  data varl;  /*在⽚内RAM低128B定义⽤直接寻址⽅式访问的字符型变量var1*/
int  idata  var2;  /*在⽚内RAM256B定义⽤间接寻址⽅式访问的整型变量var2*/
auto  unsigned  long  data  var3;  /*在⽚内RAM128B定义⽤直接寻址⽅式访问的⾃动⽆符号长整型变量var3*/
extern  float  xdata  var4;  /*在⽚外RAM64KB空间定义⽤间接寻址⽅式访问的外部实型变量var4*/
int  code  var5;      /*在ROM空间定义整型变量var5*/
unsign  char  bdata  var6;  /*在⽚内RAM位寻址区20H~2FH单元定义可字节处理和位处理的⽆符号字符型变量var6*/
五.特殊功能寄存器变量
51系列单⽚机⽚内有许多特殊功能寄存器,通过这些特殊功能寄存器可以控制51系列单⽚机的定时器、计数器、串⼝、I/O及其它功能部件,每⼀个特殊功能寄存器在⽚内RAM中都对应于⼀个字节单元或两个字节单元。
在C51中,允许⽤户对这些特殊功能寄存器进⾏访问,访问时须通过sfr或sfr16类型说明符进⾏定义,定义时须指明它们所对应的⽚内RAM单元的地址。格式如下:
sfr或sfr16  特殊功能寄存器名=地址;
sfr⽤于对51单⽚机中单字节的特殊功能寄存器进⾏定义,sfr16⽤于对双字节特殊功能寄存器进⾏定义。特殊功能寄存器名⼀般⽤⼤写字母表⽰。地址⼀般⽤直接地址形式,具体特殊功能寄存器地址见前⾯内容。
【例】特殊功能寄存器的定义。
sfr  PSW=0xd0;
sfr  SCON=0x98;
sfr  TMOD=0x89;
sfr  P1=0x90;
sfr16  DPTR=0x82;
sfr16  T1=0X8A;
六.位变量
在C51中,允许⽤户通过位类型符定义位变量。位类型符有两个:bit和sbit。可以定义两种位变量。
bit位类型符⽤于定义⼀般的可位处理位变量。它的格式如下:
bit  位变量名;
在格式中可以加上各种修饰,但注意存储器类型只能是bdata、data、idata。只能是⽚内RAM的可位寻址区,严格来说只能是bdata。
【例】  bit型变量的定义。
bit  data  a1;      /*正确*/
bit  bdata  a2;    /*正确*/
bit  pdata  a3;    /*错误*/
bit  xdata  a4;    /*错误*/
sbit位类型符⽤于定义在可位寻址字节或特殊功能寄存器中的位,定义时须指明其位地址,可以是位直接地址,可以是可位寻址变量带位号,也可以是特殊功能寄存器名带位号。格式如下:
sbit  位变量名=位地址;
如位地址为位直接地址,其取值范围为0x00~0xff;如位地址是可位寻址变量带位号或特殊功能寄存器名带位号,则在它前⾯须对可位寻址变量或特殊功能寄存器进⾏定义。字节地址与位号之间、特殊功能寄存器与位号之间⼀般⽤“^”作间隔。
【例】sbit型变量的定义:
sbit  OV=0xd2;
sbit  CY=oxd7;
unsigned  char  bdata  flag;
sbit  flag0=flag^0;
sfr  P1=0x90;
sbit  P1_0=P1^0;
sbit  P1_1=P1^1;
sbit  P1_2=P1^2;
sbit  P1_3=P1^3;
sbit  P1_4=P1^4;
sbit  P1_5=P1^5;
sbit  P1_6=P1^6;
sbit  P1_7=P1^7;
在C51中,为了⽤户处理⽅便,C51编译器把51单⽚机的常⽤的特殊功能寄存器和特殊位进⾏了定义,放在⼀
个“reg51.h”或“reg52.h”的头⽂件中,当⽤户要使⽤时,只须要在使⽤之前⽤⼀条预处理命令#include  <reg52.h>把这个头⽂件包含到程序中,然后就可使⽤殊功能寄存器名和特殊位名称。