欢迎来到三一文库! | 帮助中心 三一文库31doc.com 一个上传文档投稿赚钱的网站
三一文库
全部分类
  • 研究报告>
  • 工作总结>
  • 合同范本>
  • 心得体会>
  • 工作报告>
  • 党团相关>
  • 幼儿/小学教育>
  • 高等教育>
  • 经济/贸易/财会>
  • 建筑/环境>
  • 金融/证券>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 三一文库 > 资源分类 > PPT文档下载
     

    编程规范和技巧.ppt

    • 资源ID:3615304       资源大小:458.62KB        全文页数:80页
    • 资源格式: PPT        下载积分:8
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录   微博登录  
    二维码
    微信扫一扫登录
    下载资源需要8
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    编程规范和技巧.ppt

    编程规范和技巧, 编写高质量的C/C+程序,一定要编写高质量代码!,高质量代码 提高编程效率 减少调试时间 提高人品:代码是写给他人用的! 养成好习惯 从点点滴滴做起 不要光看不做,程序员的境界,大学计算机教育的失误:程序质量低下 什么是编程老手:能够长期稳定地编写出高质量程序的程序员 什么是编程高手:能够长期稳定地编写出高难度、高质量程序的程序员,编程风格,世上不存在最好的编程风格 一切因需求而定 团队开发讲究风格一致 如果制定了大家认可的编程风格,那么所有组员都要遵守 若某种编程风格比较合你的工作,那么就采用它,不要只看不做:养成习惯!,一流代码的特性,鲁棒 - Solid and Robust Code 简洁 - Maintainable and Simple Code 高效 - Fast Code 简短 - Small Code 共享 - Re-usable Code 可测试 - Testable Code 可移植 - Portable Code,关于代码风格问题,代码风格(Coding Style)是一种习惯 现在许多大公司都对员工书写代码制定了规范 开发大项目时由项目管理者制定代码规范 程序风格的重要构成因素 程序版式 命名规则 函数设计原则 其他 表达式规则 与零比较 常量规则 动态数组 内存管理,程序版式,程序版式程序员的书法 比书法好学得多,基本不需要特别练习 但是坏习惯一旦养成,就像书法一样难以改变 不影响程序的功能,但影响程序的可读性 追求 清晰、整洁、美观、一目了然 容易阅读,容易测试,程序版式,不良的风格,int isprime(int n) int k,i; if (n = 1) return 0; k=sqrt(double)n); for (i=2;i=k;i+) if(n%i=0) return 0; return 1; ,#include #include main() int i; for (i=2;i100;i+) if(isprime(i) printf(“%dt“,i); ,程序版式,良好的风格,int isprime(int n) int k, i; if (n = 1) return 0; k = (int)sqrt(double)n); for (i=2; i=k; i+) if (n % i = 0) return 0; return 1; ,#include #include main() int i; for (i=2; i100; i+) if (isprime(i) printf(“%dt“, i); ,程序版式,对齐(Alignment)与缩进(indent) 保证代码整洁、层次清晰的主要手段 “”位置的两种风格 和独占一行,且位于同一列,与引用它们的语句左对齐,便于检查配对情况 位于同一层和之内的代码在右边数格处左对齐,即同层次的代码在同层次的缩进层上 一般用设置为4个空格的Tab键缩进,不用空格缩进,建议的风格,不建议的风格,程序版式,现在的许多开发环境、编辑软件都支持“自动缩进” 根据用户代码的输入,智能判断应该缩进还是反缩进,替用户完成调整缩进的工作 VC中有自动整理格式功能 只要选取需要的代码,按ALT+F8就能自动整理成微软的cpp文件格式,程序版式,变量的对齐规则 数据类型 + N个TAB + 变量名 + N个TAB +=+初始化值 ; 例 char name20; char addr30; char sex = 'F' int age = 20; float score = 90;,程序版式,空行分隔程序段落的作用 在每个类声明之后加空行 在每个函数定义结束之后加空行 在一个函数体内,相邻两组逻辑上密切相关的语句块之间加空行,语句块内不加空行,程序版式,代码行内的空格增强单行清晰度 关键字之后加空格 函数名之后不加空格 赋值、算术、关系、逻辑等二元运算符前后各加一空格,但一元运算符前后一般不加空格 sum = sum + term; (向后紧跟,) , ;向前紧跟,紧跟处不留空格 , ;后留一个空格 Function(x, y, z) for (initialization; condition; update) . - 前后不加空格 对表达式较长的for和if语句,为了紧凑可在适当地方去掉一些空格 for (i=0; ic) && (b+ca) && (c+ab),程序版式,程序版式,代码行 一行只写一条语句,这样方便测试 一行只写一个变量,这样方便写注释 int width; /宽度 int height; /高度 int depth; /深度 尽可能在定义变量的同时,初始化该变量 int sum = 0; if、for、while、do等语句各占一行,执行语句无论有几条都用和将其包含在内,这样便于维护 if (width height) DoSomething(); /空行 OtherThing();,程序版式,程序版式,长行拆分 代码行不宜过长,应控制在70-80个字符以内 实在太长时要在适当位置拆分,拆分出的新行要进行适当缩进 if (veryLongVar1 = veryLongVar2) ,程序版式,修饰符*和,注释规范,注释(Comments)的重要性 写注释给谁看? 在哪些地方写注释?怎样写注释? 注释的风格 写注释时的注意事项 可灵活运用的一些规则,注释规范,注释的重要性 注释对于程序犹如眼睛对于人的重要性一样 没有注释的程序对于读者好比眼前一团漆黑,跟拿到一个可执行程序别无二致 不规范的注释和好几千度的近视眼没什么区别 代码本身体现不出价值 开发程序的思维才能使其变得有价值 这种思维的具体体现就是在于注释和规范的代码本身,注释规范,写注释给谁看? 给自己看,使自己的设计思路得以连贯 给继任者看,使其能够接替自己的工作,注释规范,写注释的最重要的功效在于传承 要站在继任者的角度写 简单明了、准确易懂、防止二义性 让继任者可以轻松阅读、复用、修改自己的代码 让继任者轻松辨别出哪些使自己写的,哪些是别人写的,注释规范,不好的注释 i = i + 1; /i加1 return -1; /返回-1 free(p); /释放p所指的内存 fclose(fin); /关闭文件 /*/ /*功能描述: 本函数用于实现xxx功能,目的是: */ /*入口参数: 参数p,表示指向结构体的指针 */ /*出口参数: 参数xx,表示 */ /*返回值: 返回xx值,当返回xx值时,表示 */ /*/,注释规范,不好的注释不但白写,还扰乱了读者的视线 /*以二进制只读方式打开文件并判断打开是否成功*/ if (fin = fopen(“cat.pic“,“rb“) = NULL) puts(“打开文件cat.pic失败“);/*如果打开失败,则显示错误信息*/ return -1; /*返回-1*/ /*从图像的第1行到第400行循环*/ for (i=0; i400; i+) /*从图像的第1列到第400列循环*/ for (j=0; j400; j+) /*按照公式Y = 0.299*R+0.587*G+0.114*B计算灰度值*/ y = (299 * r + 587 * g + 114 * b) / 1000; fclose(fin); /*关闭文件*/,注释规范,好的注释(尤其是算法注释)是对设计思想的精确表述和清晰展现,能揭示代码背后隐藏的重要信息 /*打开输入文件后判断文件长度是否符合格式要求*/ if (fin = fopen(“cat.pic“,“rb“) = NULL) puts(“打开文件cat.pic失败“); return -1; /* * 下面是图像转换的算法实现。彩色图像到灰度图像的转换主要利用RGB颜色空间到 * YUV颜色空间的变换公式来取得灰度值,公式为Y = 0.299*R+0.587*G+0.114*B */ for (i=0; i400; i+) for (j=0; j400; j+) y = (299 * r + 587 * g + 114 * b) / 1000; fclose(fin);,注释规范,在哪些地方写注释? 在重要的文件首部 文件名 + 功能说明 + 作者 + 版本 + 版权声明 + 日期 在用户自定义函数前 对函数接口进行说明 函数功能 + 入口参数 +出口参数 + 返回值 (包括出错处理) 在一些重要的语句块上方 对代码的功能、原理进行解释说明 在一些重要的语句行右方 定义一些非通用的变量 函数调用 较长的、多重嵌套的语句块结束处 在修改的代码行旁边加注释,注释规范,函数的注释风格 C风格 /*/ /*功能描述: 本函数用于实现xxx功能,目的是: */ /*入口参数: 参数xx,表示 */ /*出口参数: 参数xx,表示 */ /*返回值: 返回xx值,当返回xx值时,表示 */ /*/ /* 功能描述: 本函数用于实现xxx功能,目的是: 入口参数: 参数xx,表示 出口参数: 参数xx,表示 返回值: 返回xx值,当返回xx值时,表示 */ C+风格 / /功能描述: 本函数用于实现xxx功能,目的是: /入口参数: 参数xx,表示 /出口参数: 参数xx,表示 /返回值: 返回xx值,当返回xx值时,表示 /,注释规范,一块语句的注释风格 /* *C风格 */ C风格 /*/ /*下面代码是用来接收网络数据,其原理为*/ /* */ /*/ / / Visual C+风格 / /,注释规范,一行语句的注释风格 /*C风格*/ /Visual C+风格 i = j + 1;/代码行右方的注释 /代码行之上的注释 i = j + 1; 例子 ResetSrollInfo(g_hwndThumb);/初始化滚动条位置 for循环 while循环 if() /if结束 /while结束 /for结束,注释规范,写注释时的注意事项 注释不是白话文翻译,不要鹦鹉学舌 注释不是教科书,不要把别人当成初学者 注释不是标准库函数参考手册 注释不是越多越好,不好的注释等于垃圾 不写做了什么,写想做什么 边写代码边注释 修改代码同时修改注释,注释规范,可灵活运用的一些规则 注释可长可短,但应画龙点睛,重点加在语义转折处 简单的函数可以用一句话简单说明 /两数交换 void Swap(int *x, int *y) 内部使用的函数可以简单注释,供别人使用的函数必须严格注释,特别是入口参数和出口参数,Readme的书写内容,主要用来记录 日期、创建者、内容等 每次重大功能的添加、修改 具体格式: 日期TAB创建者TAB内容 日期:2003.1.21 创建者:XXX 内容:实例工程 日期TAB修改的文件名TAB修改的功能 对修改后的功能和原理的说明 日期TAB修改的文件名TAB修改的功能 对修改后的功能和原理的说明,类的版式,“以数据为中心”的版式 private类型的数据写在前面,public类型的数据写在后面 关注类的内部结构 “以行为为中心”的版式 public类型的数据写在前面, private类型的数据写在后面 关注的是类应该提供什么样的接口(或服务) 提倡后者 因为用户最关心的是接口,标识符命名规则,按照执行级别分为: 共性规则 必须执行 简化规则 建议采用 可选规则 灵活运用,标识符命名的共性规则,直观可以拼读,见名知意,不必解码 最好采用英文单词或其组合,切忌用汉语拼音 尽量避免出现数字编号 不要出现仅靠大小写区分的相似的标识符 不要出现名字完全相同的局部变量和全局变量 用正确的反义词组命名具有互斥意义的变量或相反动作的函数 int minValue; int maxValue; int GetValue(); int SetValue();,标识符命名的共性规则,尽量与所采用的操作系统或开发工具的风格保持一致 在Linux/Unix平台 习惯用“小写加下划线” function_name variable_Name Windows风格 大小写混排的单词组合而成 FunctionName variableName,Windows应用程序命名规则,Microsoft公司的Hungarian Notation 主要思想 在变量和函数名前加上前缀,用于标识变量的数据类型 限定范围的前缀 + 数据类型前缀 + 有意义的英文单词 限定范围的前缀 静态变量前加前缀s_ ,表示static 全局变量前加前缀g_ ,表示global 类内的成员函数m_ 默认情况为局部变量 数据类型前缀 ch 字符变量前缀 i 整型变量前缀 f 实型变量前缀 p 指针变量前缀,Windows应用程序命名规则,缺点 烦琐 例如 int i, j, k; float x, y, z; 若采用匈牙利命名规则,则应写成 int iI, iJ, ik; /前缀i表示int类型 float fX, fY, fZ; /前缀f表示float类型,简化的Windows应用程序命名规则,变量名形式 小写字母开头 “名词”或者“形容词+名词” 如oldValue, newValue等 函数名形式 大写字母开头 “动词”或者“动词+名词”(动宾词组) 如GetValue(), SetValue()等 宏和const常量全用大写字母,并用下划线分割单词 #define ARRAY_LEN 10 const int MAX_LEN = 100;,灵活运用的命名规则,限定范围的前缀与数据类型前缀可要可不要 无特殊意义的循环变量可以直接定义成i,j,k等单字母变量,表达式规则,尽量简单,不要太复杂 不要多用途 a = i+ + i+ + i+; printf(“%d, %d, %d“, i+, i+, i+); 不要与数学表达式混淆 if (abc) 不表示 if (ab)&&(bc),无需背诵的规则,运算符优先级 先算括号 用括号确定表达式的操作顺序,避免使用默认的优先级 库函数用法 会查联机帮助、手册最重要,需要考虑移植性的问题,不同平台,不同编译器,可能会迥然不同 凡是需要字节数的地方,一律用sizeof获得,与零比较的规则,布尔变量与零比较 不应写成 if (flag = 0) if (flag != 0) 应写成 if (flag) /表示flag为真 if (!flag) /表示flag为假,与零比较的规则,整型变量与零比较 不应写成 if (value) /容易误解为布尔变量 if (!value) 应写成 if (value = 0) if (value != 0) 写成如下形式能防止=误写为= if (0 = value) if (0 != value),与零比较的规则,实型变量与零比较 不应写成 if (x = 0.0) / float和double变量都有精度限制 应写成 if (x = -EPS) && (x = EPS) if (fabs(x) = EPS),与零比较的规则,指针变量与零比较 不应写成 if (p = 0) /容易误解为整型变量 if (p != 0) if (p) /容易误解为布尔变量 if (!p) 应写成 if (p = NULL) /强调p是指针变量 if (p != NULL),常量规则,尽量使用含义直观的常量来表示多次出现的数字或者字符串 #define PI 3.14159 const float PI=3.14159; C+中用const常量完全取代宏常量 需要对外公开的常量集中放在一个公共的头文件中,不需要对外公开的常量放在定义文件的头部,常量规则,怎样建立在类中恒定,且仅在类中有效的常量? #define定义的宏常量是全局的 const数据成员可以吗?,常量规则,class A const int SIZE = 100;/不能在类声明中初始化const数据成员 int arraySIZE; /类的对象未被创建时,SIZE值未知 ; const数据成员只能在类构造函数的初始化表中进行 class A A(int size); /构造函数 const int SIZE; ; A:A(int size) : SIZE(size) A a(100); /对象a的SIZE值为100 A b(200); /对象b的SIZE值为200,常量规则,怎样建立在整个类中都恒定的常量呢? const数据成员只在某个对象生存期内是常量,而对类而言是可变的 因为类可以创建多个对象 不同对象的const数据成员值不同 不能指望const数据成员了,常量规则,怎样建立在整个类中都恒定的常量呢? 应该用类中的枚举常量来实现 class A enum SIZE1 = 100, SIZE2 = 200; /枚举常量 int arrayASIZE1; int arrayBSIZE2; ; 缺点: 隐含数据类型是整数,其最大值有限,且不能表示浮点数,动态数组,一维动态数组 int *p = NULL; p = (int *) malloc(n * sizeof (int); pi /像使用一维数组一样使用 二维动态数组 int *p = NULL; p = (int *) calloc(m * n, sizeof (int); pi*n+j); /像使用一维数组一样使用 ,函数设计原则,函数的功能要单一,不要设计多用途的函数 函数的规模要小,尽量控制在50行代码以内 1986年IBM在OS/360的研究结果: 大多数有错误的函数都大于500行 1991年对148,000行代码的研究表明: 小于143行的函数比更长的函数更容易维护,函数设计原则,参数的规则 参数要书写完整,不要省略参数类型和参数名 没有参数时,用void填充 参数个数尽量控制在5个以内 参数名要恰当,顺序要合理 void MyStrcpy(char *str1, char *str2); void MyStrcpy(char *dstStr, char *srcStr); 如果参数是指针,且仅作输入用,则应在类型前加const void MyStrcpy(char *dstStr, const char *srcStr);,函数设计原则,返回值的规则 不要省略返回值的类型,可声明为void 确保返回值与声明的类型一致,不要依赖自动类型转换 不能返回指向栈内存的指针 犯了释放内存以后还继续使用的错误,函数设计原则,函数内部实现的规则 在函数的入口处,使用断言assert检查参数的合法性 尽量少用全局变量,确保函数的单入口和单出口,不得不用时,要严格控制对它的改写,例如,几个有关联的函数需要使用全局变量时 全局变量应和访问全局变量的函数放在单独的一个文件中,与其它文件分别编译 并且将该全局变量声明为static(静态全局变量) 尽量少用静态局部变量,以避免使函数具有“记忆”功能,成对编码,写函数体时 先写上面的大括号 然后马上就写下面的大括号 最后再插入函数体内的代码 动态申请内存时 先分配一块内存 然后马上就写释放这块内存的代码 最后再在中间插入你要用这块内存做什么的代码 所有变量要集中申请 在函数的首部或块的首部 按以上方法编程不仅能保证快速正确,而且不必等代码全部写完就可以调试,其他,不要过多假设 不可能发生的情况总是会发生 充分测试 构造尽可能多的数据,变态的数据 Code review 让别人看你的代码 多看别人(高手)的代码 处理错误机制 返回错误信息 异常处理 活用断言 ASSERT(),在debug版本多用,能发现很多隐含的bugs,内存管理,5.1 内存分配方式,从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。,5.2 常见的内存错误,内存分配未成功,却使用了它。 内存分配虽然成功,但是尚未初始化就引用它。 内存分配成功并且已经初始化,但操作越过了内存的边界。 忘记了释放内存,造成内存泄漏。 释放了内存却继续使用它,5.3 习惯规则,用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。 不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。 避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。 动态内存的申请与释放必须配对,防止内存泄漏。 用free或delete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。,5.4 free 和 delete 的操作,它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。 指针p被free以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p成了“野指针”。如果此时不把p设置为NULL,会让人误以为p是个合法的指针。 如果程序比较长,我们有时记不住p所指的内存是否已经被释放,在继续使用p之前,通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。 “野指针”示例,5.5 动态内存会被自动释放吗?,指针消亡了,并不表示它所指的内存会被自动释放。 内存被释放了,并不表示指针会消亡或者成了NULL指针。,5.6 杜绝野指针,“野指针”不是NULL指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是“野指针”是很危险的,if语句对它不起作用。 “野指针”的成因主要有三种: 指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的默认值是随机的,它会乱指一气。 指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。 指针操作超越了变量的作用范围。这种情况让人防不胜防,5.7 new/delete,Malloc/free 是库函数,new/delete是运算符。 光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。 由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C+语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。,new 和 delete,调用new所包含的动作 从系统堆中申请恰当的一块内存 若是对象,调用相应类的构造函数,并以刚申请的内存地址作为this参数 调用delete所包含的动作 若是对象,调用相应类的析构函数 将该内存块返回给系统堆,new 和 delete,调用new所包含的动作 从系统堆中申请可容纳n个对象外加一个整型的一块连续内存 将n记录在额外的那个整型内存中 调用n次构造函数初始化这块内存中的n个连续对象 调用delete所包含的动作 从new记录n的地方将n值找出 调用n次析构函数析构这块内存中的n个连续对象 将这一整块内存(包括记录n的整型)归还系统堆,有关内存的思考题(1),有关内存的思考题(2),有关内存的思考题(3),有关内存的思考题(4),好习惯造就成功,C+ coding is Easy ! 需大量实践 知错就改; 经常温故而知新; 坚持学习,天天向上,更多进阶,对象模型 泛型编程 软件工程,参考书籍,Steve Maguire, Writing Clean Code(编程精粹,姜静波 等译),电子工业出版 社,1993. H. Sutter and A. Alexandrescu. C+编程规范 101条规则、准则与最佳实践 Scott Meyers. Effective C+, Addison-Wesley, 1992. 林锐. 高质量C+/C 编程指南 Kinds of coding guidelines. Online.,Happy Coding,谢谢!,

    注意事项

    本文(编程规范和技巧.ppt)为本站会员(少林足球)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    经营许可证编号:宁ICP备18001539号-1

    三一文库
    收起
    展开