单片机C51程序设计(补充)_第1页
单片机C51程序设计(补充)_第2页
单片机C51程序设计(补充)_第3页
单片机C51程序设计(补充)_第4页
单片机C51程序设计(补充)_第5页
已阅读5页,还剩88页未读 继续免费阅读

下载本文档

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

文档简介

1、5.3.1 Keil C语言1、概述Keil C语言的编译器及编译过程如图510所示。单片机C语言程序设计图5-10Keil C语言的编译器及编译过程在Keil C语言的软件包中,包含下列文件:C51编译器Keil C51编译器是一个基于ANSI C标准的、针对80C51系列MCU的C编译器,生成的可执行代码快速、紧凑,在运行效率和速度上可以和汇编程序得到的代码相媲美。A51宏汇编器A51宏汇编器是一个8051系列MCU的宏汇编器,支持8051及其派生系列的全部指令集。它把汇编语言汇编成机器代码。本汇编器允许定义程序中的每一个指令,在需要极快的运行速度,很小的代码空间,精确的硬件控制时使用。本

2、汇编器的宏特性让公共代码只需要开发一次,从而节约了开发和维护的时间。A51汇编器将源程序汇编成可重定位的目标代码,并产生一个列表文件。其中可以包含也可不包含字符表及交叉参考信息。BL51连接/定位器BL51连接/定位器是具有代码分段功能的连接/定位器,利用从库中提取的目标模块和由编译器或汇编器生成的一个或多个目标模块,处理外部和全局数据,并将可重定位的段分配到固定的地址上。所产生的一个绝对地址目标模块或文件包含不可重定位的代码和数据。所有的代码和数据被安置在固定的存储器单元中。此绝对地址目标文件可以用来: 。写入EPROM或其它存储器件。 。由uVision2调试器使用来模拟和调试。 。由仿真

3、器用来测试程序。LIB51库管理器 LIB51库管理器让你建立和维护库文件。库文件是格式化的目标模块(由编译器或汇编器产生)的集合。库文件提供了一个方便的方法来组合和使用大量的连接程序可能用到的目标模块。 虽然Keil C51是一个兼容ANSI C的编译器,但为了支持80C51系列MCU还是加入了一些扩展的内容。C51编译器与ANSI C相比,扩展的内容包括:数据类型、存储器类型、存储模式、指针及函数(包括:定义函数的重入性、指定函数的寄存器组、指定函数的存储模式及定义中断服务程序)。2、 Keil C对ANSI C的扩展前已述及,本书的读者在前修课程中已经学过了通用的C语言课程,因此在这里将

4、不再叙述有关C语言的一般内容,仅简要地描述Keil C51对ANSI C的扩展。(1)数据类型Keil C51编译器支持的各种规格的数据类型列于表5-1。除了这些数据类型以外,变量可以组合成结构、联合及数组。表5-1 Keil C51支持的数据类型 数据表5-1所列的数据类型中,bit、 sbit 、sfr 和sfr16 等四种类型在ANSI C中没有,是C51编译器中新增的。sbit、sfr和sfr16类型的数据是用于操作80C51的特殊功能寄存器的。例如,下面的表达式:sfr P0 = 0 x80; /* 定义 80C51 P0 口的特殊功能寄存器 */声明了一个变量P0,并且把它和位于0

5、 x80(80C51的P 0口)处的特殊功能寄存器联系在一起。1) bit 类型bit 数据类型可能在变量声明参数列表和函数返回值中有用。一个bit 变量的声明与其它数据类型相似,例如:bit done_flag=0; /* 位变量 */bit testfunc(bit flag1, bit flag2); /* 位函数 */ 所有的 bit 变量放在80C51 内部存储区的位段。因为这个区域只有16 字节长,所以在某个范围内最多只能声明128个位变量。bit 变量的声明中,应包含存储类型。但是因为 bit 变量存储在80C51的内部数据区,只能用data 和idata 存储类型,不能用别的存

6、储类型。bit 变量和 bit 声明有以下限制: 一个位不能被声明为一个指针,例如:bit *ptr;/* 非法 */不能用一个 bit 类型的数组,例如:bit ware5/* 非法 */2 )sbit、sfr和sfr16数据类型 80C51 系列MCU用特殊功能寄存器SFR来控制计时器、计数器、串口、并口和外围设备。它们的可以用位、字节和字访问。与此对应,编译器提供 sbit、sfrs和fr16数据类型访问SFR。下面说明这些数据类型。. sfr 类型sfr和C的其它变量一样声明。例如:sfr P0=0 x80;/* P0口,地址为80h */sfr P1=0 x90;/* P1口,地址为

7、90h */sfr P2=0 xA0;/* P2口,地址为0A0h */sfr P3=0 xB0;/* P3口,地址为0B0h */P0、P1、P2 和P3 是声明的SFR名。在等号(=)后指定的地址必须是一个常数值不允许用带操作数的表达式。传统的80C51系列支持SFR地址从0 x80 到0 xFF。. sfr16 类型编译器提供 sfr16 数据类型,将两个8位的SFR作为一个16位的SFR来访问。访问该16位的SFR只能是低字节跟着高字节,即将低字节的地址用作 sfr16声明的地址。例如:sfr16 T2=0 xCC;/* 定时器2,T2L的地址为0CCh,T2H的地址为0CDh */s

8、fr16 RCAP2=0 xCA;/* RCAP2L的地址为0CAh, RCAP2H的地址为0CBh */在这个例子中,T2 和RCAP2被声明为16 位SFR。sfr16 声明和 sfr 声明遵循相同的原则。任何符号名可用在 sfr16 的声明中。等号(=)指定的地址,必须是一个常数值。不允许使用带操作数的表达式,而且必须是SFR的低位和高位字节中的低位字节的地址。. sbit 类型编译器用sbit数据类型来访问可位寻址的SFR中的位。例如:sbit EA=0 xAF;(2)存储器类型80C51的存储区域有两个特奌: 程序存储器和数据存储器是截然分开的; 特殊功能寄存器与内部数据存储器是统一

9、编址的。C51编译器支持80C51的这种存储器结构,能够访问80C51的所有存储器空间。针对80C51存储空间的多样性,提出了修饰存储空间的修饰符,用以指明所定义的变量应分配在什么样的存储空间,如表5-2所示。表5-2 存储器类型1)、程序存储区 程序的代码(CODE)存储区是只读的,不能写入。硬件决定最多可能有64KB的程序存储区。 用code标识符来访问片内、片外统一编址的程序存储区,寻址范围为065535。在此空间存放程序编码和数据、表格。用间接寻址的方式訪问程序存储区数据,如MOVC A,A+DPTR或MOVC A,A+PC。2)、内部数据存储区内部的数据存储区是可读、可写的。80C5

10、1系列最多可有256字节的内部数据存储区。内部数据区可以分成三个不同的存储类型 data、idata 和bdata。data 存储类型标识符通常是指低128字节的内部数据区,为片内直接寻址的RAM空间,寻址范围为0127。在此空向内存取速度最快。idata存储类型标识符是指全部256个字节的内部存储区,为片内间接寻址的RAM空间,寻址范围为0255。寻址方式为MOV Ri。由于只能间接寻址,访问速度比直接寻址慢。bdata存储类型标识符是指可位寻址的16字节内部存储区(20H2FH),位地址范围为0127。本空间允许按字节和按位寻址。在本区域可以声明可位寻址的数据类型。3)、外部数据存储区外部

11、数据存储区是可读、可写的。可通过一个数据指针加载一个地址来间接访问外部数据区。因此,访问外部数据存储区比访问内部数据存储区来得慢。外部数据存储区最多可有64KB。这些地址不一定都用来作为数据存储区。因为,硬件设计可能把外围设备影射到该存储区。编译器提供两种不同的存储类型,访问外部数据 xdata 和 pdata。xdata 存储类型标识符是指外部数据存储区(64KB)内的任何地址,寻址范围为065535。寻址方式为MOVX DPTR。pdata 存储类型标识符仅指一页或256 字节的外部数据存储区,寻址范围为0255。寻址方式为MOVX Ri。 在定义变量时,通过指明存储器类型,可以将所定义的

12、变量存储在指定的存储区域中。访问内部数据存储器将比访问外部数据存储器快的多。因此,应该把频繁使用的变量放置在内部数据存储器中,把很少使用的变量放在外部数据存储器中。在变量的声明中,可以包括存储器类型和signed或unsigned属性。如:char data var1;char code text = ENTER PARAMETER;unsigned long xdata array100;float idata x,y,z;unsigned int pdata dimension;unsigned char xdata vector1044;char bdata flags;如果在变量的定义

13、中,没有包括存储器类型,将自动选用默认的存储器类型。(3)存储模式在C51编译器中,可以在命令行用SMALL,COMPACT和LARGE参数定义存储模式。存储模式决定了默认的存储器类型。定义变量时,若指定了存储器类型,将屏蔽掉由存储模式所决定的默认的存储器类型。1)、小(SMALL)模式在这种模式下,所有变量都默认定义在内部数据存储器中。这和用data显式定义变量起到相同的作用。该模式的特点是,变量访问是非常快速的。然而,此时所有的数据对象,包括堆栈都必须放在内部RAM中。堆栈空间面临溢出,因为堆栈占用空间的多少依赖于各个子程序的调用嵌套的深度。在典型应用中,如果,将BL51连接/定位器配置成

14、可覆盖内部数据存储器中的变量时,这种模式将是最好的选择。2)、紧凑(COMPACT)模式在这种模式下,所有变量都默认存放在外部数据存储器的一页中。这和用pdata显式定义变量起到相同的作用。该页地址的高字节往往通过P2口输出。编译器不会设置P2口的输出值,必须在启动代码中设置。此模式最多只能提供256字节的变量。这种限制来自于间接寻址所使用的R0,R1(MOVX R0/R1)。这种模式不如SMALL模式高效,所以变量的访问不够快。不过它比LARGE模式要快。3)、大(LARGE)模式在大模式下,所有的变量都默认在外部存储器(xdata)中。这和用xdata显式定义变量起到相同的作用。数据指针(

15、DPTR)用来寻址。通过DPTR进行存储器的访问的效率很低。此数据访问类型比SMALL和COMPACT模式需要更多的代码。一般情况下,应该使用小(SMALL)模式,它产生最快,最紧凑,效率最高的代码。在定义变量时,最好要指定存储器类型。只有当应用不可能在SMALL模式下操作时,才需要往上增加你的存储模式。(4)指针C51编译器支持用星号(*)进行指针声明。可以用指针完成在标准C语言中有的所有操作。由于80C51及其派生系列所具有的独特结构,C51编译器支持两种不同类型的指针:通用指针和存储器指针。1)、通用指针通用或未定型的指针的声明和标准C语言中一样。如:char *s; /* string

16、 ptr */int *numptr;/* int ptr */long *state; /* long ptr */ 通用指针需要三个字节来存储。第一个字节用来表示存储器类型,第二个字节是指针的高字节,第三字节是指针的低字节。 通用指针可以用来访问所有类型的变量,而不管变量存储在哪个存储空间中。因而许多库函数都使用通用指针。通过使用通用指针,一个函数可以访问数据,而不用考虑它存储在什么存储器中。 通用指针很方便,但是也很慢。在所指向目标的存储空间不明确的情况下,它们用的最多。2)、存储器指针存储器指针或类型确定的指针在定义时要包含一个存储器类型说明,并且总是指向此说明的特定存储器空间。例如:

17、char data *str; /* 指向data 区域的字符串 */int xdata *numtab; /* 指向xdata 区域的 int */long code *powtab; /* 指向code 区域的 long */正是由于存储器类型在编译时已经确定,通用指针中用来表示存储器类型的字节就不再需要了。指向idata,data,bdata和pdata的存储器指针使用一个字节来保存;指向code和xdata的存储器指针用两个字节来保存。由此可见,使用存储器指针比通用指针效率要高,速度要快。当然,存储器指针的使用不是很方便。只有在所指向目标的存储空间明确并不会变化的情况下,才用它。(5)

18、函数1)、重入函数函数的嵌套调用是指当一个函数正被调用尚未返回时,又被本函数或其它函数再次调用的情况,只有等到后次调用返回到了本次,本次被暂时搁置的程序才得以恢复接续原来的正常运行,直到本次返回。允许被嵌套调用的函数必须是可重入函数,即函数应具有可重入性。 通常情况下,C51函数一般是不能被递归调用的。这是由于函数参数和局部变量是存储在固定的地址单元中的。重入函数需要使用重入堆栈,这种堆栈是在存储模式所指的空间内从顶端另行分配的一个非覆盖性的堆栈。该堆栈将被嵌套调用的每层参数及局部变量一直保留到由深层返回到本层,而又终止本层的返回。在一个基本函数的基础上添加reentrant说明,从而使它具有

19、重入特性。如:int calc (char i, int b) reentrant int x; x = table i; return (x * b); 在实时应用中以及中断服务程序代码和非中断程序代码必须共用一个函数的场合中,经常用到重入函数。 需要注意的是, 不应将全部程序声明为重入函数。把全部程序声明为重入函数将增加目标代码的长度并减慢运行速度。应该选择哪些必须的函数作为重入函数。2)、函数使用指定的寄存器组 using n函数使用指定寄存器组的定义性说明如下:viod 函数标识符(形参表)using n其中 n=03为寄存器组号,对应80C51中的四个寄存器组。函数使用了using

20、n后,C51编译器自动在函数的汇编码中加入如下的函数头段和尾段:pushpswmovpsw,#与寄存器组号n有关的常量poppsw 应该注意的是,using n不能用于有返回值的函数。因为,C51的返回值是放在寄存器中的,而返回前寄存器组却改变了,将会导致返回值发生错误。3)、函数使用指定的存储模式针对80C51存储空间的多样性,提出了修饰存储空间的修饰符,用以指明所定义的变量应分配在什么样的存储空间,其定义性格式为:类型说明符 函数标识符(形参表)存储模式修饰符small,compact,large 其中,修饰符可用small、compact、large三者中的一个。 存储模式为本函数的参数

21、和局部变量指定的存储空间,在指定了存储模式之后,该空间将再也不随编译模式而变。如:extern int func (int i, int j)large;/* 修饰为大模式 */4)、中断服务程序C51编译器允许用C语言创建中断服务程序。只需关心中断号和寄存器组的选择。编译器自动产生中断向量和程序的入栈及出栈代码。在函数声明时包括interrupt m,将把所声明的函数定义为一个中断服务程序。其格式为:viod 函数标识符(viod)interrupt m其中,m031, 0对应于外部中断0; 1对应于定时器0中断; 2对应于外部中断1; 3对应于定时器1中断; 4对应于串行口中断; 其它为预

22、留。从定义中可以看出,中断的函数必须是无参数、无返回值的函数。如:unsigned int interruptcnt;unsigned char second;void timer0 (void) interrupt 1 using 2 if (+interruptcnt = 4000) /* 计数到 4000 */second+; /* 秒计数器 */interruptcnt = 0; /* 清除中断计数器 */4.3.4 绝对地址的访问一使用C51运行库中预定义宏 C51编译器提供了一组宏定义来对51系列单片机的code、data、pdata和xdata空间进行绝对寻址。规定只能以无符号数

23、方式访问,定义了8个宏定义,其函数原型如下:#define CBYTE(unsigned char volatile*)0 x50000L)#define DBYTE(unsigned char volatile*)0 x40000L)#define PBYTE(unsigned char volatile*)0 x30000L)#define XBYTE(unsigned char volatile*)0 x20000L)#define CWORD(unsigned int volatile*)0 x50000L)#define DWORD(unsigned int volatile*)0

24、x40000L)#define PWORD(unsigned int volatile*)0 x30000L)#define XWORD(unsigned int volatile*)0 x20000L) 这些函数原型放在absacc.h文件中。使用时须用预处理命令把该头文件包含到文件中,形式为:#include 。 其中:CBYTE以字节形式对code区寻址,DBYTE以字节形式对data区寻址,PBYTE以字节形式对pdata区寻址,XBYTE以字节形式对xdata区寻址,CWORD以字形式对code区寻址,DWORD以字形式对data区寻址,PWORD以字形式对pdata区寻址,XWOR

25、D以字形式对xdata区寻址。访问形式如下: 宏名地址 宏名为CBYTE、DBYTE、PBYTE、XBYTE、CWORD、DWORD、PWORD或XWORD。地址为存储单元的绝对地址,一般用十六进制形式表示。【例4-7】绝对地址对存储单元的访问#include /*将绝对地址头文件包含在文件中*/#include /*将寄存器头文件包含在文件中*/#define uchar unsigned char /*定义符号uchar为数据类型符unsigned char*/#define uint unsigned int /*定义符号uint为数据类型符unsigned int*/void main

26、(void)uchar var1;uint var2;var1=XBYTE0 x0005; /*XBYTE0 x0005访问片外RAM的0005字节单元*/var2=XWORD0 x0002; /*XWORD0 x0002访问片外RAM的000字单元*/.while(1); 在上面程序中,其中XBYTE0 x0005就是以绝对地址方式访问的片外RAM 0005字节单元;XWORD0 x0002就是以绝对地址方式访问的片外RAM 0002字单元。二通过指针访问 采用指针的方法,可以实现在C51程序中对任意指定的存储器单元进行访问。【例4-8】 通过指针实现绝对地址的访问。#define ucha

27、r unsigned char /*定义符号uchar为数据类型符unsigned char*/#define uint unsigned int /*定义符号uint为数据类型符unsigned int*/void func(void)uchar data var1;uchar pdata *dp1; /*定义一个指向pdata区的指针dp1*/uint xdata *dp2; /*定义一个指向xdata区的指针dp2*/uchar data *dp3; /*定义一个指向data区的指针dp3*/dp1=0 x30; /*dp1指针赋值,指向pdata区的30H单元*/dp2=0 x1000

28、; /*dp2指针赋值,指向xdata区的1000H单元*/*dp1=0 xff; /*将数据0 xff送到片外RAM30H单元*/*dp2=0 x1234; /*将数据0 x1234送到片外RAM1000H单元*/dp3=&var1; /*dp3指针指向data区的var1变量*/*dp3=0 x20; /*给变量var1赋值0 x20*/三使用C51扩展关键字_at_ 使用_at_对指定的存储器空间的绝对地址进行访问,一般格式如下: 存储器类型 数据类型说明符 变量名 _at_ 地址常数; 其中,存储器类型为data、bdata、idata、pdata等C51能识别的数据类型,如省略则按存

29、储模式规定的默认存储器类型确定变量的存储器区域;数据类型为C51支持的数据类型。地址常数用于指定变量的绝对地址,必须位于有效的存储器空间之内;使用_at_定义的变量必须为全局变量。【例4-9】通过_at_实现绝对地址的访问。#define uchar unsigned char /*定义符号uchar为数据类型符unsigned char*/#define uint unsigned int /*定义符号uint为数据类型符unsigned int*/data uchar x1 _at_ 0 x40; /*在data区中定义字节变量x1,它的地址为40H*/xdata uint x2 _at_

30、 0 x2000; /*在xdata区中定义字变量x2,它的地址为2000H*/void main(void)x1=0 xff;x2=0 x1234;.while(1);5.3.2 C语言与汇编语言的混合编程 C语言编程与汇编语言编程各有所长。使用C语言,开发速度快,可读性、可维护性、可移植性都好;而使用汇编语言,则可以更为充分地利用芯片的软、硬件资源,使得程序代码的执行效率高。为了发挥C语言与汇编语言两种语言各自的优势,希望能够实现它们的混合编程。这一点特别适用于要求占用空间小、有严格时间限制的子程序设计,这类子程序总是希望用汇编语言来编写,然后由C 语言主程序来调用。 要创建有正确接口的汇

31、编语言子程序,我们首先通过C51编译器创建汇编语言源程序的框架,看一看为了创建有正确接口的汇编语言子程序所需要考虑的问题。例5。12:有名为mod.c的模块,试用C51编译器产生它的汇编语言程序。int func(int i,int j) char c; i+;/* 访问i */j+;/* 访问j */c+;/* 访问c */return(i); 执行 C51 mod.c SRC产生的汇编语言程序模块为:; MOD.SRC generated from: MOD.C; COMPILER INVOKED BY:; F:C51.EXE MOD.C SRCNAME MOD?PR?_func?MOD

32、SEGMENT CODE ?DT?_func?MOD SEGMENT DATA OVERLAYABLE ?PR?func1?MOD SEGMENT CODE PUBLIC_funcRSEG ?DT?_func?MOD?_func?BYTE: c?042: DS 1RSEG ?PR?_func?MOD_func:USING0 INC R7CJNE R7,#00H,?C0003INC R6?C0003:INC R5CJNE R5,#00H,?C0004?C0004:INC c?042?C0001:RET ; END OF _func ; END 通过上面的例子,可以看出,为了要创建有正确接口的汇编

33、语言子程序,必须注意以下几个问题: 函数名的命名规则C51的编译器在编译过程中,将模块的名字转换为大写字符;对所有的定义说明的函数,还按函数有无寄存器参数传送和函数是否具有可重入性进行换名。函数换名的规则如表5-3所示。表5-3函数换名的规则 在上述的例子中,将整个模块的名字由mod 转换为MOD。函数int func(int i,int j)由于有寄存器参数的传送,将其函数名换为“_func”。 函数段名的命名规则函数经编译之后,有程序部分和数据部分,它们分别放在独立的段中。表5-4给出的是在不同存储模式下,函数所使用的段名。表5-4 不同存储模式下,函数的段名 在上述的例子中,由于是处于默

34、认的存储模式(SMALL)下,相应的段名为:?PR?_func?MOD SEGMENT CODE ?DT?_func?MOD SEGMENT DATA OVERLAYABLE 段“?PR?_func?MOD”存放函数_func的代码;段“?DT?_func?MOD”存放局部变量c,而且该区域是可覆盖的(OVERLAYABLE)。. 参数传递规则C51编译器能在CPU寄存器中传递最多三个参数,由于不用从存储器中读出和写入参数,从而显著提高了系统性能。表5-5列出了不同的参数和数据类型所占用的寄存器。表5-5 不同的参数和数据类型占用的寄存器 如果没有CPU寄存器供参数传递所用,或太多的参数需要传

35、递时,地址固定的存储器将用来存储这些额外的参数。在上述的例子中,有三个局部变量,i, j和c。i, j为 int 型变量,各占两个字节,分别由R7/R6和R5/R4传递;c为char型变量,需占一个字节,这由地址c?042所保留的存储区来存储。 函数返回值函数返回值总是通过CPU寄存器进行。表6列出了返回各种数据时所用的CPU寄存器。表5-6 不同返回数据类型占用的寄存器 在上述的例子中,函数func是有返回值的,通过寄存器R7/R6返回变量i,它是一个int型量占两个字节。 从上述的例子中可以得出编写被C语言调用的汇编语言程序需要通过以下步骤: 要获得由C输入的函数参数,前三个参数一般应从寄

36、存器中取得。寄存器不够或参数多于三个时,则放在与模式有关的缺省数据段中传入的。数据是按定义说明的先后顺序安放的。对于位变量另有位段。 汇编子程序的主体部分放在code段中。主体部分的一开始一定要把寄存器中的参数保存起来,因为函数内部可能要使用到这些寄存器。函数的内部变量应安排在与参数相关同的段内。 函数的主体部分用汇编写出。 函数的结尾部分应考虑是否有返回量。如有,在RET指令之前放入合适的寄存器中;没有返回量,则直接写RET指令返回。 应将函数地址和数据段及位段的首址均说明为汇编的public。 将程序段、数据段和位段均加上overlayable(覆盖)的连接属性。以下试举例说明之。例5.1

37、3:试编写能被C函数调用的汇编语言延时子程序。viod delay (unsigned vd)?PR?_delay?MOD SEGMENT CODE PUBLIC_funcRSEG ?PR? _delay?MOD_delay:USING0Delay: MOVA,#0FFHDel:NOPNOPDJNZA,DelDJNZ R7,DelayMOVA,R6JZEXITDJNZR6,DelayEXIT:RETEND5.3.3 C语言程序设计如前所述,一般的程序都是顺序、选择、循环三种结构的复杂组合。C语言中有一大批控制语句,用于控制程序的流程,以实现程序的选择结构和循环结构。它们由特定的语句定义符组成。

38、下面分别介绍顺序、选择、循环三种基本结构与它们的控制语句。 顺序结构例: includeint gcd(int u,int v) int temp; temp=u-v; return(temp);main() int result,a=150,b=35; result= gcd(a,b);这个程序是一个纯粹的顺序结构程序。 选择结构C语言中,提供if 语句和switch语句条件判断语句,以实现程序的选择结构。其中,if 语句适合二选一,而switch语句适用于多选一。(1) if语句if语句有三种基本形式: if (条件表达式) 动作 如果条件表达式的值为真(非零的数),则执行 内的动作,如果

39、条件表达式为假,则略过该动作而继续往下执行。例:if (a=b)printf (“a=b”);如果相等,那么打印a=b,否则跳过这条语句。 if (条件表达式)动作1 else动作2 如果条件表达式的值为真,执行动作1,略过else的部分,接着往下执行;如果条件表达式的值为假,则略过动作1部分而执行else后的动作2,然后再往下执行。在选择结构中,注意else 与前面最靠近它的if 配对。例5.14:在a,b两数中,求其大者并存入c中。if (ab)c=a;elsec=b; if (条件表达式1)动作A else if (条件表达式2)动作B else if (条件表达式3)动作C else动

40、作D 条件表达式1成立时执行动作A;条件表达式1、2成立,执行动作B;条件表达式1、2、3成立,执行动作C;条件表达式1、2、3均不成立时,执行动作D。(2) switch-case 语句switch-case 语句专门处理多路分支的情况,使程序变得更为简洁。一般当程序必须作多选一时,可采用switch-case 语句。switch(条件表达式)case 条件值1:动作1break;case 条件值2:动作2break;case 条件值3:动作3break;default: 动作4break; switch 内的条件表达式的结果必须为整数或字符。Switch以条件表达式的值来与各case 的条

41、件值对比,如果与某个条件相符合,则执行该case的动作,如果所有的条件值都不符合,则执行default的动作。每一个动作之后一定要写break,否则会有错误。另外,case之后的条件值必须是数据常数,不能是变量,而且不能重复,即条件值必须各不相同。如果有数种case所做的动作一样时,也可以写在一起,即上下并列。default:当所有case的条件值都不成立时,就执行default所指定的动作,作完后也要用break指令跳出switch循环。例:switch(temp) case 1: do_ack();break; case 2: do_cack();break; case 3: do_mnack();break; default:b

温馨提示

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

评论

0/150

提交评论