版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第五章 构造数据类型Cx51 的构造数据类型主要有数组、指针和结构等。在单片机系统中,数组的应用比较广泛,指针则次之,结构用的相对较少,这和单片机系统的要求以及用户的程序设计习惯有一定的关系。一、 数组数组是同类型数据的一个有序集合。数组用一个名字来标识,称为数组名。数组中各元素的顺序用下标表示,下标为n 的元素可以表示为数组名n。改变 中的下标就可以访问数组中所有的元素。1、 一维数组由具有一个下标的数组元素组成的数组称为一维数组,定义一维数组的一般形式如下:类型说明符 存储器类型 数组名元素个数=初值1,初值n;其中,数组名是一个标识符,元素个数是一个常量表达式,不能是含有变量的表达式。和
2、标准C比较,多了一个存储器类型。例1:unsigned int idata demo110;定义一个数组名为demo1 的数组,数组包含10 个无符号整型的元素,片内间接寻址。在定义数组时可以对数组进行整体初始化,若定义后想对数组赋值,则只能对每个元素分别赋值。例2:char data a5=1,2,3,4,5;/给全部元素赋值,a0=1,a1=2,a2=3,a3=4,a4=5int b6=1,2,6;/给部分元素赋值,b0=1,b1=2,b2=6,b3=b4=b5=02、 二维数组和多维数组数组的下标具有两个,则称为二维数组。定义二维数组的一般形式如下:类型说明符 存储器类型 数组名行数 列
3、数=初值表1,初值表n;其中,数组名是一个标识符,行数和列数都是常量表达式。例1:float xdata demo234;/demo2 数组有3 行4 列共12个实型元素,存储在片外RAM中。二维数组也可以在定义时进行整体初始化,也可以在定义后单个地进行赋值。例2:char pdata a34=1,2,3,4,5,6,7,8,9,10,11,12;/全部初始化int b34=1,2,3,4,5,6,7,8,;/部分初始化,未初始化的个元素为0说明:1)多维数组是二维数组的延伸,定义格式基本相同。但由于单片机中内存较小,多维数组用的很少。2)如果不赋初值,计算机自动置0。3、 字符数组若一个数组
4、的元素是字符型的,则该数组就是一个字符数组。例如:char a20=“Shanxi Ligongxueyuan”;/字符数组char add36=weight,height,width; /字符串数组数组名地址数据a10x340x12a20x350x34a30x360x564、数组的存储1)一维数组的存储一维数组在存储空间连续存储,数组名就是数组存储的首地址。注意不同的数据类型占用的字节长度不一样。数组名地址x00+0x01+1x02+2x10+3x11+4x12+5x20+5x21+7x22+8char data a3=0x12,0x34,0x56;2)二维数组的存储对二维数组,同样数组名就
5、是首地址,存储时,将每列的数据存完后,再存储下一列的数据,如图:表中地址1表示加一个数据单位,根据数据类型不同一个数据单位所占字节不同,如插入为1字节;int为2字节;long为4字节等。5、数组的应用数组在编程时应用很多,如LED显示的字形表,在数据进行滤波等处理中多用到数组。下面举一个将摄氏温度转换成华氏温度的例子,在出口产品中经常要求转换。例1:将摄氏温度05转换成华氏温度。转换关系:转换时,可以用公式在程序中进行计算转换,也可以先将转换关系转换成表格,用查表法进行转换,一般查表法占用内存少,速度快,对于表格数量不大的情况下,经常用数组或查表法。源程序如下:#define uchar u
6、nsigned charuchar code tempt=32,34,36,37,39,41;/*数组元素可以为空,根据实际数据多少在编译时设置,初值为转换成华氏温度的值,按顺序排列*/uchar ftoc(uchar degc)/转换函数 return temptdegc;main() x=ftoc(5);例2:用冒泡法对一组数据进行排序。排序是一种十分有用的数据处理方法,例如在对测量值进行中值滤被之前,必须先对测量数据进行排序。 #include #include #define uchar unsigned char void main() uchar data a=0x3f,0x44,
7、0x32,0x54,0x66,0x56,0x99,0x88,0x77,0x11,0x34;/11个数uchar i,j,t;for(j=0;j=8;j+)for(i=0;iai+1) t=ai;ai=ai+1;ai+1=t;/交换数据,将最大的排到最后运行结果,将数组内的数从小到大排列。(冒泡法排序)例3:用8155扩展的LED显示。共显示4个数据,每个数据小于999,用8155的A口作为字位控制,地址为ff21,共阳极,点亮时输出高电平;用8155的B口输出字型码,地址为ff22,低电平亮。参考程序如下:#include#include #define uchar unsigned char
8、 #define uint unsigned int#define COM8155 PBYTE0xff20/控制字地址 #define PA8155 PBYTE0xff21/字位地址 #define PB8155 PBYTE0xff22 /字形码地址uchar code dispcode=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff,0x0c,0x89,0xbf; /字形代码表 ,共阳uint dispbuf3,getdata4=123,343,564,679;/*显示缓
9、存和4通道数据缓存,全局变量 */uchar dd,m=0; disp2()/显示字符,显示3位, uchar i1=2,j; for(j=0x04;j!=0;j=j1)/循环3次 PA8155=j; PB8155=dispcodedispbufi1; I1=i1-; disp1(uchar k) /显示拆分字符程序 uint getd; getd=getdatak; dispbuf2=getd/100; getd=getd%100; dispbuf1=getd/10; dispbuf0=getd%10; disp2(); void main(void) uchar i=0; COM8155=
10、0x01;/PA,PB为基本输出方式 SP=0x53; PA8155=0x00;/关显示 while(1) disp1(i); i=i+; if(i=4) i=0; (实验显示)二、 结构1、基本概念 结构是一种构造类型的数据,它是将若干个不同类型的数据变量有序地组合在一起而形成的一种数据的集合体。组成该集合体的各个数据变量称为结构成员,整个集合体使用一个单独的结构变量名。一般来说结构中的各个变量之间是存在某些关联的,例如时间数据中的时、分、秒,日期数据中的年、月、日等。由于结构是将一组相关联的数据变量作为一个整体来进行处理,因此在程序中使用结构将有利于对一些复杂且具有内在联系的数据进行有序的
11、管理。2、结构变量的定义 有二种定义结构变量的方法,分述如下。 1)先定义结构类型再定义结构变量名 定义结构类型的一般格式为: struct结构名 结构成员表; 其中,“结构成员表”为该结构中的各个成员,由于结构可以由不同类型的数据组成,因此对结构中的各个成员都要进行类型说明。例如定义一个日期结构类型date,它由三个结构元素year、month、day组成,定义格式如下: struct date int year; char month;char day; ;结构类型是对该结构中都含那些元素,各元素的数据类型进行说明,编译时给变量分配存储空间。(上例中1个变量留4个存储单元)定义好结构类型之
12、后,就可以用它来定义结构变量。一般格式为:存储器类型 struct 结构名 结构变量名l,结构变量名2,结构变量名n;注意:先定义结构类型,然后定义结构变量。例如可以用结构date来定义两个结构变量dl和d1:struct date dl,d2; 结构变量dl和d2都具有struct date类型的结构,即它们都是由1个整型数据和2个字符型数据所组成的。 2)在定义结构类型的同时定义结构变量名 这种方法是将方法l的两个步骤合在一起,一般格式为: struct 结构名 结构成员表 存储器类型 结构变量名l,结构变量名2结构变量名n; 例如对于上述日期结构变量也可按以下格式定义: struct d
13、ate int year;char month,day; xdata d1,d2; 关于结构变量的应用有几点需要注意的地方: 1)结构类型与结构变量是两个不同的概念。定义一个结构类型时只是给出了该结构的组织形式,并没有给出具体的组织成员。因此结构名不占用任何存储空间,也不能对一个结构名进行赋值、存取和运算。结构变量是一个结构中的具体组织成员,编译器会给具体的结构变量名分配确定的存储空间,因此可以对结构变量名进行赋值、存取和运算。 2)一个结构中的结构成员还可以是另外一个结构,即可以形成结构的嵌套。 3)一个结构中的结构成员的名字可以与程序中其它地方使用的变量同名。在使用中不会互相影响。 4)结
14、构体成员不能是位变量。3、结构变量的引用 在定义了一个结构变量之后,就可以对它进行引用,即可以进行赋值、存取和运算。一般情况下,结构变量的引用是通过对其结构成员的引用来实现的。引用结构成员的一般格式为: 结构变量名结构成员 其中“”是存取结构成员运算符。例如:d1year2006;表示给结构变量dl中的成员year赋值。如果一个结构变量中的结构成员又是另外一个结构变量,即出现结构的嵌套时,则需要采用若干个成员运算符,一级级地找到最低级的结构成员,而且只能对这个最低级的结构成员进行访问。例如:clerk1birthdayyear=20064、例子 1)includevoid main()stru
15、ct date 说明第一个结构 int month; char day;int year; 说明3个结构成员data date1;第一个结构变量的1种说明方法pdata struct date date2; 第二种说明方法struct clerk 说明第二个结构 int num; struct date birthday;第一个结构是第二个结构的成员;struct clerk teacher;第二个结构的第一个变量说明xdata struct clerk classl30;xdata struct clerk class230;第二个结构的其他变量 date1month=9; datelday
16、13; date1year1989; date2month=8;结构的引用 date2day=22; date2year2005;class123 birthdaymonth=1O;class23 birthdaymonth=11;(运行“结构”)5、结构数据的存储成员1变量1成员2成员k成员1变成员2量2成员k成员1按照结构变量为大循环,结构成员为小循环依次存放。即按定义的顺序,每一个结构变量的成员是在连续空间,存完一个变量的成员后,接着存放下一个成员。与数组相同,也是按数据单位存放。三、 指针指针是C语言的一个难点,也是C语言的精华。C51的指针内容与标准C基本相同,有一些小的区别。1、指
17、针变量的概念1)指针的概念地址变量代号35H0x12a36H0x34b50H0x35p151H0x36p2 一个程序的指令、常量和变量等都要存放在机器的内存单元中,该单元有一个地址,这就是存储单元的地址。通过地址可以找到所需要的需要的存储内容。一个变量的地址就称为该变量的指针。例如,有个整型变量a0x12存放在内存单元35H中,则该内存单元地址35H就是变量a的指针。可以这样理解:变量就是存储在单元中可变的内容,而该单元的地址就是指针。2)取地址运算符 &使用格式: & 变量作用:取出&符号右侧变量的地址(指针)。地址变量代号35H0x12a36H0x34b50H0x35p151H0x36p2
18、例:ap&a;/将地址35H送入ap。3)指针变量因为变量就是存储在单元中的内容,如果存储的内容为地址(指针),则该变量就是指针变量。就和汇编语言中R1的含义完全一样。如在上图中,将地址35H放到地址为50H的单元中,则35H就是指针变量。4)指针变量的定义指针变量的定义与一般变量的定义类似,其一般形式如下:地址变量代号35H0x12a36H0x34b50H0x35p151H0x36p2 数据类型 存储器类型1 * 存储器类型2 标识符=初值;其中:标识符:是所定义的指针变量名,可以赋初值,赋初值时用取址符“&”,或者直接赋地址。数据类型:存储到指针(地址)中数据的类型。(图中0X12)特别注
19、意:指针定义中的数据类型必须和存储的数据类型完全一致。如果给指针中送数据,送的数据类型必须与此处定义的类型相同,否则编译出错。存储器类型1:指针对象存储类型;存储器类型2:指针存储类型。(1)普通指针:省略存储器类型1时,为普通指针。普通指针在存储时占用3 字节。三个字节的内容见下表:地 址012内 容存储类型代码高位地址偏移量低位地址偏移量存储类型代码如下:存储类型idata/data/bdataxdatapdatacode编码值0x000x010xfe0xff其中存储类型代码是由指针变量中所存储数据的存储类型确定。(按存位置,主要是地址区分)(2)基于存储器的指针如果在定义中给出指针变量存
20、储类型,就是基于存储器的指针。当存储器类型1为data,idata,pdata,指针长度占1个字节;存储器类型1为xdata, 指针长度占2个字节。当为16位地址时要用xdata。要根据地址的长度确定存储类型。注意:因为该项是指针对象(即地址中存的内容)的存储类型,存储对象本身已定义存储类型,在此必须两者一致,否则出错。最好的办法是该项省略,用普通指针。 存储器类型2指针变量的存储器类型。在上图中,指0x35的存储器类型。一般可以不指明,由编译器确定。如果用xdata类型,就把指针变量的地址存储到片外RAM中。可以这样理解,盖一个房子存放地址,存储类型1确定房子的大小,也就是存地址时占几个字节
21、;存储类型2确定将房子盖在什么地方,即地址存到片内还是片外。char xdata *px;/ px本身在默认的存储器中,指针占2 字节“*”是指针定义符,表示右边的标识符代表一个指针。但要注意的是:如果将“*”都理解成指针定义符,则不好解释,所以后面又将其称作指针定义或间接访问运算符。 #include main()int xdata * data p;int data a=0x1234,b;/注意:定义的数据a存在片内,/则指针定义时存储器类型1也要求是“data”存储类型,/否则出错。同时要求变量与指针变量的数据类型必须一致,如上面的“int”。上面定义是不对的。p=&a;b=*p;/注意
22、观察(指针类型)例如:Int data *p1;/基于存储器指针,1字节,地址存片内float * xdata p2;/普通指针,3字节,指针存片外。5)常数指针常数指针就是将一个常数定义为指针,常用来定义地址,如:(P318)#include#define PA8155 XBYTE0X00F1main() int *a1; a1=&PA8155;(见指针常量)注意看教材P318页,如果按页访问,要用PBYTE,在实验中就是这样。6)间接访问运算符 *同汇编语言中的间接寻址()的作用相同,该 * 作为运算符,表示将 * 右边地址中的内容取出。有没有必要如此区分是指针定义符还是间接访问运算符,怎
23、么区分是定义符还是运算符?下面看一个例子:地址变量代号35H0x23a36H0x23b50H35Hpint a=0x23,b;int *p=&a;/定义了一个指针变量并将变量a的地址送入b=*p;/将a送入b如果直观从形式看, b中存储的是a变量的地址呢?指针定义符与间接访问运算符的区别:(1)指针定义符的位置有下列特点:无等号(int *p);或者在等号的左侧(int *p=&a);或者表达式中有多个“*”时,出现在“*”的右侧(b=*p)。要注意多维数组中的指针数组规律与此不同。(2)间接访问运算符一般在等号右边(b=*(p+i););表达式中有多个“*”时,出现在“*”的最左边(b=*p
24、)。例:int *p;/定义符 int *p=&a;/定义符 b=*(p+i);/ 间接访问运算符 b=*(*(ap+i)+j);/左边的是间接访问运算符,右边的是定义符 b=*p;/ 左边的是间接访问运算符,右边的是定义符7)指针使用中的注意事项:(1)指针变量中存放的只能地址。指针变量定义后,可以给变量赋值,赋值时变量前面不要”*”,但必须是地址。如: int data x3=1,2,3; uchar *ad_adr; ad_adr=&x;ad_adr=x;/正确的,数组也可以不加“&”符号如:int *p;/表示指向的变量为整型 p=0x09;(2)指针(地址)中所存对象的数据类型不同,
25、指针给数据留的空间不同,如指针指向char数据类型,留一个字节;若是long数据类型,则留4个字节。(3)一个指针变量只能指向同一类型的变量,因为指针定义了指向变量的类型。而定义变量时也定义了变量类型,该部分不注意容易出错。(见“指针类型”)(4)指针加1表示加了1个存储单位,一个存储单位占几个字节要根据数据类型确定,char型为1个字节;int型为两个字节等。二、指针变量使用中的要点指针变量既然是存储地址的变量,虽然应用很灵活,但万变不离其宗,所以使用时要紧扣以下几点:1、存的是数据还是函数的地址,数据类型是什么,数据的数量及存储方式。2、指针变量所指数据类型存储的方式,这一点很重要,如一维
26、数组,按次序存放,数组名也就是第一个数组元素的地址,定义一个数组指针变量,则该变量里面存的就是该数组的首地址。对于函数,在ROM中占连续一片空间进行存储,函数的指针变量就是该函数存储的首地址。3、c语言语法中对不同数据类型和函数的指针定义是怎么规定的,如何引用。最好通过例子进行理解。该内容很重要,因为指针变量的概念很简单,就是存放地址的变量,所以必须清楚:1)指针变量中存的是那一类数据的地址,数组、结构、函数还是一般变量;2)如何通过该地址将数据传输到该变量中;3)如何取出该数据。三、指针与数组由前面已经知道,一个数组是由连续的一块内存单元组成的。 数组名就是这块连续内存单元的首地址。一个数组
27、也是由各个数组元素组成的。按照不同类型,每个数组元素占有几个连续的内存单元(存储单位)。 一个数组元素的首地址也是指它所占有的几个内存单元的首地址。数组的指针数组的起始地址;数组的指针变量存储数组起始地址的变量。1、一维数组与指针定义一个指针,将数组名或第一个元素的地址赋予它。就可以用指针访问该数组的任意一个元素。例:char a5; char *pa; pa=a;/数组名与&a0都是指该数组的首地址地址数组名变量指针35Ha00x23pa36Ha10x32pa+137Ha20x98pa+238Ha30x46pa+339Ha40x51pa+4pa,a,&a0均指向同一单元,它们是数组a的首地址
28、,也是0 号元素a0的首地址。pa+1,a+1,&a1均指向1号元素a1。类推可知pa+i,a+i,&ai都指向i号元素ai。应该说明的是pa是变量,而a,&ai都是常量。引用:b=*(pa+3);/数组的第4个元素则引用的是a3=0x46。注意,如果定义成整型(int)变量,数组的每一个元素占两个字节,指针变量加1时,表示加一个存储单元,即2个字节。其他类型也一样。2、二维数组指针变量的定义及引用1)二维数组查找的基本思路在前面已经介绍过二维数组的存储规律, 语言允许把一个二维数组按行分解为多个一维数组来处理。则一行为一个一维数组,如图所示。第1列第2列第3列第4列第5列第1行a00a01a
29、02a03a04第2行a10a11a12a13a14第3行a20a21a22a23a24第4行a30a31a32a33a34对于一个二维数组,只要知道了每行的元素个数(该数组的列数),和该数据在那一行,就能够很方便的找到数组中的每一个元素。如果不知道列数,就无法查找。所以定义数组时行数可以为空。如x10是可以的,而x10是编译不过去的。知道了多维数组得规律,就较容易理解存储方法与查找方法。例如定义一个数组为a45,要找数组中a23元素,每行5个元素,在第3行第4列 (注意数组行列标号是从0开始) ,该元素的位置=总列数行数列数+1=52+(3+1)=14 2)数组指针变量的定义在二维数组中,定
30、义的指针变量是一个复合指针的概念,也就是大指针套小指针的一个指针组,类似与双重循环,外循环为行,内循环为列。即按行排列的指针序列为大指针,每个大指针里面又按列包含了小指针,如图所示。二维数值指针变量的定义,数据类型,存储类型与一般指针定义是相同的,不同的部分如下: (*ap)n从形式上看,它是一个指针数组。n:是数组的列数,前面已经介绍过它的作用。ap:是整个数组的首地址,也就是大指针;ap1:表示加1个大存储单位长度,由于二维数组存储时,是按行存储,列数n就是一个大存储单位长度。小指针:每一行的首地址作为一个小指针。找到每一行的小指针(该行的首地址)后,再按列找该元素的地址。小存储单位:每个元素占得存储单元。(顺便讲一下,在Cx51中,没有指针数组。)3)引用: b=*(*(ap+i)+j);数组元素指针变量a00*apna01*(ap+0)+1a0n-1*(ap+0)+(n-1)a10*(ap+1)a11*(ap+1)+1a1n-1*(ap+0)+(n-1) ai0*(ap+i)ai1*(ap+i)+1ain-1*(ap+i)+(n-1)am-10*(ap+m-1)am-11*(ap+m-1)+1am-1n-1*(ap+m-1)+(n-1) 其中i为行号,就是大存储单位,j为列号,也就是小存储单位。地址计算为: (in)+(j+1)*
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 企业管理-报表管理制度
- 江苏省高邮市重点名校2025-2026学年初三第一次阶段考试数学试题含解析
- 湖南省汨罗市弼时片区市级名校2026年初三下学期期末考试(二模)数学试题含解析
- 江西南昌市心远中学度2025-2026学年初三5月月考(数学试题文)试题含解析
- 扬州地区部分县2026届初三暑假末结业考试数学试题含解析
- 江西省赣州市南康区唐西片区2026届初三下学期第二次大联考物理试题含解析
- 娄底市重点中学2026届初三下学期第一次诊断性考试物理试题试卷含解析
- 2026年朔州市重点中学初三七校联合体考前冲刺交流考试物理试题含解析
- 艾灸护理安全注意事项
- 老年患者压疮护理的伦理问题
- 2026广东深圳医学科学院科研职能岗位招聘笔试备考试题及答案解析
- 山东大众报业集团有限公司招聘笔试题库2026
- 2026年国网江苏省电力有限公司高校毕业生招聘约825人(第二批)笔试模拟试题及答案解析
- 2026上半年新疆维吾尔自治区招聘事业单位工作人员分类考试4474人笔试备考题库及答案解析
- GB/T 20151-2026光度学CIE物理光度系统
- GB/T 18570.9-2025涂覆涂料前钢材表面处理表面清洁度的评定试验第9部分:水溶性盐的现场电导率测定法
- 高中实验室安全教育课件
- 2026年甘肃省交通运输厅所属事业单位招聘笔试易考易错模拟试题(共500题)试卷后附参考答案
- 电信公司客户服务部门员工绩效考评表
- 安徽合肥市人力资源服务有限公司招聘笔试题库2026
- GB/T 1883.1-2025往复式内燃机词汇第1部分:发动机设计和运行术语
评论
0/150
提交评论