电子教案·《单片机接口技术(C51版)》课件_第1页
电子教案·《单片机接口技术(C51版)》课件_第2页
电子教案·《单片机接口技术(C51版)》课件_第3页
电子教案·《单片机接口技术(C51版)》课件_第4页
电子教案·《单片机接口技术(C51版)》课件_第5页
已阅读5页,还剩572页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、21世纪高等学校精品教材单片机接口技术(C51版) 张道德 编著 杨光友 主审中国水利水电出版社单片机接口技术(C51版)第一章 C51基本语法内容概述数据类型和运算符、表达式是是C51语言程序设计的最基础知识,C51语言把数据分成了多种数据类型,并提供了丰富的运算对数据进行处理。本章对C51语言的基本数据类型、常量变量、运算符及表达式等进行详细介绍。教学目标1掌握数据类型的概念,了解C51语言能够处理的数据类型。2掌握常量的概念,掌握各种类型常量的特点及表示形式。3掌握变量的概念,了解int、float、char型变量的特点,掌握这三种类型变量的定义、赋值和使用方法。理解C51中变量的存储和

2、编译模式的关系,掌握单片机片内资源的访问方法。4了解C51语言的基本运算符及其特点,掌握运算符的优先级和结合性的概念。5了解算术运算表达式、关系表达式及逻辑表达式的特点,熟练进行表达式计算,能熟练进行实际问题的表达式描述。6熟悉自增、自减运算的特点,掌握赋值运算,了解逗号运算符和逗号表达式。7掌握数据类型转换的概念,能进行基本的数据类型转换。11 C51基本数据类型具有一定格式的数字或数值叫做数据,数据的不同格式叫作数据类型。任何程序设计都离不开数据的处理。 C5l的数据类型有位型(bit)、无符号字符(unsigned char)、有符号字符(signed char)、无符号整型(unsig

3、ned int)、有符号整型(signed int)、无符号长型(unsigned long)、有符号长型(signed long)、浮点(float)和指针类型等。其中short与long属整型数据、 float与 double型属浮点型数据。 数据类型长 度值 域 范 围bit1 bit0,1sbit1 bit0,1unsigned char1 byte0255signed char1 byte-128127sfr1 byte0255unsigned int2 byte065536signed int2 byte-3276832767sfr162 byte065536*13 byte对象的

4、地址unsigned long4 byte04294967295signed long4 byte-21474836482147483647float4 byte+1.175494E-38+3.402823E+38当程序中出现表达式或变量赋值运算时,若运算对象的数据类型不一致,数据类型可以自动进行转换,转换按以下优先级别自动进行:bit char int long floatunsigned signed12 常量与变量121 常量在程序运行中其值不能改变的量称为常量。 1整型常量。可以表示为十进制如123,0,-8等。十六进制则以0 x开头如0 x34。长整型就在数字后面加字母L,如10L,

5、 0 xF340L等。2浮点型常量。分为十进制和指数表示形式。十进制由数字和小数点组成,如0.888,3345.345,0.0等,整数或小数部分为0时可以省略0但必须有小数点。指数表示形式为: 数字.数字e数字 中的内容为可选项,其中内容根据具体情况可有可无,但其余部分必须有,如123e3,5e6,-1.0e-3。而e3,5e4.0则是非法的表示形式。3字符型常量是单引号内的字符,如a,d等。4字符串型常量由双引号内的字符组成,如 hello,english等。当引号内的没有字符时,为空字符串。用标识符代表的常量称为符号常量。例如:在指令“ #define PI 3.1415926”后,符号常

6、量PI即代表圆周率3.1415926。1.2.2 变量1.2.2.1变量类型在程序运行中,其值可以改变的量称为变量一个变量主要由两部分构成:一个是变量名,一个是变量值。每个变量都有一个变量名,在内存中占据一定的存储单元(地址),并在该内存单元中存放该变量的值。C51支持的变量通常有如下类型:位变量(bit)位变量的值可以是1(true)或0(false)。与805l硬件特性操作有关的位变量必须定位在8051CPU片内存储区(RAM)的可位寻址空间中。 字符变量(char)字符变量的长度为l byte,即8位。C51编译器默认的字符型变量为无符号型(unsigned char)。负数在计算机中存

7、储时一般用补码表示。 整型变量(int)整型变量的长度为16位。8051系列CPU将整型变量的msb存放在低地址字节。有符号整型变量(signed int)也使用msb位作为标志位,并使用二进制的补码表示数值。 长整型变量(1ong int)长整型变量占用4个字节(byte),其它方面与整型变量(int)相似。浮点型变量(float)浮点型变量占4个字节(byte),许多复杂的数学表达式都采用浮点变量数据类型。它用符号位表示数的符号,用阶码和尾数表示数的大小。用它们进行任何数学运算都需要使用由编译器决定的各种不同效率等级的库函数。(补充存储格式) 在编程时,为了书写方便,经常使用简化的缩写形式

8、来定义变量的数据类型。其方法是在源程序开头使用#define语句。例如: #define uchar unsigned char #define uint unsigned int 1.2.2.2变量的存储变量的存储器类型是指该变量在8051单片机硬件系统中所使用的存储区域,并在编译时准确的定位。8051系列单片机将程序存储器(ROM)和数据存储器(RAM)分开,并各有各自的寻址机构和寻址方式。8051系列单片机在物理上有四个存储空间: *片内程序存储器空间; *片外程序存储器空间, *片内数据存储器空间; *片外数据存储器空间KEIL uVision2所能支持的存储器类型: 存储器类型说 明

9、data直接访问内部数据存储器(128字节),访问速度最快bdata可位寻址内部数据存储器(16字节),允许位与字节混合访问idata间接访问内部数据存储器(256字节),允许访问全部256B地址pdata分页访问外部数据存储器(256字节),用MOVX Ri指令访问xdata外部数据存储器(64KB),用MOVX DPTR指令访问code程序存储器(64KB),用MOVC A+DPTR指令访问注意的是在AT89C51芯片中RAM只有低128位,位于80H到FFH的高128位则在52芯片中才有用,并和特殊寄存器地址重叠。定义变量时如果省略存储器类型,系统则会按编译模式SMALL、COMPACT

10、或LARGE所规定的默认存储器类型去指定变量的存储区域。无论什么存储模式都可以声明变量在任何的8051存储区范围,然而把最常用的变量、命令放在内部数据区可以显著的提高系统性能。 C51支持的主要编译模式 存储模式说 明SMALL 函数参数及局部变量放在片内RAM(默认变量类型为DATA,最大128字节)。另外所有对象包括栈都优先放置于片内RAM,当片内RAM用满,再向片外RAM放置。 COMPACT 参数及局部变量放在片外RAM(默认的存储类型是PDATA,最大256字节);通过R0、R1间接寻址,栈位于8051片内RAM。LARGE 参数及局部变量直接放入片外RAM(默认的存储类型是XDAT

11、A,最大64KB);使用数据指针DPTR间接寻址。因此访问效率较低且直接影响代码长度1.2. 3 8051片内资源及位变量1.2.3.1 特殊功能寄存器的C51定义8051单片机的内部高128个字节为专用寄存器区,其中51子系列有21个(52子系列有26个)特殊功能寄存器(SFR),它们离散的分布在这个区中,分别用于CPU并行口、串行口、中断系统、定时/计数器等功能单元及控制和状态寄存器。 对SFR的操作,只能采用直接寻址方式。为了能直接访问这些特殊功能寄存器,Keil C51扩充了两个关键字“sfr”、“sfr16”,可以直接对51单片机的特殊寄存器进行定义,这种定义方法与标准C51语言不兼

12、容,只适用于对8051系列单片机C51编程。定义方法如下:sfr 特殊功能寄存器名= 特殊功能寄存器地址常数;sfr16 特殊功能寄存器名= 特殊功能寄存器地址常数;对于8051片内I/O口,定义方法如下:sfr P1 = 0 x90; /定义P1口,地址90Hsfr P2 = 0 xA0; /定义P1口,地址A0Hsfr后面是一个要定义的名字,要符合标识符的命名规则,名字最好有一定的含义 等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H-FFH)。sfr是定义8位的特殊功能寄存器, sfr16用来定义16位特殊功能寄存器,如8052的T2定时

13、器,可以定义为: sfr16 T2 = 0 xCC; /这里定义8052定时器2,地址为T2L=CCH,T2H=CDH用sfr16定义16位特殊功能寄存器时,等号后面是它的低位地址,高位地址一定要位于物理低位地址之上。注意的是,sfr16不能用于定时器0和1的定义。对于需要单独访问SFR中的位,C51的扩充关键字sbit可以访问位寻址对象。sbit定义某些持殊位,并接受任何符号名,“=”号后将绝对地址赋给变量名这种地址分配,有三种方法:1)sbit 位变量名位地址sbit P1_1 = Ox91;这样是把位的绝对地址赋给位变量。同sfr一样,sbit的位地址必须位于80HFFH之间。2)Sbi

14、t 位变量名特殊功能寄存器名位位置sfr P3 = 0 xB0;sbit P3_1 = P3 1; /先定义一个特殊功能寄存器名,再指定位变量名所在的位置。当可寻址位位于特殊功能寄存器中时可采用这种方法。3)sbit 位变量名字节地址位位置sbit P3_1 = 0 xB0 1;1.2.3.2 位寻址区及位变量定义C51提供一个bdata的存储器类型,用于访问单片机的可位寻址区的数据 如:unsigned char bdata age; /在位寻址区定义ucsigned char类型的变量ageint bdata score2; /在可位寻址区定义数组score2sbit flag=age7

15、/用关键字sbit定义位变量来独立访问可寻址位对象的其中一位C51提供关键字“bit”实现位变量的定义及访问。bit flag; / 将flag定义为位变量bit valve_state; / 将valve_state定义为位变量通常C51编译器会将位变量分配在位寻址区的某一位。定义位变量时应注意以下问题1)位变量不能定义成一个指针,如不能定义:bit * POINTER。2) 不能定义位数组,如不能定义: bit array2。3) bit与sbit的不同。bit不能指定位变量的绝对地址,当需要指定位变量的绝对地址(范围必须在0 x80-0 xff)时,需要使用sbit来定义。例:sbit

16、flag=P10;也可使用sbit访问可位寻址对象的位。bdata char jj ; * jj定义为bdata整型变量*int bdata sum2; /*在可位寻址区定义数组sum2,也称为可寻址位对象*/ sbit mybit7=jj7; *mybit7 定义为jj的第7位*/ sbit score12=sum112; * score12定义为sum1的第12位*/ 可位寻址对象也可以字节寻址。例: jj=0; *jj赋值为0*sbit定义要求基址对象的存储类型为bdata,否则只有绝对的特殊位定义(sbit)是合法的。位置(操作符)后的最大值依赖于指定的访问对象型,对于char、uch

17、ar而言是0-7,对于int、uint而言是015。sbit定义要求基址对象的存储类型为bdata,否则只有绝对的特殊位定义(sbit)是合法的。位置(操作符)后的最大值依赖于指定的访问对象型,对于char、uchar而言是0-7,对于int、uint而言是015。1.3 自定义变量类型typedef通常定义变量的数据类型时都是使用标准的关键字,方便别人阅读程序。但使用typedef可以有方便程序的移植和简化较长的数据类型定义 例如:程序设计者对变量的定义习惯了DELPHI的关键字,如整型数据习惯用关键字integer来定义,在用C51时还想用integer的话,你可以这样写:typedef

18、int integer;integer a,b;1.4 运算符与表达式1.4.1赋值运算利用赋值运算符将一个变量与一个表达式连接起来的式子为赋值表达式,在表达式后面加“;”便构成了赋值语句。使用=的赋值语句格式如下:变量 = 表达式;例如:a = 0 x10; /将常数十六进制数10赋于变量ab = c = 2; /同时将2赋值给变量b,cd = e; /将变量e的值赋于变量df = d-e; /将变量d-e的值赋于变量f赋值语句的意义就是先计算出=右边的表达式的值,然后将得到的值赋给左边的变量。而且右边的表达式可以是一个赋值表达式。1.4.2算术运算1.4.2.1 算术运算符及算术表达式C5

19、1中的算术运算符有如下几个,其中只有取正值和取负值运算符是单目运算符,其它则都是双目运算符:十 (加法运算符,或正值符号) - (减法运算符,或负值符号) * (乘法运算符)/ (除法运算将) (模(求余)运算符。例如5%3结果是5除以3所得的余数2) 用算术运算符和括号将运算对象连接起来的式子称为算术表达式。运算对象包括常量、变量、函数、数组、结构体等等。算术表达式的形式:表达式1算术运算符表达式2例如:a+b, (x+4)/(y-b),y-sin(x)/21.4.2.2 算术运算的优先级与结合性算术运算符的优先级规定为:先乘除模,后加减,括号最优先。乘、除、模运算符的优先级相同,并高于加减

20、运算符。括号中的内容优先级最高。 a+b*c; / 乘号的优先级高于加号,故先运算b*c,所得的结果再与a相加 (a+b)*(c-d)-6; / 括号的优先级最高,*次之,减号优先级最低故先运算(a+b)和(c-d),/ 然后将二者的结果相乘,最后再与6相减算术运算的结合性规定为自左至右方向,称为“左结合性”。即当一个运算对象两边的算术运算符优先级相同时,运算对象先与左面的运算符结合。 a+b-c; / b两边是“+”、“-”运算符优先级相同,按左结合性优先执行a+b再减C 1.4.2.3 数据类型转换运算当运算符的两侧的数据类型不同时必须通过数据类型转换将数据转换成同种类型。 转换的方式有两

21、种:自动类型转换和强制类型转换。自动类型转换由C51编译器编译时自动进行。如图1-4-1所示为自动数据类型转换规则。 charintlongfloatdoubleunsigned signed低 高图1-4-1数据类型转换规则强制类型转换需要使用强制类型转换运算符,其格式为:(类型名) (表达式);例如:(double)xx / 将xx强制转换成double类型。(int)(a+b) / 将a+b的值强制转换成int类型。使用强制转换类型运算符后,运算结果被强制转换成规定的类型。例如:unsigned char x,y;unsigned char z;z (unsigned char)(x*y

22、);1.4.3关系运算1.4.3.1关系运算符 (小于) (大于) (小于或等于) (大于或等于) (等于) ! (不等于) 关系运算符同样有着优先级别。前四个具有相同的优先级,后两个也具有相同的优先级,但是前四个的优先级要高于后两个。关系运算符的结合性为左结合。1.4.3.2 关系表达式关系表达式就是用关系运算符连接起来两个表达式。关系表达式通常是用来判别某个条件是否满足。要注意的是用关系运算符的运算结果只有0和1两种,也就是逻辑的真与假,当指定的条件满足时结果为1,不满足时结果为0。关系表达式结构如下:表达式1关系运算符表达式2例如: ab; /若a大于b,则表达式值为1(真)b+ca;

23、/若a=3,b=4,c=5, 则表达式值为0(假)(ab)c; /若a=3,b=2,c=1, 则表达式值为1(真)。因为ab值为1,等于c值c5ab;/若a=3,b=2,c=1, 则表达式值为0(假)。1.4.4逻辑运算关系运算符反映两个表达式之间的大小等于关系,逻辑运算符则用于求条件式的逻辑值,用逻辑运算符将关系表达式或逻辑量连接起来就是逻辑表达式了。C51提供三种逻辑运算:逻辑与(&)逻辑或( | | ) 逻辑非( ! ) 逻辑表达式的一般形式为:逻辑与:条件式1 & 条件式2逻辑或:条件式1 | | 条件式2逻辑非: ! 条件式逻辑表达式的结合性为自左向右。逻辑表达式的值应该是一个逻辑值

24、“真”或“假”, 以0代表假,以1代表真。逻辑表达式:用逻辑运算符将关系表达式或逻辑量连接起来的式子称为逻辑表达式。逻辑表达式的运算结果不是0就是1,不可能是其它值。C51逻辑运算符与算术运算符、关系运算符、赋值运算符之间优先级的次序如图1-3-2所示。!(非)算术运算符关系运算符&和| |赋值运算符 高 低 优 先 级图1-3-2运算符的优先级1.4.5 位运算C51语言直接面对8051单片机,对于8051单片机强大灵活的位处理能力也提供了位操作指令。C51中共有6种位运算符:& 按位与| 按位或 按位异或 按位取反 位右移位运算符的作用是按位对变量进行运算,但是并不改变参与运算的变量的值。

25、如果要求按位改变变量的值,则要利用相应的赋值运算。应当注意的是位运算符不能对浮点型数据进行操作。按位与、或、异或的真值表如表1-4-1所示。表1-4-1 与、或、异或位操作真值表XYX&YX|YXY00000010111001111110位运算一般的表达形式如下:变量1 位运算符 变量2位运算符也有优先级。从高到低依次是: |(按位或)(按位异或)&(按位与)(右移)=右移位赋值-=减法赋值 &=逻辑与赋值*=乘法赋值|= 逻辑或赋值/= 除法赋值 = 逻辑异或赋值%=取模赋值 =逻辑非赋值b)?a : b1.4.8逗号运算符可以用它将两个或多个表达式连接起来,形成逗号表达式。逗号表达式的一般

26、形式为:表达式1,表达式2,表达式3表达式n这样用逗号运算符组成的表达式在程序运行时,是从左到右计算出各个表达式的值,而整个用逗号运算符组成的表达式的值等于最右边表达式的值,就是“表达式n”的值。在实际的应用中,大部分情况下,使用逗号表达式的目的只是为了分别得到名个表达式的值,而并不一定要得到和使用整个逗号表达式的值。并不是在程序的任何位置出现的逗号,都可以认为是逗号运算符。如函数中的参数,参数之间的逗号只是用来间隔之用而不是逗号运算符。单片机接口技术(C51版)第二章 C51基本结构程序设计教学目标1 掌握if语句来实现选择结构,能利用if语句编写相应的分枝结构的程序。在嵌套if语句中,一定

27、要搞清楚else与哪个if结合的问题。2掌握switch语句来实现多向分枝选择结构,能利用switch语句编写相应的分枝结构的程序。 3. 掌握循环语句的即初始化、循环体、循环控制及结束四个部分,并能进行循环语句的程序设计。分别掌握for 语句、while语句以及do-while语句的使用语法及方法,能利用这三种循环结构进行循环程序设计,理解这三种语句的异同。4理解并掌握continue、break语句在循环结构和选择结构中的作用。对于goto语句,理解该语句优缺点。概述C51语言是结构化编程语言。结构化语言的基本元素是模块,它是程序的一部分只有一个出口和一个入口不允许有偶然的中途插入或以模块

28、的其它路径退出。结构化编程语言在没有妥善保护或恢复堆栈和其它相关的寄存器之前,不应随便跳入或跳出一个模块。因此使用这种结构化语言进行编程,当要退出中断时,堆栈不会因为程序使用了任何可以接受的命令而崩溃。 结构化程序由若干模块组成,每个模块中包含着若干个基本结构,而每个基本结构中可以有若干条语句。归纳起来,C51程序有顺序结构、选择结构、循环结构共三种结构。21 顺序结构顺序结构是一种最基本最简单的编程结构。在这种结构中,程序由低地址向高地址顺序执行指令代码。如图2-1-1所示,程序先执行A操作,再执行B操作,两者是顺序执行的关系。结束A开始图2-1-1 顺序结构流程图B22 选择结构在选择结构

29、中,程序首先对一个条件语句进行测试。当条件为“真”(True)时,执行一个方向上的程序流程;当条件为“假”(False)时,执行另一个方向上的程序流程。 条件满足?AYN条件满足?ABNYK=?A0A1An(a)(c)(b)图2-2-1 分支程序结构流程图K=0 K=1 k=n 分支程序有三种基本形式 2.2.1 if语句C51语言的if语句有三种基本形式。1.第一种形式为基本形式if(表达式) 语句 其语义是:如果表达式的值为真,则执行其后的语句, 否则不执行该语句,其过程可表示为图2-2-1(a)。例2-2-1 输入两个整数,输出其中的大数。void main()int a,b,max;p

30、rintf(n input two numbers: );scanf(%d%d,&a,&b);max=a;if (maxb) printf(max=%dn,a);else printf(max=%dn,b);3.第三种形式为if-else-if形式前二种形式的if语句一般都用于两个分支的情况。 当有多个分支选择时,可采用if-else-if语句,其一般形式为: if(表达式1) 语句1; else if(表达式2) 语句2; else if(表达式3) 语句3; else if(表达式m) 语句m; else 语句n; 其语义是:依次判断表达式的值,当出现某个值为真时, 则执行其对应的语句。然

31、后跳到整个if语句之外继续执行程序。 如果所有的表达式均为假,则执行语句n 。然后继续执行后续程序。 例2-2-3 要求判别键盘输入字符的类别。#includestdio.hvoid main() char c; printf(input a character: ); c=getchar(); if(c=0&c=A&c=a&cb)a+;b+;elsea=0;b=10;5 if语句的嵌套当if语句中的执行语句又是if语句时,则构成了if 语句嵌套的情形。其一般形式可表示如下: if(表达式) if语句; 或者为if(表达式) if语句; else if语句; 在嵌套内的if语句可能又是if-e

32、lse型的,这将会出现多个if和多个else重叠的情况,这时要特别注意if和else的配对问题。 例如:if(表达式1) if(表达式2) 语句1; else 语句2;其中的else究竟是与哪一个if配对呢?为了避免这种二义性,C51语言规定,else 总是与它前面最近的if配对。2.2.2 switch-case语句 C51语言还提供了另一种用于多分支选择的switch语句, 其一般形式为: switch(表达式) case常量表达式1: 语句1; case常量表达式2: 语句2; case常量表达式n: 语句n; default : 语句n+1; 其语义是:计算表达式的值。 并逐个与其后的

33、常量表达式值相比较,当表达式的值与某个常量表达式的值相等时, 即执行其后的语句,然后不再进行判断,继续执行后面所有case后的语句。 如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。其执行流程图如图2-2-1(C)所示。例2-2-4要求输入一个数字,输出一个相应的英文单词。#includestdio.hvoid main() int a; printf(input integer number: ); scanf(“%d”,&a); switch (a) case 1:printf(Mondayn); case 2:printf(Tuesdayn); case

34、 3:printf(Wednesdayn); case 4:printf(Thursdayn); case 5:printf(Fridayn); case 6:printf(Saturdayn); case 7:printf(Sundayn); default:printf(errorn); break 语句C51语言还提供了一种break语句,专用于跳出switch语句,break 语句只有关键字break,没有参数。例 修改例2-2-4题的程序,在每个case语句之后增加break 语句,使每一次执行之后均可跳出switch语句,从而避免输出不应有的结果。Switch结构中的break语句

35、#includestdio.hvoid main() int a; printf(input integer number: ); scanf(“%d”,&a); switch (a) case 1:printf(Mondayn);break; case 2:printf(Tuesdayn);break; case 3:printf(Wednesdayn);break; case 4:printf(Thursdayn);break; case 5:printf(Fridayn);break; case 6:printf(Saturdayn);break; case 7:printf(Sunda

36、yn);break; default:printf(errorn); 在使用switch语句时还应注意以下几点:1)在case后的各常量表达式的值不能相同,否则会出现错误。2)在case后,允许有多个语句,可以不用括起来。3)各case和default子句的先后顺序可以变动,而不会影响程序执行结果。4)default子句可以省略不用。2.3 循环结构程序设计中,常常要求某一段程序重复执行多次,这时可采用循环结构程序。这种结构可大大简化程序,但程序执行的时间并不会减少。循环程序的结构图2-3-1(a)是典型的当型循环结构,控制语句在循环体之前,所以在结束条件已具备的情况下,循环体程序可以一次也不

37、执行,C51提供了while和for语句实现这种循环结构。图2-3-1(b)其控制部分在循环体之后,因此,即使在执行循环体程序之前结束条件已经具备,循环体程序至少还要执行一次 ,因此称为直到型循环结构,C51提供了do-while语句实现这种循环结构。循环程序一般包括如下四个部分:1)初始化:置循环初值,即设置循环开始的状态,比如设置地址指针,设定工作寄存器,设定循环次数等。2)循环体:这是要重复执行的程序段,是循环结构的基本部分。3)循环控制:循环控制包括修改指针、修改控制变量和判断循环是否结束还是继续,修改指针和变量是为下一次循环判断作准备,当符合结束条件时,结束循环;否则,继续循环。4)

38、结束:存放结果或作其他处理。两种常用的控制循环方法在循环程序中,有两种常用的控制循环次数的方法。一种是循环次数已知,这时把循环次数作为循环计算器的初值,当计数器的值加满或减为0时,即结束循环;否则,继续循环。另一种是循环次数未知,这时可根据给定的问题条件来判断是否继续。2.3.1 while语句 while语句的一般形式为: while(表达式) 语句; 其中表达式是循环条件,语句为循环体。 while语句的语义是:计算表达式的值,当值为真(非0)时, 执行循环体语句。其执行过程可用图2-3-1(a)表示。 例2-3-1 统计从键盘输入一行字符的个数。#include void main()i

39、nt n=0;printf(input a string:n);while(getchar()!=n) n+;printf(%d,n);使用while语句应注意以下几点1)while语句中的表达式一般是关系表达或逻辑表达式,只要表达式的值为真(非0)即可继续循环。2)循环体如包括有一个以上的语句,则必须用括起来, 组成复合语句。3)应注意循环条件的选择以避免死循环。2.3.2 do-while语句 do-while语句的一般形式为: do 语句; while(表达式); 其中语句是循环体,表达式是循环条件。 do-while语句的语义是:先执行循环体语句一次, 再判别表达式的值,若为真(非0)

40、则继续循环,否则终止循环。do-while语句和while语句的区别do-while语句和while语句的区别在于do-while是先执行后判断,因此do-while至少要执行一次循环体。而while是先判断后执行,如果条件不满足,则循环体语句一次也不执行。while语句和do-while语句一般都可以相互改写。2.3.3 for语句for语句的一般格式 for(变量赋初值;循环继续条件;循环变量增值) 循环体语句组;执行过程如图2-3-2所示。图2-3-2for语句执行流程图for语句的执行过程1)求解“变量赋初值”表达式1。2)求解“循环继续条件”表达式2。如果其值非0,执行3);否则,转

41、至4)。3)执行循环体语句组,并求解“循环变量增值”表达式3,然后转向2)。4)执行for语句的下一条语句。应当注意的问题1) “变量赋初值”、“循环继续条件”和“循环变量增值”部分均可缺省,甚至全部缺省,但其间的分号不能省略。2)当循环体语句组仅由一条语句构成时,可以不使用复合语句形式;3)“循环变量赋初值”表达式1,既可以是给循环变量赋初值的赋值表达式,也可以是与此无关的其它表达式(如逗号表达式)。4) “循环继续条件”部分是一个逻辑量,除一般的关系(或逻辑)表达式外,也允许是数值(或字符)表达式。应当注意的问题for语句中的各表达式都可省略,但分号间隔符不能少。如:for(;表达式;表达

42、式) 省去了表达式1;for(表达式;表达式) 省去了表达式2;for(表达式;表达式;) 省去了表达式3;for(;) 省去了全部表达式。在循环变量已赋初值时,可省去表达式1。如省去表达式2或表达式3则将造成无限循环, 这时应在循环体内设法结束循环。void main()int a=0,n;printf(n input n: );scanf(%d,&n);for(;n0;) a+;n-;printf(%d ,a*2);2.3.4 循环嵌套(1)循环语句的循环体内,又包含另一个完整的循环结构,称为循环的嵌套。循环嵌套的概念,对所有高级语言都是一样的。(2)for语句和while语句允许嵌套,d

43、o-while语句也不例外。 三种循环(while循环、dowhile循环和for循环)可以互相嵌套。例如,下面几种都是合法的形式:(1) while( ) while( ) (2) do do while( ); while( );(3) for(;) for(; ;) (4) while( ) do while( ); (5) for(; ;) while( ) (6) do for (; ;) while( );2.4 转移语句如果需要改变程序的正常流向, 可以使用本小节介绍的转移语句。C51提供了4种转移语句: goto,break, continue和return。其中的return

44、语句只能出现在被调函数中, 用于返回主调函数, 2.4.1 goto语句 goto语句也称为无条件转移语句, 其一般格式如下: goto 语句标号; 其中语句标号是按标识符规定书写的符号, 放在某一语句行的前面,标号后加冒号(:)。语句标号起标识语句的作用,与goto 语句配合使用。如: label: i+; loop: while(x7); 在结构化程序设计中一般不主张使用goto语句, 以免造成程序流程的混乱, 例2-4-1 统计从键盘输入一行字符的个数。#includestdio.hvoid main()int n=0;printf(input a stringn);loop: if(g

45、etchar()!=n) n+;goto loop;printf(%d,n);2.4.2 循环语句中的break语句break语句只能用在switch 语句或循环语句中, 其作用是跳出switch语句或跳出本层循环,转去执行后面的程序。由于break语句的转移方向是明确的,所以不需要语句标号与之配合。break语句的一般形式为: break; 2.4.3 continue语句 continue语句只能用在循环体中,其一般格式是:continue; 其语义是:结束本次循环,即不再执行循环体中continue 语句之后的语句,转入下一次循环条件的判断与执行。应注意的是,本语句只结束本层本次的循环,

46、并不跳出循环。例2-4-2 输出100以内能被7整除的数。void main()int n;for(n=7;n=100;n+)if (n%7!=0)continue;printf(%d ,n);单片机接口技术(C51版)第三章 数组内容概述数组是一种构造类型的数据,通常用来处理具有相同属性的一批数据。本章主要介绍一维数组、二维数组、多维数组以及字符数组的定义、初始化、引用及应用。教学目标1理解数组的概念,能定义、初始化一维数组,利用一维数组进行简单的程序设计。2能定义、初始化二维数组,利用二维数组进行相关的程序设计。在此基础上理解三维数组以及多维数组的定义与使用方法。3理解字符数组的概念,能定

47、义、初始化字符数组,能利用一维数组进行字符串的处理。C51语言还提供了构造类型的数据,它们有:数组类型、结构体类型、共用体类型。构造类型数据是由基本类型数据按一定规则组成的,因此有的书称它们为“导出类型”。3.1 一维数组3.1.1 一维数组的定义一维数组的定义方式为:类型说明符 数组名常量表达式; 例如:int a10;它表示数组名为a,此数组有10个元素。说明:1) 数组名的定名规则和变量名相同,遵循标识符定名规则;2) 数组名后是用方括弧括起来的常量表达式,不能用圆括弧,下面用法不对:int a(10);3) 常量表达式表示元素的个数,即数组长度。例如,在a10中,10表示a数组有10个

48、元素,下标从0开始,这10个元素是,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9。注意不能使用数组元素a10;(4) 常量表达式中可以包括常量和符号常量,不能包含变量。也就是说,C51不允许对数组的大小作动态定义,即数组的大小不依赖于程序运行过程中变量的值。例如,下面这样定义数组是不行的: int n;scanf(%d,&n);int an;3.1.2一维数组元素的引用 数组必须先定义,后使用。C51语言规定只能逐个引用数组元素而不能一次引用整个数组。 数组元素的表示形式为:数组名下标 下标可以是整型常量或整型表达式。例如: a0=a5+a7-a2*3 例3-1-1 数组元素的引

49、用 #include#includervoid main(void ) int i,a10;#ifndef MONITOR51 /* 需要串口输出时请作如下设置*/ SCON = 0 x50; /* 方式 1, 允许接收 */ TMOD |= 0 x20; /* TMOD:定时器1方式2 */ TH1 = 221; /* 1200bps 16MHz */ TR1 = 1; /* 启动定时器1 */ TI = 1; /*Keil C自带的puchar()函数需要设置TI1*/#endif for (i=0; i=0; i-) printf(%d ,ai); 3.1.3 一维数组的初始化对数组元素

50、的初始化可以用以下方法实现:1)在定义数组时对数组元素赋以初值。例如:int a10=0,1,2,3,4,5,6,7,8,9; 2) 可以只给一部分元素赋值。例如:int a10=0,1,2,3,4; 定义a数组有10个元素,但花括弧内只提供5个初值,这表示只给前面5个元素赋初值,后5个元素值为0。3) 如果想使一个数组中全部元素值为0,可以写成int a10=0,0,0,0,0,0,0,0,0,0;不能写成int a10=0*10;4) 在对全部数组元素赋初值时,可以不指定数组长度。例如:int a5=1,2,3,4,5;可以写成int a=1,2,3,4,53.1.4 一维数组应用举例例3

51、-1-2 已知某课程的平时、实习、测验和期末成绩,求该课程的总评成绩。其中平时、实习、测验和期末分别占10、20、20、50。#include#include void main(void) int i=1,j; char con_key=x20; / x20 空格键的ASCII码 float score5,ratio4=0.1,0.2,0.2,0.5; /*定义成绩、比例系数数组*/#ifndef MONITOR51 /* 需要从串口1输出时请作如下设置*/ SCON = 0 x50; /* 方式 1, 允许接收 */ TMOD |= 0 x20; /* TMOD:定时器1方式2 */ TH

52、1 = 221; /* 1200bps 16MHz */ TR1 = 1; /* 启动定时器1 */ TI = 1; /*Keil C自带的puchar()函数需要设置TI1*/#endif while(con_key=x20) printf(输入第%2d个学生的成绩n, i+); printf(平时 实习 测验 期末成绩n); score4=0;/* score4:存储总评成绩*/ for(j=0; j4; j+) scanf(%f,&scorej); score4 += scorej * ratioj; printf(总评成绩为:%6.1fn, score4); getchar(); 3.

53、2 二维数组3.2.1 二维数组的定义 二维数组定义的一般形式为 类型说明符 数组名常量表达式常量表达式 例如: float a34,b510;不能写成 float a3,4,b5,10;3.2.2二维数组元素的引用 引用二2维数组元素的形式为:数组名行下标表达式列下标表达式1“行下标表达式”和“列下标表达式”,都应是整型表达式或符号常量。2“行下标表达式”和“列下标表达式”的值,都应在已定义数组大小的范围内。假设有数组x34,则可用的行下标范围为02,列下标范围为03。3对基本数据类型的变量所能进行的操作,也都适合于相同数据类型的二维数组元素。3.2.3 二维数组的初始化1按行赋初值 数据类

54、型 数组名行常量表达式列常量表达式第0行初值表,第1行初值表,最后1行初值表;赋值规则:将”第0行初值表”中的数据,依次赋给第0行中各元素;将“第1行初值表”中的数据,依次赋给第1行各元素;以此类推。2按二维数组在内存中的排列顺序给各元素赋初值数据类型 数组名行常量表达式列常量表达式初值表;赋值规则:按二维数组在内存中的排列顺序,将初值表中的数据,依次赋给各元素。如果对全部元素都赋初值,则“行数”可以省略。注意:只能省略“行数”。 3.2.4 二维数组应用举例例3-2-1 有M个学生,学习N门课程,已知所有学生的各科成绩,编程:分别求每个学生的平均成绩和每门课程的平均成绩。 #define N

55、UM_std 5/*定义符号常量人数为5*/#define NUM_course 4/*定义符号常量课程为4*/#include main() int i,j; static xdata float scoreNUM_std+1NUM_course+1=78,85,83,65, 88,91,89,93, 72,65,54,75,86,88,75,60, 69,60,50,72; for(i=0;iNUM_std;i+) for(j=0;jNUM_course;j+) scoreiNUM_course += scoreij;/*求第i个人的总成绩*/ scoreNUM_stdj += score

56、ij;/*求第j门课的总成绩*/ scoreiNUM_course /= NUM_course;/*求第i个人的平均成绩*/ for(j=0;jNUM_course;j+) scoreNUM_stdj /= NUM_std; /*求第j门课的平均成绩*/ /*输出表头*/ printf(学生编号 课程1 课程2 课程3 课程4 个人平均n); /*输出每个学生的各科成绩和平均成绩*/for(i=0;iNUM_std;i+) printf(学生%dt,i+1); for(j=0;jNUM_course+1;j+) printf(%6.1ft,scoreij); printf(n); /*输出1条

57、短划线*/ for(j=0;j8*(NUM_course+2);j+) printf(-); printf(n课程平均); /*输出每门课程的平均成绩*/ for(j=0;jNUM_course;j+) printf(%6.1ft,scoreNUM_stdj); printf(n); 3.3字符数组用来存放字符量的数组称为字符数组。字符数组类型说明的形式与前面介绍的数值数组相同。例如:char c10; char c510;/即为二维字符数组。字符数组也允许在类型说明时作初始化赋值。static char c=c, ,p,r,o,g,r,a,m;/ 当对全体元素赋初值时也可以省去长度说明 例3

58、-3-1 定义一个二维数组,在放字符串“BASIC”、“DBASE”,并输出。#includevoid main(void)int i,j;char a5=B,A,S,I,C,d,B,A,S,E;for(i=0;i=1;i+) for(j=0;j=4;j+) printf(%c,aij); printf(n); 字符串在语言中没有专门的字符串变量, 通常用一个字符数组来存放一个字符串。字符串总是以0作为串的结束符。因此当把一个字符串存入一个数组时, 也把结束符0存入数组,并以此作为该字符串是否结束的标志。 有了0标志后,就不必再用字符数组的长度来判断字符串的长度了。C51语言允许用字符串的方式

59、对数组作初始化赋值。例如: static char c=c, ,p,r,o,g,r,a,m; 可写为:static char c=C program; 或去掉写为:sratic char c=C program;用字符串方式赋值比用字符逐个赋值要多占一个字节, 用于存放字符串结束标志0。 除了上述用字符串赋初值的办法外,还可用printf函数和scanf函数一次性输出输入一个字符数组中的字符串, 而不必使用循环语句逐个地输入输出每个字符。void main() static char c=BASICndBASE; printf(%sn,c); 注意在本例的printf函数中,使用的格式字符串为

60、“%s”, 表示输出的是一个字符串。而在输出表列中给出数组名则可。 不能写为: printf(%s,c);3.4 多维数组 多维数组的一般说明格式是: 类型 数组名第n维长度第n-1维长度第1维长度;例如: int m32; /*定义一个整数型的二维数组*/ char c223; /*定义一个字符型的三维数组*/ 数组m32共有3*2=6个元素, 顺序为: m00, m01, m10, m11, m20, m21; 数组c223共有2*2*3=12个元素, 顺序为: c000, c001, c002, c010, c011, c012, c100, c101, c102, c110, c111

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论