第3章单片机C51语言程序设计基础•单片机C51语言既具有汇编语言对操作硬件的功能,又兼有高级编程语言的许多优点。在现代的单片机程序设计中,单片机C51语言得到了广泛的采用。本章主要介绍了包括C51程序的基本结构,以及C51程序设计的基础知识,包括标识符、关键字、数据类型、表达式和运算符等。熟练掌握这些知识,将为下面进一步学习打好基础。3.1C51程序的基本结构•单片机C51语言继承了C语言的特点,其程序结构与一般C语言的程序结构没有差别。C51源程序文件的扩展名为“.c”,如Test.c、Function.c等。每个C51源程序中包含一个名为“main()”的主函数,C51程序的执行总是从main()函数开始的。当主函数中所有语句执行完毕,则程序执行结束。项目文件头文件C源文件库文件编译中间文件可烧录文件KeilµVision3项目结构示意图3.2C51编程规范及注意事项•在学习任何一种编程语言的时候,按照一定的规范培养良好的编程习惯很重要。良好的编程规范可以帮助开发人员理清思路、方便整理代码,同时也便于他人阅读理解以促进代码的交流。在进行C51语言程序设计时,应该注意一下几方面的编程规范。3.2.1注释•任何编程语言都支持注释语句。注释语句只对代码起到功能描述的作用,在实际的编译链接过程中不起作用。C51语言中可以通过两种方式来表示注释内容:•用“//”符号开头来注释一行,如“//变量声明”。•用“/*”符号开头,并以“*/”符号结束来对C51源程序中的任何部分进行注释,如“/*声明整型变量ch*/”。3.2.2命名•在进行程序设计时,经常需要自定义一些函数或者变量。一般来说,只要符合C51命名规范即可通过编译。但是,为了便于源程序的理解和交流,在进行命名时应注意如下几点:•自定义函数或者变量的名称最好能反映该函数或变量的功能用途。因此,需要采用有意义的单词或者字母组合来表示。例如,MAX表示最大值、MIN表示最小值等。•变量名通常加上表示数据类型的前缀,如“ucSendData”的前缀“uc”表示unsignedchar。•在命名时不要和系统保留的标识符以及关键字产生冲突或者歧义。3.2.3格式•为了程序阅读的方便,在进行C51程序设计时,在程序结构以及语句书写格式方面应注意以下几点:•虽然C51语言对main()函数放置的位置没有限定,但为了程序阅读的方便,最好将其放置在所有自定义函数的最前面,即依次是头文件声明、自定义函数以及全局变量声明、main()函数、自定义函数。•C51语句可以写在一行上也可以写在多行上。为了程序理解的方便,最好将每个语句单独写在一行,并加以注释。有时某几个相连的语句相近或者共同执行某个功能则可以放置在一行。•对于源程序文件不同结构部分之间要留有空行。例如,头文件声明、自定义函数声明、main()函数以及自定义函数之间均要空一行来明显区分不同结构。•对于if、while等块结构语句中的“{”和“}”要配对对齐,以便于程序阅读时能够理解该结构的起始和结束。•源代码安排时可以通过适当的空格以及Tab键来实现代码对齐。3.3C51的标识符与关键字•标识符和关键字是一种编程语言最基本的组成部分,C51语言同样支持自定义的标识符以及系统保留的关键字。在进行C51程序设计时,需要了解标识符和关键字的使用规则。3.3.1标识符•标识符常用来声明某个对象的名称,如变量和常量的声明、数组和结构的声明、自定义函数的声明以及数据类型的声明等。示例如下。•intcount;•voidFunction1();•在上面的例子中,count为整型变量的标识符,Function1为自定义函数的标识符。•在C51语言中,标识符可以由字母、数字(0~9)和下划线“_”组成,最多可支持32个字符。并且,C51标识符第一个字符必须是字母或者下划线“_”。例如“ut1”、“ch_1”等,都是正确的。而“5count”则是错误的标识符。另外,C51的标识符区分大小写,例如“count1”和“COUNT1”代表两个不同的标识符。3.3.2关键字•关键字是C51语言重要的组成部分,是C51编译器已定义保留的专用特殊标识符,有时也称为保留字。这些关键字通常有固定的名称和功能,如int、float、if、for、do、while、case等。3.4C51的变量类型•数据类型是C51语言最基本的组成部分。在C51中,每个变量在使用之前必须定义其数据类型。C51语言中的数据类型分为基本数据类型和聚合数据类型,这里首先介绍基本数据类型。3.4.1C51的数据类型•C51的基本数据类型有整型(int)、浮点型(float)、字符型(char)、无值型(void)。在基本数据类型中,除void类型外,其前面均可以有各种修饰符。修饰符用来改变基本类型的意义,以便更准确地适应各种情况的需求。•常用的修饰符有signed(有符号)、unsigned(无符号)、long(长型符)、short(短型符)。在C51语言中的所有数据类型的字长和取值范围,如表所示。表3.2C51语言的数据类型3.4.2整型变量•整型变量是整数类型的数据。整型变量是最常用的数据类型。整型变量的定义格式是“类型说明符变量标识符,变量标识符…”。示例如下:•inta,b;//定义a、b为短整型变量•longc,d;//定义c、d为长整型变量•其中,类型说明符与变量标识符之间至少有一个空格。最后一个变量标识符必须以“;”结尾。整型变量的前面可以加上不同的修饰符,整型变量的类型如表所示。表整型变量的类型类型简写形式字长(bit)取值范围unsignedshortint(无符号短整型)unsignedint80~65535signedshortint(有符号短整型)short或int8-32768~32767signedlongint(有符号长整型)unsignedlong32-2147483648~2147483649unsignedlongint(无符号长整型)long320~42949672963.4.3浮点型变量•浮点型变量是用于表示包含小数点的数据类型。浮点型变量的一般定义格式是“类型说明符变量标识符,变量标识符…”。示例如下:•floata,b;//定义a、b为单精度浮点型变量•doublec,d;//定义c、d为双精度浮点型变量•同整型变量一样,浮点型变量也可以同时定义多个。C51支持三种浮点型变量类型,即float类型、double类型和longdouble类型。但是在C51中不具体区分这三种类型,它们都被当作float类型对待。因此,这三种浮点类型的精度和取值范围相同。浮点类型变量的字长为4个字节,共32位二进制数,取值范围为3.4x10-38~3.4x10+38。浮点型变量的示例程序如下:•#includestdio.h//头文件•voidmain()//主函数{•floata;//定义a为单精度浮点型变量•doubleb;//定义b为双精度浮点型变量•a=8976.1538;//赋值•b=6950.2692;•printf(a=%f\nb=%f\n,a,b);//打印输出结果•}3.4.4字符型变量•在信息的表示和传递中,经常用到字符以及文字的表示。字符型变量就是用来存放单个字符的变量类型。字符型变量的定义格式是“类型说明符变量标识符,变量标识符…”。示例如下:•chara://定义a为有符号字符变量•unsignedcharb;//定义b为无符号字符变量•在C51中,可以定义两种类型的字符型变量:有符号字符变量char和无符号字符变量unsignedchar。在C51中,字符型变量在操作时将按整型变量处理。字符是以ASCII码方式表示的,其字长为1个字节,所以有符号字符型变量的取值范围为-128~127,无符号字符型变量的取值范围是0~255。如果某个变量被定义成char,则表明该变量是有符号的,即它将转换成有符号的整型变量。3.4.5指针型变量•指针型变量是指向变量所存放地址的数据类型。在C51中,指针型变量的定义格式是“类型说明符变量标识符,变量标识符…”。示例如下:•int*i;//定义整型指针变量•float*f;//定义浮点型指针变量•char*c;//定义字符型指针变量•struct*stu;//定义结构型指针变量•union*uni;//定义联合指针变量3.4.6无值型变量•无值型变量是一个特殊的类型,其字节长度为0。无值型变量的定义格式是“类型说明符变量标识符,变量标识符…”。示例如下:•void*buf;//buf被定义为无值型指针•在C51中,无值型变量主要用于以下两个方面:•定义一个同一类型的指针,该指针可根据需要动态分配内存。•在自定义函数时,明确地表示这个函数不返回任何值。程序示例如下:•#includestdio.h//头文件••voidFun1(inta)//定义一个无返回值的函数•{•printf(thenumberis%d,a);//输出•}••voidmain()//主函数•{•inti;//定义变量•i=12;//赋值•Fun1(i);//调用函数•}3.5C51的常量类型•常量也C51中常用的数据形式。与变量的表示相比,常量的表示要相对简单,但是同样要注意表示的规范,否则会导致程序出错。C51中的常量有整型常量、浮点型常量、字符型常量和转义字符四种类型。下面分别对其进行介绍。3.5.1整型常量•整型数据包括整型变量和整型常量两种,整型变量的定义前面已经详细介绍。整型常量及整型常数可以表示十进制、八进制、十六进制的整数值。根据表示的数的进制不同进行区分,整型常量的表示如表所示。整型常量的表示整型常量类型表示形式示例十进制数以非0开始的数来表示220,-560,45900八进制数以0开始的数来表示06,0106,0578十六进制数以0X或0x开始的数来表示0X0D,0XFF,0x4e3.5.2浮点型常量•浮点型常量也称为实型常量,只可以以十进制来表示。一般来说,浮点型常量的值由整数部分、尾数部分和指数部分组成。在不加说明的情况下,浮点型常量通常为正值。如果需要表示负值,则在常量前使用负号,如18.47,-45.63,-4.2e-16,8.165。•在C51中,所有浮点常量都被默认为float型。对于绝对值小于1的浮点型常量,其小数点前面的零可以省略。例如,0.68可写为.68,-0.0314E-4可写为-.0314E-4。•在编译环境中,默认的输出格式为浮点数时,最多只保留小数点后六位,不够的后面补零。在浮点型常量中不得出现任何空白符号。字母E或e之前必须有数字,其表示形式为“数字e±数字”,且浮点型常量中E或e后面的指数必须是整数,例如“e2.3”、“e-2.5”等都是不合法的指数形式。3.5.3字符型常量•字符型常量用来表示单个字符,其用一对单引号括起来。其中单引号只起定界作用,并不表示字符本身,例如‘F’,‘5’,‘?’。在C51中,字符常量的单引号中的字符不能是单引号(’)或反斜杠(\)。如果需要使用这两个字符,则需要采用转义字符来表示,这将在后面介绍。•在C51中,字符是按其所对应的ASCII码值来存储的,一个字符占一个字节。因此也可用该字符的ASCII码值来表示该字符,例如,十进制数65表示大写字母'A',十六进制数0x5d表示符号']',八进制数0110表示大写字母'B'等。•另外,格式控制符是无法在程序中显式地表示的。因此,这些格式控制字符不能用符号表示,但其可以用ASCII码值来表示。例如,十进制数13表示回车符,八进制数033表示Esc,十六进制数0x0A表示换行符等。3.5.4转义字符•转义字符用于表示ASCII码字符集中的格式控制字符和特定功能字符,这些字符都是不可打印的。例如,用于表示字符常量的单引号('),用于表示字符串常量的双引号()和反斜杠(\)等。转义字符是C51语言中一种特殊的字符表示形式,其用反斜杠“\”后面加一个字符或一个八进制或十六进制数表示,转义字符的表示如表所示。转义