模块化程序设计一、变量变量分为局部变量、静态变量、全局变量和寄存器变量,关键字依次为auto、static、extern和register。全局变量和静态变量存放在内存静态存储区域,局部变量存放在内存栈区。在C语言中,只允许在函数体的开始位置声明变量,C++可在函数任何位置声明。auto默认省略,如autointa一般写成inta。对变量赋值不能放在函数外,只有在定义全局变量时的初始化才被允许,如在函数外inta;a=0非法,inta=0合法。局部变量也称为内部变量,是在函数内部定义的变量,其作用域从声明处到所在函数的结尾。补充:即使主函数中定义的变量也只能在主函数中使用;形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量;允许在不同的函数中使用相同的变量名,互不干扰。在复合语句中也可定义变量,其作用域只在复合语句范围内,例如:ints,a;{intb;s=a+b;//b作用域}//s,a作用域全局变量也称为外部变量,是在函数外部定义的变量,其作用域从声明处到本程序文件的结尾,其他程序文件可对其进行extern声明从而合法使用,即具有全文件作用域。全局变量只能定义一次,但可声明多次。在同一源文件中,允许全局变量和局部变量同名,在局部变量的作用域内,全局变量不起作用。从模块化程序设计考虑,尽量少用全局变量,使用静态全局变量。在函数中使用全局变量,一般应作全局变量声明,但在一个函数之前定义的全局变量,在该函数内使用可不声明,例如:inta,b;//外部变量main(){}intx,y;//外部变量a和b在main可不声明,x和y若不声明则非法。静态变量可分为静态局部变量和静态全局变量,两者都只能定义一次。静态全局变量作用域从声明处到本程序文件的结尾,不能作用到其它文件里,即具有单文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。若全局变量仅在单个程序文件中访问,则可将该变量修改为静态全局变量,以降低模块间的耦合度;同理,修改为静态局部变量;若需要一个可重入的函数,则一定要避免函数中使用static变量;当函数返回值为指针类型时,必须是static局部变量的地址作为返回值,若为auto类型,则返回为错指针。注意:不要在头文件文件中定义变量!定义和声明的区别可理解为:用关键字auto、static、extern和register是声明,如inta,声明一般在头文件中;初始化是定义,如a=0。二、函数和宏定义函数分为内部函数和外部函数,关键字分别为static和extern,外部函数声明时extern可省略(全局变量声明不能省略)。在定义函数时声明的参数叫做“形式参数”,简称形参。在调用函数时,被调用函数的参数成为“实际参数”,简称实参。实参必须与形参的类型保持一致。宏定义分简单宏定义和带参数宏定义,简单宏定义格式为:#define标识符常量表达式。在预处理阶段将用常量表达式直接替换标识符,编译时不进行数据类型检验,且要注意“边际效应”,故存在风险(与const关键字各有优缺点)。若某头文件被多个程序文件include,可用#ifndef和#pragmaonce,避免出现变量重复定义的错误,建议头文件都加#pragmaonce。宏定义的边际效应的风险包括:#defineMUL(A,B)A*B,若调用为d=MUL(a+b,c),经过编译展开会变成d=a+b*c,所以应定义为#defineMUL(A,B)((A)*(B));在用#define定义新数据类型时,容易出错,如#definedPSstructs*,若调用为dPSp1,p2,经过编译会变成structs*p1,p2,而p2就不是所预期的s的指针类型了,而是一个普通的s的数据结构类型,所以定义新数据类型时,应用typedef;在宏定义中出现++或――之类的操作符时,即使加括号,也无法避免其中的问题,应特别注意。三、模块模块即是一个.c文件(程序文件)和一个.h文件(即头文件)的结合,头文件是对于该模块接口的声明。程序设计要遵循“高聚合,低耦合”。模块化的实现方法和实质:将一个功能模块的代码单独编写成一个.c文件,然后把该模块的接口函数放在头文件文件中。假如用到液晶显示,那么可能会写一个液晶驱动模块,以实现字符、汉字和图像的现实,命名为led_device.c,该模块的.c文件大致为:#includecharvalue;//全局变量staticvoiddelay(intus){}//该函数只供本模块的函数调用,故用static关键字修饰voidwr_lcd(chardat_comm,charcontent){}//该函数要在其他模块中调用第一个函数的作用范围是模块内,第二个是其它模块需要调用的。为简化,此处未写出函数体。头文件文件中给出模块的接口,如wr_lcd(chardat_comm,charcontent)就是一个接口函数,因其它模块会调用它,故头文件中必须声明为外部函数(省略了extern),而voiddelay(intus)是本地函数,不需要在头文件中声明,即使声明了,因static的限制作用,其他文件也无法调用。.h文件大致为:externcharvalue;//声明全局变量voidwr_lcd(chardat_comm,charcontent);//声明接口函数如需在LCD菜单模块lcd_menu.c中使用液晶驱动模块lcd_device.c中的函数voidwr_lcd(chardat_comm,charcontent),只需在lcd_menu.c文件中加入液晶驱动模块的头文件lcd_device.h即可。