2020/2/24高质量C语言编程指南1高质量C语言编程指南路南平2020/2/24高质量C语言编程指南2目录1.文件结构2.程序的版式3.命名规则4.表达式和基本语句5.函数设计6.内存管理7.其他编程经验2020/2/24高质量C语言编程指南3文件结构C/C++程序中,文件有头文件、实现文件资源文件等类型。常见的是以.h结尾的头文件以.C或者.CPP结尾的实现文件.2020/2/24高质量C语言编程指南4版权和版本的声明版权和版本的声明:位于头文件和实现文件的开头,主要说明了版权信息和版本信息2020/2/24高质量C语言编程指南5头文件结构2020/2/24高质量C语言编程指南6实现文件结构2020/2/24高质量C语言编程指南7目录结构当软件的数目比较多时,通常将头文件和实现文件分别保存在不同的目录便于维护.2020/2/24高质量C语言编程指南8程序的版式空行:每个函数定义结束之后都要加空行。2020/2/24高质量C语言编程指南9程序的版式函数体内:逻辑上密切相关的语句之间不加空行,其他地方应加空行分割。2020/2/24高质量C语言编程指南10程序的版式代码行:一行代码只做一件事。if、for、while、do等语句自占一行,执行语句不得紧随其后。无论代码多少,都要加{}。2020/2/24高质量C语言编程指南11程序的版式代码行内的空格:voidFun(intx,inty,intz);不良风格代码VoidFun(intx,inty,intz);if(year=200)不良风格If(year=200)If(a=b&&c=d);不良风格If((a=b)&&(c=d))x=ab?a:b;不良风格x=ab?a:b;2020/2/24高质量C语言编程指南12对齐{和}要单独占一行,处同一列,{}内的代码应该{之内右边数格对齐(tab键)2020/2/24高质量C语言编程指南13长行拆分屏幕显示有限,代码行最大字符在70到80之间。长表达式要在低优先级操作符处拆分称新行,操作符放在新行之首。用#define的时候要加\2020/2/24高质量C语言编程指南14修饰符位置举例:Int*x,y;X变量是?Y变量是?良好风格:int*x,y;建议:应当将修饰符*紧靠变量名2020/2/24高质量C语言编程指南15注释注释一般用于版本、版权声明、函数接口说明、重要的代码行或段落提示。2020/2/24高质量C语言编程指南162020/2/24高质量C语言编程指南172020/2/24高质量C语言编程指南18命名规则著名的匈牙利命名法:基本原则是:变量名=属性+类型+对象描述,其中每一对象的名称都要求有明确含义。hwnd:h是类型描述,表示句柄,wnd是变量对象描述,表示窗口,所以hwnd表示窗口句柄;pfnEatApple:pfn是类型描述,表示指向函数的指针,EatApple是变量对象描述,所以它表示指向EatApple函数的函数指针变量。2020/2/24高质量C语言编程指南19命名共性规则标识符应当直观且可以拼读,可望文知意。标识符的长度应当符合“min-length&&max_information”原则。命名规则尽量与所采用的操作系统或者开发工具风格保持一致。(windos*nixlinux)程序中不要出现仅靠大小写区分的相似的标识符。程序中不要出现标识符完全相同的局部变量和全局变量。2020/2/24高质量C语言编程指南20变量的名字应当使用“名词”或者“形容词+名词“intvalue;floatodlValue;floatnewValue;全局函数的名字应当使用动词或者动词+名词。DrawBox();用正确的反义词组命名具有互斥意义的变量或相反动作的函数等.intSetValue();intGetValue();尽量避免名字中出现数字编号。命名共性规则(续)2020/2/24高质量C语言编程指南21简单windows程序命名规则函数名用大写字母开头的单词组合而成。voidDraw(void);voidSetValue(intvalue);变量和参数用小写字母开头的单词组合而成。BOOLflag;intdrawMode;常量全用大写的字母,用下划线分割单词。constintMAX=100;constintMAX_LENGH=100;静态变量加前缀s_,全局变量加前缀g_;staticints_initValue;intg_howManyPeople;可以为各种标识符加上能反映软件性质的前缀。OpenGL的所有库函数以gl开头,常量以GL开头。2020/2/24高质量C语言编程指南22表达式和基本语句2020/2/24高质量C语言编程指南23表达式和基本语句如果代码行中运算符比较多,用括号确定表达式的操作顺序。if((a|b)&&(a&c))不要编写太复杂的复合表达式。i=ab&&cd&&c+f=g+h;不要用多用途的复合表达式。d=(a=b+c)+r;不要把程序中的复合表达式与真正的数学表达式混淆。if(abc)2020/2/24高质量C语言编程指南24表达式和基本语句If语句:布尔变量与0值比较If(flag==0)if(flag!=0)不可将布尔变量直接与TRUE、FALSE或者1、0进行比较。If(flag)if(!flag)2020/2/24高质量C语言编程指南25If语句(续)整型变量与0值比较if(value)if(!value)应当将整型变量用“==”或“!=”直接与0比较。If(value==0)if(value!=0)浮点型变量与0值比较If(value==0)if(value==0.0)不可将浮点变量用“==”或者“!=”与任何数字比较。If((value=-0.0001)&&(value=0.0001)2020/2/24高质量C语言编程指南26IF语句(续)指针变量与0值比较if(p==0)if(p)应当将指针变量用“==”或“!=”与NULL比较if(p==NULL)if(p!=NULL)If(NULL==p)If/else/return组合if(condition)returnx;returny;良好风格:return(condition?x:y);2020/2/24高质量C语言编程指南27循环效率在多重循环中,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数。2020/2/24高质量C语言编程指南28循环效率(续)如果循环体内存在逻辑判断,并且循环体次数很大,宜将逻辑判断移动到循环体的外面。2020/2/24高质量C语言编程指南29FOR语句的循环控制变量不可在FOR循环体内修改循环变量,防止FOR循环失去控制。for(i=0;i10;i++){doSomeThing();i++;}建议FOR语句的循环控制变量采用“半开半闭区间”写法。For(x=0;x=9;x++)2020/2/24高质量C语言编程指南30Switch语句1.每个case语句的结尾不要忘记break;2.最后添加一个default;3.Case关键字之后的值有什么要求么?case后面只能是整型或字符型的常量或常量表达式。4.Case语句的顺序有什么要求?把正常情况的语句放在前面,而把异常情况的语句放在后面。2020/2/24高质量C语言编程指南31GOTO语句goto语句也称为无条件转移语句,一般格式如下:goto语句标号;其中语句标号是按标识符规定书写的符号,放在某一语句行的前面,标号后加冒号(:)。在跳出多重循环的时候,比较简洁。慎用!!2020/2/24高质量C语言编程指南32常量常量的作用:避免了意义模糊的数字出现,使得程序语义流畅清晰可以很方便地进行参数的调整与修改提高了程序的执行效率,由于使用了预编译器进行值替代,并不需要为这些常量分配存储空间,所以执行的效率较高。用法:#defineMAX1002020/2/24高质量C语言编程指南33函数设计参数的规则:1.参数书写要完整。voidSetValue(int,int);voidSetValue(intwidth,intheight);2.函数命名要恰当,顺序要合理。voidStringCopy(char*str1,char*str2);voidStringCopy(char*strSource,char*strDestion);2020/2/24高质量C语言编程指南34参数规则3.参数是指针,且仅做输入用,应在类型前加const防止修改。voidStringCopy(char*strDestion,constchar*strSource);4.避免函数有太多的参数。5.尽量不要使用类型和数目不确定的参数。intprintf(constchar*format[,argument]...);2020/2/24高质量C语言编程指南35返回值规则1.不要省略返回值的类型。2.函数名字与返回值类型在语义上可不冲突。函数原型:Intgetchar(void)3.不要将正常值和错误标志混在一起返回。正常值用输出参数获得,错误表示用return语句返回。4.有时候函数原本不需要返回值,为增加灵活性可以附加返回值。char*strcpy(char*strDest,constchar*strSrc);可以支持链式表达intlength=strlen(strcpy(str,HwelloWorld));2020/2/24高质量C语言编程指南36函数内部实现规则1.在函数体的入口处,对参数的有效性进行检查。2.在函数体的出口处,对return语句的正确性和效率进行检查。char*Func(void){charstr[]=helloworld;returnstr;}return语句不可返回指向栈内存的指针。2020/2/24高质量C语言编程指南37assert断言1.assert断言仅在Debug版本有效如果不可能发生的事情的确发生了,则要使用断言进行报警。2020/2/24高质量C语言编程指南38内存管理内存分配的方式:1.从静态存储区域分配。全局变量static变量。2.从栈上创建。系统自动管理.3.从堆上分配,即动态内存分配。程序员管理.常见错误.1.内存分配未成功,却使用了它.解决:指针p是函数的参数,在入口处用assert(p!=NULL)检查。如果是malloc来申请内存,用if(p==NULL)或if(p!=NULL)进行放错处理。2020/2/24高质量C语言编程指南39常见错误2.内存分配虽然成功,但是尚未初始化就引用它。Inta[100];For(i=0;i100;i++){if(a[i]==0)}有的编译器初始化数组为0有的不是最好在创建的时候赋值。2020/2/24高质量C语言编程指南40常见错误3.内存分配成功并且已经初始化,但操作越过了内存的边界。4.忘记释放内存,造成内存泄漏。New/deletemalloc/free5.释放了内存却继续使用(1).return语句返回栈内存,(2).free或者delte释放了内存之后,没设置指针为NULL,导致野指针;2020/2/24高质量C语言编程指南41建议1.malloc或new申请内存之后,立即检查指针值是否为NULL。2.为数组和动态内存赋初值。3.避免数组或者指针的下标越界。4.动态内存的申请与释放必须配对。5.fee或delete释放内存之后,立即将指针设置为NULL。2020/2/24高质量C语言编程指南42指针与数组的对比1.数组被创建在静态存储区或者栈上,数组名对应着一块内存,其地址与容量在生命期内保持不变,数