windows7专业版-华为mate30怎么升级鸿蒙系统
![127 0 0 1](/uploads/image/0612.jpg)
2023年4月3日发(作者:怎么定位手机)
第四课数据类型
先来简单说说C语言的标识符和关键字。标识符是用来标识源程序中某个对象的名字的,这些对象可
以是语句、数据类型、函数、变量、数组等等。C语言是大小字敏感的一种高级语言,如果我们要定义一
个定时器1,可以写做"Timer1",如果程序中有"TIMER1",那么这两个是完全不同定义的标识符。标识符
由字符串,数字和下划线等组成,注意的是第一个字符必须是字母或下划线,如"1Timer"是错误的,编译
时便会有错误提示。有些编译系统专用的标识符是以下划线开头,所以一般不要以下划线开头命名标识符。
标识符在命名时应当简单,含义清晰,这样有助于阅读理解程序。在C51编译器中,只支持标识符的前32
位为有效标识,一般情况下也足够用了,除非你要写天书:P。
关键字则是编程语言保留的特殊标识符,它们具有固定名称和含义,在程序编写中不允许标识符与关
键字相同。在KEILuVision2中的关键字除了有ANSIC标准的32个关键字外还根据51单片机的特点扩展
了相关的关键字。其实在KEILuVision2的文本编辑器中编写C程序,系统可以把保留字以不同颜色显示,
缺省颜色为天蓝色。
先看表4-1,表中列出了KEILuVision2C51编译器所支持的数据类型。在标准C语言中基本的数据
类型为char,int,short,long,float和double,而在C51编译器中int和short相同,float和double相同,这里就
不列出说明了。下面来看看它们的具体定义:
数据类型长度值域
unsignedchar单字节0~255
signedchar单字节-128~+127
unsignedint双字节0~65535
signedint双字节-32768~+32767
unsignedlong四字节0~
signedlong四字节-~+
float四字节±1.E-38~±3.E+38
*1~3字节对象的地址
bit位0或1
sfr单字节0~255
sfr16双字节0~65535
sbit位0或1
表4-1KEILuVision2C51编译器所支持的数据类型
1.char字符类型
char类型的长度是一个字节,通常用于定义处理字符数据的变量或常量。分无符号字符类型unsignedchar
和有符号字符类型signedchar,默认值为signedchar类型。unsignedchar类型用字节中所有的位来表示数
值,所可以表达的数值范围是0~255。signedchar类型用字节中最高位字节表示数据的符号,"0"表示正数,
"1"表示负数,负数用补码表示。所能表示的数值范围是-128~+127。unsignedchar常用于处理ASCII字符
或用于处理小于或等于255的整型数。
*正数的补码与原码相同,负二进制数的补码等于它的绝对值按位取反后加1。
2.int整型
int整型长度为两个字节,用于存放一个双字节数据。分有符号int整型数signedint和无符号整型数unsigned
int,默认值为signedint类型。signedint表示的数值范围是-32768~+32767,字节中最高位表示数据的符号,
"0"表示正数,"1"表示负数。unsignedint表示的数值范围是0~65535。
好了,先停一下吧,我们来写个小程序看看unsignedchar和unsignedint用于延时的不同效果,说明它们的
长度是不同的,呵,尽管它并没有实际的应用意义,这里我们学习它们的用法就行。依旧用我们上一课的
最小化系统做实验,不过要加多一个电阻和LED,如图4-1。实验中用D1的点亮表明正在用unsignedint
数值延时,用D2点亮表明正在用unsignedchar数值延时。
图4-1第4课实验用电路
我们把这个项目称为TwoLED,实验程序如下:
#include
voidmain(void)//主函数名
{
unsignedinta;//定义变量a为unsignedint类型
unsignedcharb;//定义变量b为unsignedchar类型
do
{//dowhile组成循环
for(a=0;a<65535;a++)
P1_0=0;//65535次设P1.0口为低电平,点亮LED
P1_0=1;//设P1.0口为高电平,熄灭LED
for(a=0;a<30000;a++);//空循环
for(b=0;b<255;b++)
P1_1=0;//255次设P1.1口为低电平,点亮LED
P1_1=1;//设P1.1口为高电平,熄灭LED
for(a=0;a<30000;a++);//空循环
}
while(1);
}
同样编译烧写,上电运行您就可以看到结果了。很明显D1点亮的时间长于D2点亮的时间。程序中的循环
延时时间并不是很好确定,并不太适合要求精确延时的场合,关于这方面我们以后也会做讨论。这里必须
要讲的是,当定义一个变量为特定的数据类型时,在程序使用该变量不应使它的值超过数据类型的值域。
如本例中的变量b不能赋超出0~255的值,如for(b=0;b<255;b++)改为for(b=0;b<256;b++),编译是可以
通过的,但运行时就会有问题出现,就是说b的值永远都是小于256的,所以无法跳出循环执行下一句P1_1
=1,从而造成死循环。同理a的值不应超出0~65535。大家可以烧片看看实验的运行结果,同样软件仿真
也是可以看到结果的。
3.long长整型
long长整型长度为四个字节,用于存放一个四字节数据。分有符号long长整型signedlong和无符号长整型
unsignedlong,默认值为signedlong类型。signedint表示的数值范围是-~+,字节中最高位表示数据的符
号,"0"表示正数,"1"表示负数。unsignedlong表示的数值范围是0~。
4.float浮点型
float浮点型在十进制中具有7位有效数字,是符合IEEE-754标准的单精度浮点型数据,占用四个字节。
因浮点数的结构较复杂在以后的章节中再做详细的讨论。5.*指针型
指针型本身就是一个变量,在这个变量中存放的指向另一个数据的地址。这个指针变量要占据一定的内存
单元,对不同的处理器长度也不尽相同,在C51中它的长度一般为1~3个字节。指针变量也具有类型,
在以后的课程中有专门一课做探讨,这里就不多说了。
6.bit位标量
bit位标量是C51编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义
位数组。它的值是一个二进制位,不是0就是1,类似一些高级语言中的Boolean类型中的True和False。
7.sfr特殊功能寄存器
sfr也是一种扩充数据类型,点用一个内存单元,值域为0~255。利用它可以访问51单片机内部的所有特
殊功能寄存器。如用sfrP1=0x90这一句定P1为P1端口在片内的寄存器,在后面的语句中我们用以用P1
=255(对P1端口的所有引脚置高电平)之类的语句来操作特殊功能寄存器。
*AT89C51的特殊功能寄存器表请看附录二
8.sfr1616位特殊功能寄存器
sfr16占用两个内存单元,值域为0~65535。sfr16和sfr一样用于操作特殊功能寄存器,所不同的是它用于
操作占两个字节的寄存器,好定时器T0和T1。
9.sbit可录址位
sbit同位是C51中的一种扩充数据类型,利用它可以访问芯片内部的RAM中的可寻址位或特殊功能寄存器
中的可寻址位。如先前我们定义了
sfrP1=0x90;//因P1端口的寄存器是可位寻址的,所以我们可以定义
sbitP1_1=P1^1;//P1_1为P1中的P1.1引脚
//同样我们可以用P1.1的地址去写,如sbitP1_1=0x91;
这样我们在以后的程序语句中就可以用P1_1来对P1.1引脚进行读写操作了。通常这些可以直接使用系统
提供的预处理文件,里面已定义好各特殊功能寄存器的简单名字,直接引用可以省去一点时间,我自己是
一直用的。当然您也可以自己写自己的定义文件,用您认为好记的名字。
关于数据类型转换等相关操作在后面的课程或程序实例中将有所提及。大家可以用所讲到的数据类型
改写一下这课的实例程序,加深对各类型的认识。
附录
附录一C51中的关键字
关键字用途说明
auto存储种类说明用以说明局部变量,缺省值为此
break程序语句退出最内层循环
case程序语句Switch语句中的选择项
char数据类型说明单字节整型数或字符型数据
const存储类型说明在程序执行过程中不可更改的常
量值
continue程序语句转向下一次循环
default程序语句Switch语句中的失败选择项
do程序语句构成do..while循环结构
double数据类型说明双精度浮点数
else程序语句构成if..else选择结构
enum数据类型说明枚举
extern存储种类说明在其他程序模块中说明了的全局
变量
flost数据类型说明单精度浮点数
for程序语句构成for循环结构
goto程序语句构成goto转移结构
if程序语句构成if..else选择结构
int数据类型说明基本整型数
long数据类型说明长整型数
register存储种类说明使用CPU内部寄存的变量
return程序语句函数返回
short数据类型说明短整型数
signed数据类型说明有符号数,二进制数据的最高位为
符号位
sizeof运算符计算表达式或数据类型的字节数
static存储种类说明静态变量
struct数据类型说明结构类型数据
swicth程序语句构成switch选择结构
typedef数据类型说明重新进行数据类型定义
union数据类型说明联合类型数据
unsigned数据类型说明无符号数数据
void数据类型说明无类型数据
volatile数据类型说明该变量在程序执行中可被隐含地
改变
while程序语句构成while和do..while循环结构
附表1-1ANSIC标准关键字
关键字用途说明
bit位标量声明声明一个位标量或位类型的函数
sbit位标量声明声明一个可位寻址变量
Sfr特殊功能寄存器声明声明一个特殊功能寄存器
Sfr16特殊功能寄存器声明声明一个16位的特殊功能寄存器
data存储器类型说明直接寻址的内部数据存储器
bdata存储器类型说明可位寻址的内部数据存储器
idata存储器类型说明间接寻址的内部数据存储器
pdata存储器类型说明分页寻址的外部数据存储器
xdata存储器类型说明外部数据存储器
code存储器类型说明程序存储器
interrupt中断函数说明定义一个中断函数
reentrant再入函数说明定义一个再入函数
using寄存器组定义定义芯片的工作寄存器
附表1-2C51编译器的扩展关键字
附录二AT89C51特殊功能寄存器列表(适用于同一架构的芯片)
符号地址注释
*ACCE0H累加器
*BF0H乘法寄存器
*PSWD0H程序状态字
SP81H堆栈指针
DPL82H数据存储器指针低8位
DPH83H数据存储器指针高8位
*IEA8H中断允许控制器
*IPD8H中断优先控制器
*P080H端口0
*P190H端口1
*P2A0H端口2
*P3B0H端口3
PCON87H电源控制及波特率选择
*SCON98H串行口控制器
SBUF99H串行数据缓冲器
*TCON88H定时器控制
TMOD89H定时器方式选择
TL08AH定时器0低8位
TL18BH定时器1低8位
TH08CH定时器0低8位
TH18DH定时器1高8位
带*号的特殊功能寄存器都是可以位寻址的寄存器
第五课常量
上一节我们学习了KEILC51编译器所支持的数据类型。而这些数据类型又是怎么用在常量和变量的
定义中的呢?又有什么要注意的吗?下面就来看看吧。晕!你还区分不清楚什么是常量,什么是变量。常
量是在程序运行过程中不能改变值的量,而变量是可以在程序运行过程中不断变化的量。变量的定义可以
使用所有C51编译器支持的数据类型,而常量的数据类型只有整型、浮点型、字符型、字符串型和位标量。
这一节我们学习常量定义和用法,而下一节则学习变量。
常量的数据类型说明是这样的
1.整型常量可以表示为十进制如123,0,-89等。十六进制则以0x开头如0x34,-0x3B等。长整型就
在数字后面加字母L,如104L,034L,0xF340等。
2.浮点型常量可分为十进制和指数表示形式。十进制由数字和小数点组成,如0.888,3345.345,0.0等,
整数或小数部分为0,可以省略但必须有小数点。指数表示形式为[±]数字[.数字]e[±]数字,[]中的内容为可
选项,其中内容根据具体情况可有可无,但其余部分必须有,如125e3,7e9,-3.0e-3。
3.字符型常量是单引号内的字符,如'a','d'等,不可以显示的控制字符,可以在该字符前面加一个反
斜杠""组成专用转义字符。常用转义字符表请看表5-1。
4.字符串型常量由双引号内的字符组成,如"test","OK"等。当引号内的没有字符时,为空字符串。
在使用特殊字符时同样要使用转义字符如双引号。在C中字符串常量是做为字符类型数组来处理的,在存
储字符串时系统会在字符串尾部加上o转义字符以作为该字符串的结束符。字符串常量"A"和字符常量'A'
是不同的,前者在存储时多占用一个字节的字间。
5.位标量,它的值是一个二进制。
转义字符含义ASCII码(16/10进制)
o空字符(NULL)00H/0
n换行符(LF)0AH/10
r回车符(CR)0DH/13
t水平制表符(HT)09H/9
b退格符(BS)08H/8
f换页符(FF)0CH/12
'单引号27H/39
"双引号22H/34
反斜杠5CH/92
表5-1常用转义字符表
常量可用在不必改变值的场合,如固定的数据表,字库等。常量的定义方式有几种,下面来加以说明。
#difineFalse0x0;//用预定义语句可以定义常量
#difineTrue0x1;//这里定义False为0,True为1
//在程序中用到False编译时自动用0替换,同理True替换为1
unsignedintcodea=100;//这一句用code把a定义在程序存储器中并赋值
constunsignedintc=100;//用const定义c为无符号int常量并赋值
以上两句它们的值都保存在程序存储器中,而程序存储器在运行中是不允许被修改的,所以如果在这
两句后面用了类似a=110,a++这样的赋值语句,编译时将会出错。
说了一通还不如写个程序来实验一下吧。写什么程序呢?跑马灯!对,就写这个简单易懂的吧,这个也好
说明典型的常量用法。先来看看电路图吧。它是在我们上一课的实验电路的基础上增加6个LED组成的,
也就是用P1口的全部引脚分别驱动一个LED,电路如图5-1所示。
新建一个RunLED的项目,主程序如下:
#include
voidmain(void)
{
//定义花样数据
constunsignedchardesign[32]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF,
0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x0,
0xE7,0xDB,0xBD,0x7E,0xFF};
unsignedinta;//定义循环用的变量
unsignedcharb;//在C51编程中因内存有限尽可能注意变量类型的使用
//尽可能使用少字节的类型,在大型的程序中很受用
do{
for(b=0;b<32;b++)
{
for(a=0;a<30000;a++);//延时一段时间
P1=design[b];//读已定义的花样数据并写花样数据到P1口
}
}while(1);
}
程序中的花样数据可以自以去定义,因这里我们的LED要AT89C51的P1引脚为低电平才会点亮,所
以我们要向P1口的各引脚写数据O对应连接的LED才会被点亮,P1口的八个引脚刚好对应P1口特殊寄
存器的八个二进位,如向P1口定数据0xFE,转成二进制就是,最低位D0为0这里P1.0引脚输出低电平,LED1
被点亮。如此类推,大家不难算出自己想要做的效果了。大家编译烧写看看,效果就出来,显示的速度您
可以根据需要调整延时a的值,不要超过变量类型的值域就很行了。哦,您还没有实验板?那如何可以知
道程序运行的结果呢?呵,不用急,这就来说说用KEILuVision2的软件仿真来调试IO口输出输入程序。
图5-1八路跑马灯电路
编译运行上面的程序,然后按外部设备菜单Peripherals-I/OPorts-Port1就打开Port1的调试窗口了,
如图5-3中的2。这时程序运行了,但我们并不能在Port1调试窗口上看到有会什么效果,这时我们可以
用鼠标左击图5-3中1旁边绿色的方条,点一下就有一个小红方格在点一下又没有了,哪一句语句前有小
方格程序运行到那一句时就停止了,就是设置调试断点,同样图5-2中的1也是同样功能,分别是增加/
移除断点、移除所有断点、允许/禁止断点、禁止所有断点,菜单也有一样的功能,另外菜单中还有Breakpoints
可打开断点设置窗口它的功能更强大,不过我们这里先不用它。我们?quot;P1=design[b];"这一句设置一个
断点这时程序运行到这里就停住了,再留意一下Port1调试窗口,再按图5-2中的2的运行键,程序又运行
到设置断点的地方停住了,这时Port1调试窗口的状态又不同了。也就是说Port1调试窗口模拟了P1口的
电平状态,打勾为高电平,不打勾则为低电平,窗口中P1为P1寄存器的状态,Pins为引脚的状态,注意
的是如果是读引脚值必须把引脚对应的寄存器置1才能正确读取。图5-2中2旁边的{}样的按钮分别为
单步入,步越,步出和执行到当前行。图中3为显示下一句将要执行的语句。图5-3中的3是Watches窗
口可查看各变量的当前值,数组和字串是显示其头一个地址,如本例中的design数组是保存在code存储区
的首地址为D:0x08,可以在图中4Memory存储器查看窗口中的Address地址中打入D:0x08就可以查看到
design各数据和存放地址了。如果你的uVision2没有显示这些窗口,可以在View菜单中打开在图5-2中
3后面一栏的查看窗口快捷栏中打开。
图5-2调试用快捷菜单栏
图5-3各调试窗口
更多推荐
127 0 0 1
发布评论