15第十五课 C51数组的使用.docx
- 文档编号:7030591
- 上传时间:2023-01-16
- 格式:DOCX
- 页数:8
- 大小:19.04KB
15第十五课 C51数组的使用.docx
《15第十五课 C51数组的使用.docx》由会员分享,可在线阅读,更多相关《15第十五课 C51数组的使用.docx(8页珍藏版)》请在冰豆网上搜索。
15第十五课C51数组的使用
第十五课C51数组的使用
前面的文章中,都是介绍单个数据变量的使用,在“走马灯”等的例子中略有使用到数组,不难看出,数组不过就是同一类型变量的有序集合。
形象的能这样去理解,就像一个学校在操场上排队,每一个级代表一个数据类型,每一个班级为一个数组,每一个学生就是数组中的一个数据。
数据中的每个数据都能用唯一的下标来确定其位置,下标能是一维或多维的。
就如在学校的方队中要找一个学生,这个学生在I年级H班X组Y号的,那么能把这个学生看做在I类型的H数组中(X,Y)下标位置中。
数组和普通变量一样,要
求先定义了才能使用,下面是定义一维或多维数组的方式:
数据类型
数组名
[常量表达式];
数据类型
数组名
[常量表达式1]......[常量表达式N];
“数据类型”是指数组中的各数据单元的类型,每个数组中的数据单元只能是同一数据
类型。
“数组名”是整个数组的标识,命名方法和变量命名方法是一样的。
在编译时系统会根据数组大小和类型为变量分配空间,数组名能说就是所分配空间的首地址的标识。
“常量表达式”是表示数组的长度和维数,它必须用“[]”括起,括号里的数不能是变量只能是常量。
unsignedintxcount[10];//定义无符号整形数组,有10个数据单元
charinputstring[5];//定义字符形数组,有5个数据单元
floatoutnum[10],[10];//定义浮点型数组,有100个数据单元
在C语言中数组的下标是从0开始的而不是从1开始,如一个具有10个数据单元的数
组count,它的下标就是从count[0]到count[9],引用单个元素就是数组名加下标,如count[1]就是引用count数组中的第2个元素,如果错用了count[10]就会有错误出现了。
还有一点要注意的就是在程序中只能逐个引用数组中的元素,不能一次引用整个数组,但是字符型的数组就能一次引用整个数组。
数组也是能赋初值的。
在上面介绍的定义方式只适用于定义在内存DATA存储器使用的内存,有的时候我们需要把一些数据表存放在数组中,通常这些数据是不用在程序中改变数值的,这个时候就要把这些数据在程序编写时就赋给数组变量。
因为51芯片的片内RAM很有限,通常会把RAM分给参与运算的变量或数组,而那些程序中不变数据则应存放在片内的CODE存储区,以节省宝贵的RAM。
赋初值的方式如下:
数据类型[存储器类型]数组名[常量表达式]={常量表达式};
数据类型[存储器类型]数组名[常量表达式1]......[常量表达式N]={{常量表达式}...{常量表达式N}};
在定义并为数组赋初值时,开始学习的朋友一般会搞错初值个数和数组长度的关系,而致使编译出错。
初值个数必须小于或等于数组长度,不指定数组长度则会在编译时由实际的初值个数自动设置。
unsignedcharLEDNUM[2]={12,35};//一维数组赋初值
intKey[2][3]={{1,2,4},{2,2,1}};//二维数组赋初值
unsignedcharIOStr[]={3,5,2,5,3};//没有指定数组长度,编译器自动设置
unsignedcharcodeskydata[]={0x02,0x34,0x22,0x32,0x21,0x12};//数据保存在code区
下面的一个简单例子是对数组中的数据进行排序,使用的是冒泡法,一来了解数组的使用,二来掌握基本的排序算法。
冒泡排序算法是一种基本的排序算法,它每次顺序取数组中的两个数,并按需要按其大小排列,在下一次循环中则取下一次的一个数和数组中下一个数进行排序,直到数组中的数据全部排序完成。
#include
#include
voidtaxisfun(inttaxis2[])
{
unsignedcharTempCycA,TempCycB,Temp;
for(TempCycA=0;TempCycA<=8;TempCycA++)
for(TempCycB=0;TempCycB<=8-TempCycA;TempCycB++)
{//TempCycB<8-TempCycA比用TempCycB<=8少用很多循环
if(taxis2[TempCycB+1]>taxis2[TempCycB])//当后一个数大于前一个数
{
Temp=taxis2[TempCycB];//前后2数交换
taxis2[TempCycB]=taxis2[TempCycB+1];
taxis2[TempCycB+1]=Temp;//因函数参数是数组名调用形
参的变动影响实参
}
}
}
voidmain(void)
{
inttaxis[]={113,5,22,12,32,233,1,21,129,3};
charText1[]={"sourcedata:
"};//"源数据"
charText2[]={"sorteddata:
"};//"排序后数据"
unsignedcharTempCyc;
SCON=0x50;//串行口方式1,允许接收
TMOD=0x20;//定时器1定时方式2
TCON=0x40;//设定时器1开始计数
TH1=0xE8;//11.0592MHz1200波特率
TL1=0xE8;TI=1;
TR1=1;//启动定时器
printf("%s\n",Text1);//字符数组的整体引用
for(TempCyc=0;TempCyc<10;TempCyc++)
printf("%d",taxis[TempCyc]);
printf("\n----------\n");
taxisfun(taxis);//以实际参数数组名taxis做参数被函数调用
printf("%s\n",Text2);
for(TempCyc=0;TempCyc<10;TempCyc++)//调用后taxis会被改变
printf("%d",taxis[TempCyc]);
while
(1);
}
例子中能看出,数组同样能作为函数的参数进行传递。
数组做参数时是用数组名进
行传递的,一个数组的数组名表示该数组的首地址,在用数组名作为函数的调用参数时,它的传递方式是采用了地址传递,就是将实际参数数组的首地址传递给函数中的形式参数数组,这个时候实际参数数组和形式参数数组实际上是使用了同一段内存单元,当形式参数数组在函数体中改变了元素的值,同时也会影响到实际参数数组,因为它们是存放在同一个地址的。
上面的例子同时还使用到字符数组。
字符数组中每一个数据都是一个字符,这样一个一维的字符数组就组成了一个字符串,在C语言中字符串是以字符数组来表达处理的。
为了能测定字符串的长度,C语言中规定以‘\o’来做为字符串的结束标识,编译时会自动在字符串的最后加入一个‘\o’,那么要注意的是如果用一个数组要保存一个长度为10字节的字符串则要求这个数组至少能保存11个元素。
‘\o’是转义字符,它的含义是空字符,它的ASCII码为00H,也就是说当每一个字符串都是以数据00H结束的,在程序中操作字符数据组时要注意这一点。
字符数组除了能对数组中单个元素进行访问,还能访问整个数组,其实整个访问字符数组就是把数组名传到函数中,数组名是一个指向数据存放空间的地址指针,函数根据这个指针和‘/o’就能完整的操作这个字符数组。
对于这一段所说的,能参看下面一例1602LCD显示模块的驱动演示例子进行理解。
这里要注意就是能用单个字
符数组元素来进行运算,但不能用整个数组来做运算,因为数组名是指针而不是数据。
/*============================================================
使用1602液晶显示的实验例子明浩2004/2/27
==============================================================
SMC1602A(16*2)模拟口线接线方式连接线图:
---------------------------------------------------
|LCM-----51|LCM-----51|LCM------51|
---------------------------------------------|
|DB0-----P1.0|DB4-----P1.4|RW-------P2.0|
|DB1-----P1.1|DB5-----P1.5|RS-------P2.1|
|DB2-----P1.2|DB6-----P1.6|E--------P2.2|
|DB3-----P1.3|DB7-----P1.7|VLCD接1K电阻到GND|
---------------------------------------------------
[注:
AT89S51使用12M晶体震荡器]
=============================================================*/
#defineLCM_RWP2_0//定义引脚
#defineLCM_RSP2_1
#defineLCM_EP2_2
#defineLCM_DataP1
#defineBusy0x80//用于检测LCM状态字中的Busy标识
#include
voidWriteDataLCM(unsignedcharWDLCM);
voidWriteCommandLCM(unsignedcharWCLCM,BuysC);
unsignedcharReadDataLCM(void);unsignedcharReadStatusLCM(void);voidLCMInit(void);
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData);
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData);
voidDelay5Ms(void);
voidDelay400Ms(void);
unsignedcharcodecdle_net[]={""};
unsignedcharcodeemail[]={"pnzwzw@"};
voidmain(void)
{
Delay400Ms();//启动等待,等LCM讲入工作状态
LCMInit();//LCM初始化
Delay5Ms();//延时片刻(可不要)
DisplayListChar(0,0,cdle_net);DisplayListChar(0,1,email);ReadDataLCM();//测试用句无意义while
(1);
}
//写数据
voidWriteDataLCM(unsignedcharWDLCM)
{
ReadStatusLCM();//检测忙LCM_Data=WDLCM;LCM_RS=1;
LCM_RW=0;
LCM_E=0;//若晶体震荡器速度太高能在这后加小的延时
LCM_E=0;//延时
LCM_E=1;
}
//写指令
voidWriteCommandLCM(unsignedcharWCLCM,BuysC)//BuysC为0时忽略忙检测
{
if(BuysC)ReadStatusLCM();//根据需要检测忙
LCM_Data=WCLCM;LCM_RS=0;LCM_RW=0;
LCM_E=0;
LCM_E=0;LCM_E=1;
}
//读数据
unsignedcharReadDataLCM(void)
{
LCM_RS=1;LCM_RW=1;LCM_E=0;LCM_E=0;LCM_E=1;return(LCM_Data);
}
//读状态
unsignedcharReadStatusLCM(void)
{
LCM_Data=0xFF;LCM_RS=0;LCM_RW=1;LCM_E=0;LCM_E=0;LCM_E=1;
while(LCM_Data&Busy);//检测忙信号
return(LCM_Data);
}
voidLCMInit(void)//LCM初始化
{
LCM_Data=0;
WriteCommandLCM(0x38,0);//三次显示模式设置,不检测忙信号
Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();WriteCommandLCM(0x38,0);Delay5Ms();
WriteCommandLCM(0x38,1);//显示模式设置,开始要求每次检测忙信号
WriteCommandLCM(0x08,1);//关闭显示WriteCommandLCM(0x01,1);//显示清屏WriteCommandLCM(0x06,1);//显示光标移动设置WriteCommandLCM(0x0C,1);//显示开及光标设置
}
//按指定位置显示一个字符
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData)
{
Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
if(Y)X|=0x40;//当要显示第二行时地址码+0x40;X|=0x80;//算出指令码
WriteCommandLCM(X,0);//这里不检测忙信号,发送地址码
WriteDataLCM(DData);
}
//按指定位置显示一串字符
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData)
{
unsignedcharListLength;
ListLength=0;Y&=0x1;
X&=0xF;//限制X不能大于15,Y不能大于1
while(DData[ListLength]>0x20)//若到达字串尾则退出
{
if(X<=0xF)//X坐标应小于0xF
{
DisplayOneChar(X,Y,DData[ListLength]);//显示单个字符
ListLength++;X++;
}
}
}
//5ms延时
voidDelay5Ms(void)
{
unsignedintTempCyc=5552;
while(TempCyc--);
}
//400ms延时
voidDelay400Ms(void)
{
unsignedcharTempCycA=5;unsignedintTempCycB;while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
};
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 15第十五课 C51数组的使用 15 第十五 C51 数组 使用