您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 第5章C语言程序的基本结构
第5章C语言程序的基本结构C语言程序是由若干个函数单元组成的,每个函数都是完成某个特殊任务的子程序段。组成一个程序的若干个函数可以保存在一个源程序文件中,也可以保存在几个源程序文件中,最后再将它们连接在一起。C语言程序的扩展名为“.c”,如“test.c”等。为了使初学者能彻底弄明白,我们通过实例进行引导,由浅入深。5.1用函数调用方式完成LED1~LED8这8个二极管实现D0、D2、D4、D6及D1、D3、D5、D7的交替点亮的实验,周期约1秒5.1.1源程序文件在D盘建立一个文件目录(CS5-1),然后建立CS5-1.uv2的工程项目,最后建立源程序文件(CS5-1.c)。输入下面的程序:#includeREG51.H//1/*=====================2================*/voiddelay(void)//3{//4unsignedinti,j;//5for(i=0;i500;i++)//6{//7for(j=0;j121;j++)//8{;}//9}//10}//11//=====================12============voidlight1(void)//13{//14P1=0xaa;//15}//16//=====================17============voidlight2(void)//18{//19P1=0x55;//20}//21/*=====================22============*/voidmain(void)//23{//24while(1)//25{//26light1();//27delay();//28light2();//29delay();//30}//31}//32编译通过后,试验板接通5V稳压电源,将生成的CS5-1.hex文件下载到51MCUDEMO试验板上的单片机89S51中,注意,标示“LED”的双排针应插上8个短路块。我们看到D0~D7这8个二极管中的D0、D2、D4、D6及D1、D3、D5、D7的交替点亮,周期差不多为1S。图5-1为keilC51软件进行仿真时的界面。图5-1keilc51软件进行仿真时的界面5.1.2程序分析解释序号1:包含头文件REG51.H。序号2:程序分隔或注释,在“/*”及“*/”之间的内容,程序不会去处理,因此通常可进行文字注释,能增加程序的可读性,当然也可作为程序语句模块之间的分隔。序号3:定义函数名为delay的延时子函数。序号4:delay延时子函数开始。序号5:定义两个无符号整形变量i,j。序号6~10:两个for语句循环体,作用是延时,由于我们还未学习for语句,因此这里可暂不理会。序号11:delay的延时子函数结束。序号12:程序分隔或注释,在“//”之后的内容,程序也不会去处理,因此也可进行文字注释,能增加程序的可读性,当然也能作为程序模块之间的分隔。但应注意,这种风格的注释,只对本行有效,所以在只需要一行注释的时候,往往采用“//……”这种格式。而“/*……*/”风格的注释,既可用于一行,也可用于多行。序号13:定义函数名为light1的子函数,该子函数用于点亮D0、D2、D4、D6四个LED。序号14:light1子函数开始。序号15:向P1口送数0xaa(0xaa为16进制数,相当于汇编语言中的AAH,前缀加0x为C51的风格),这条语句的目的是点亮D0、D2、D4、D6四个LED。序号16:light1子函数结束。序号17:程序分隔。序号18:定义函数名为light2的子函数,该子函数用于点亮D1、D3、D5、D7四个LED。序号19:light2子函数开始。序号20:向P1口送数0x55,目的是点亮D1、D3、D5、D7四个LED。序号21:light2子函数结束。序号22:程序分隔。序号23:定义函数名为main的主函数。序号24:main的主函数开始。序号25:while循环语句,这里进行无限循环。序号26:while循环语句开始。序号27:调用light1子函数模块。序号28:调用延时子函数模块。序号29:调用light2子函数模块。序号30:调用延时子函数模块。序号31:while循环语句结束。序号32:main的主函数结束。5.2C语言程序的组成结构从上面的程序我们可以看出,C语言程序的组成结构如下:预处理命令include功能子函数1delay(){函数体…}功能子函数2light1(){函数体…}┊功能子函数nlight2(){函数体…}主函数main(){主函数体…}结论:C语言程序是由函数构成的,一个C源程序至少包括一个函数(主函数),一个C源程序有且只有一个名为main()的函数,也可能包含其它函数,因此,函数是C程序的基本单位。函数后面一定有一对大括号“{……}”,在大括号里书写程序。C语言程序总是从main主函数开始执行的,而不管物理位置上这个main()放在什么地方。主函数通过直接书写语句和调用其它功能子函数来实现有关功能,这些功能子函数可以是由C语言本身提供给我们的库函数,也可以是用户自己编写的函数。那么库函数和用户自定义子函数有什么区别呢?简单地说,库函数就是针对一些经常使用的算法,经前人开发、归纳、整理形成的通用功能子函数集供大家使用。而自己编写的功能子函数则称用户自定义功能子函数,显然,用户自定义功能子函数是用户根据自己需要而编写的。可以看出,使用C语言开发产品,可以大量使用库函数而减少用户自己编写程序的工作量,这样,产品开发的速度和质量是汇编语言绝对不能相比的。KeilC51内部有数百个库函数可供我们使用。调用KeilC51的库函数时只需要包含具有该函数说明的相应的头文件即可。5.3只用主函数完成LED1~LED8这8个二极管实现D0、D2、D4、D6及D1、D3、D5、D7的交替点亮的实验,周期约1秒5.3.1源程序文件在D盘中建立一个文件目录(CS5-2),然后建立CS5-2.uv2的工程项目,最后建立源程序文件(CS5-2.c)。输入下面的程序:#includeREG51.H//1/*=====================2============*/voidmain(void)//3{unsignedinti,j;//4while(1)//5{//6P1=0xaa;//7//==================8for(i=0;i500;i++)//9{//10for(j=0;j121;j++)//11{;}//12}//13//==================14P1=0x55;//15//==================16for(i=0;i500;i++)//17{//18for(j=0;j120;j++)//19{;}//20}//21//==================22}//23}//24编译通过后,试验板接通5V稳压电源,将生成的CS5-2.hex文件下载到51MCUDEMO试验板上的单片机AT89S51中,注意,标示“LED”的双排针应插上8个短路块,发现实验效果与CS5-1完全相同。但是我们能看出,此程序的结构条理没有CS5-1的程序来得清晰,一大堆实现各种功能的语句全部放在主函数内,显得有点乱。因此一个设计合理的C语言程序,不仅语句要流畅,而且结构也要简洁明了。5.3.2程序分析解释序号1:包含头文件REG51.H。序号2:程序分隔。序号3:定义函数名为main的主函数。序号4:主函数开始。定义两个无符号整形变量i,j。序号5:while循环语句,进行无限循环。序号6:while循环语句开始。序号7:向P0口送数0xaa,目的是点亮D0、D2、D4、D6四个LED。序号8:程序语句分隔。序号9~13:两个for语句循环体,作用是延时。序号14:程序语句分隔。序号15:向P0口送数0x55,目的是点亮D1、D3、D5、D7四个LED。序号16:程序语句分隔。序号17~21:两个for语句循环体,作用是延时。序号22:程序语句分隔。序号23:while循环语句结束。序号24:main的主函数结束。5.4文件包含处理我们还没有解释过预处理命令中的包含头文件REG51.H(即includeREG51.H)。包含头文件即为文件包含处理。所谓“文件包含”是指一个文件将另外一个文件的内容全部复制并包含进来,所以这里的预处理命令虽然只有一行,但C编译器在处理的时候却要处理几十乃至几百行。包含头文件REG51.H的目的是为了要使用P1这个符号,即通知C编译器,程序中所写的P1是指80C51单片机的P1端口而不是其它变量。用记事本打开C:/Keil/C51/Inc/Reg51.h(打开时的文件类型改为所有文件)可以看到这样的一些内容:/*--------------------------------------------------------------------------REG51.HHeaderfileforgeneric80C51and80C31microcontroller.Copyright(c)1988-2002KeilElektronikGmbHandKeilSoftware,Inc.Allrightsreserved.--------------------------------------------------------------------------*/#ifndef__REG51_H__#define__REG51_H__/*BYTERegister*/sfrP0=0x80;sfrP1=0x90;sfrP2=0xA0;sfrP3=0xB0;sfrPSW=0xD0;sfrACC=0xE0;sfrB=0xF0;sfrSP=0x81;sfrDPL=0x82;sfrDPH=0x83;sfrPCON=0x87;sfrTCON=0x88;sfrTMOD=0x89;sfrTL0=0x8A;sfrTL1=0x8B;sfrTH0=0x8C;sfrTH1=0x8D;sfrIE=0xA8;sfrIP=0xB8;sfrSCON=0x98;sfrSBUF=0x99;/*BITRegister*//*PSW*/sbitCY=0xD7;sbitAC=0xD6;sbitF0=0xD5;sbitRS1=0xD4;sbitRS0=0xD3;sbitOV=0xD2;sbitP=0xD0;/*TCON*/sbitTF1=0x8F;sbitTR1=0x8E;sbitTF0=0x8D;sbitTR0=0x8C;sbitIE1=0x8B;sbitIT1=0x8A;sbitIE0=0x89;sbitIT0=0x88;/*IE*/sbitEA=0xAF;sbitES=0xAC;sbitET1=0xAB;sbitEX1=0xAA;sbitET0=0xA9;sbitEX0=0xA8;/*IP*/sbitPS=0xBC;sbitPT1=0xBB;sbitPX1=0xBA;sbitPT0=0xB9;sbitPX0=0xB8;/*P3*/sbitRD=0xB7;sbitWR=0xB6;sbitT1=0xB5;sbitT0=0xB4;sbitINT1=0xB3;sbitINT0=0xB2;sbitTXD=0xB1;sbitRXD=0xB0;/*SCON*/sbitSM0=0x9F;sbitSM1=0x9E;sbitSM2=0x9D;sbitREN=0x9C;sbitTB8=0x9B;sbitRB8=0x9A;sbitTI=0x99;sbitRI=0x98;#endif在第4章,我们已经介绍了MCS-51单片机的基本结构,对80C51内部结构应该比较熟悉,因此从中可看出,这里都是一些符号的定义,即规定符号名与地址的对应关系。其中有“sfrP1=0x90;”一行,即定义P1口与地址0x90对应(0x90是C语言中十六进制数的写法,相当于汇编语言中的90H
本文标题:第5章C语言程序的基本结构
链接地址:https://www.777doc.com/doc-2195885 .html