![编程精粹理解.ppt_第1页](http://file1.renrendoc.com/fileroot2/2020-1/11/705464c6-c82d-4faa-ab0f-e022c0b21589/705464c6-c82d-4faa-ab0f-e022c0b215891.gif)
![编程精粹理解.ppt_第2页](http://file1.renrendoc.com/fileroot2/2020-1/11/705464c6-c82d-4faa-ab0f-e022c0b21589/705464c6-c82d-4faa-ab0f-e022c0b215892.gif)
![编程精粹理解.ppt_第3页](http://file1.renrendoc.com/fileroot2/2020-1/11/705464c6-c82d-4faa-ab0f-e022c0b21589/705464c6-c82d-4faa-ab0f-e022c0b215893.gif)
![编程精粹理解.ppt_第4页](http://file1.renrendoc.com/fileroot2/2020-1/11/705464c6-c82d-4faa-ab0f-e022c0b21589/705464c6-c82d-4faa-ab0f-e022c0b215894.gif)
![编程精粹理解.ppt_第5页](http://file1.renrendoc.com/fileroot2/2020-1/11/705464c6-c82d-4faa-ab0f-e022c0b21589/705464c6-c82d-4faa-ab0f-e022c0b215895.gif)
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、编写无错的程序,作为一个程序员,你在写每一行代码时应该始终保持如履薄冰的危机感。,由来,编程精粹,Steve Maguire,电子工业出版社 作者是Microsoft公司资深项目主管 以下的内容是个人对此书的理解,与大家共同探讨,概述,基本要求 总则 函数的设计 函数的实现 编译、调试、修改、合版本 进一步的建议 设计 实现 超越编码 攻击错误,总则,确立并坚持编码的优先顺序我们推荐的编码优先顺序: 正确性 可维护性/可读性 可测试性 全局效率 一致性 大小 局部效率 个人表达方式/个人方便性 建立程序的DEBUG版本,同时维护DEBUG版本和发行版本。在DEBUG版本中加入能暴露程序错误的代
2、码。 坚持彻底测试代码(单元测试),即使延误进度。不要依靠测试组测试你的代码。 不要责怪测试员发现你的错误(惊讶,怎么会有这样的问题?然后感谢测试员在问题到用户手中之前发现了它),函数的设计,函数不仅仅要正确,而且在使用时要安全 (糖果机的界面) 函数的返回值不要同时作为错误代码和正常的返回结果,让使用者不容易忽视错误情况 仔细考虑函数的界面,是否容易被误用(函数名称、参数、返回值) 不要定义多用途且面面俱到的函数 不要设计太灵活的(无确切含义、空空洞洞)函数参数 让你的函数在调用点显得易读 不要使用布尔参数输入 编写函数,使其在有效输入情况下不会失败,减少调用者的错误检查 使用注释突出使用时
3、可能的异常情况,返回值,函数的返回值不要同时作为错误代码和正常的返回结果,让使用者不容易忽视错误情况 风险的代码 char c ; c = getchar() ; if (c = EOF) ? 问题 getch()返回int型 在stdio.h种,#define EOF (-1) 如果变量 c 是无符号字符,if语句永远不会成立 换一种做法 flag fGetChar(char * pch) ; char ch ; if (fGetCh( if (pbBuf != NULL) 问题 如果仅有pbBuf引用其指向的内存,在分配失败时出现内存泄露 换一种做法 flag fResizeMemory(
4、void *ppv, size_t sizeNew) byte * ppb = (byte *)ppv ; byte * pbResize ; pbResize = (byte *)realloc(*ppb, sizeNew) ; if (pbResize != NULL) * ppb = pbResize ; return (pbResize != NULL) ; ,不要定义面面俱到的函数,风险的代码 void * realloc(void *pv, sizet size) ; 如果内存块的新长度小于老长度 如果内存块的新长度大于老长度 如果内存不够 如果pv是NULL = malloc 如
5、果pv不是NULL,但新长度为0 = free 如果pv是NULL,新长度为0 = ? 问题 对不同pv的操作是否有用? 如何处理这些情况? 换一种做法 ASSERT的使用,pv = NULL | size = 0 fGrowMemory(void *ppv, size_t sizeLarger) ; fShrinkMemory(void *pv, size_t sizeSmaller) ;,明确定义函数参数,避免摸棱两可,风险 char *CopySubStr(char * strTo, char *strFrom, size_t size) ; char * strStart = strT
6、o ; while (size - 0) * strTo + = * strFrom + ; *strTo = 0 ; return strStart) ; 问题 如果size大于strFrom的长度,? 换一种做法 明确规定,strFrom必须包含size个字符 ASSERT(strTo!=NULL void UnsignedToHexStr(unsigned u, char * str) ;,返回失败的函数,编写函数,使其在有效输入情况下不会失败 减少调用者的错误检查 风险的代码 char tolower(char ch) if (ch =A 换一种做法 如果输入不是字母,则返回输入的字符
7、 不接收非字母的输入(ASSERT),函数的注释,使用注释突出使用时可能的异常情况 风险的代码 pv = realloc( pv, sizeNew) ; 问题 内存泄露 替你的客户着想 /* realloc(pv, size) 典型用法: void * pvNew ; pvNew = realloc(pv, sizeNew) ; if ( NULL != pvNew ) pv = pvNew ; / success else / failue / pvNew为NULL,不要丢掉pv的内存 */,实现,保证程序良好的可读性,保证代码的中注释行与空行所占比例大于30% 使用断言。在以下情况下应该使
8、用断言: 利用断言确认函数的参数 用断言保证没有定义的特性不被使用(或者去除无定义的特性). 将你对程序开发运行环境(OS, Compiler, Hardware)的假设用断言给出 用断言检查不可能发生的情况 编写防错性处理程序,但防止错误之后用断言宣布发生错误 对复杂的断言加上注释 尽量编写和测试小块代码,即使测试影响进度,函数规模限制在200行以内 使用严格定义的、可移植的数据类型 避免使用嵌套的?:运算符 一个任务应该一次完成(如果多段代码重复做同一件事,意味者存在问题) 避免无关紧要的if语句(草率设计、粗心实现的结果) 对特殊情况,只在程序的一个地方处理 不同类型的操作符混合使用时,
9、使用括号隔离之 尽量避免使用返回错误的函数,断言,断言的实现 #ifdef NDEBUG #define assert(p) (void)0) #else # define assert(p) (p) ? (void)0 : (void) _assertfail( Assertion failed: %s, file %s, line %d _ENDL, #p, _FILE_, _LINE_ ) ) #endif 断言与错误处理 断言不等于错误处理 char *pcM = (char *) malloc(sizeWant) ; ASSERT(NULL != pcM) ; 。 。 断言不等同与状
10、态提示 VC+中的TRACE,断言的使用(一),利用断言确认函数的参数 void memcpy(void *pvTo, void *pvFrom, size_t size) assert( NULL != pvTo 。 。,断言的使用(二),用断言检查不可能发生的情况 switch state) 。 default: ASSERT(FALSE) ; 编写防错性处理程序,但防止错误之后用断言宣布发生错误 / get Name from self-gen temp. file. Extern file * pfSaveBuffFile ; BOOL getName(char * pcName) i
11、f (8 != fread(pcName, 1, 7, fpSaveBuffFile) / this must not occur ASSERT(FALSE) ; / do some thing 。 。 对复杂的断言加上注释,实现(陷阱的回避),尽量编写和测试小块代码,即使测试影响进度,函数规模限制在200行以内 使用严格定义的、可移植的数据类型 High C环境下B型机的数据类型 typedef unsigned short _UI; typedef unsigned char _UC; typedef unsigned short _US; typedef unsigned int _UL
12、; 不同类型的操作符混合使用时,使用括号隔离之 混合操作类型 word = high 8 + low ; / 运算符优先级错误 while (ch = getchar() != EOF) . 换一种做法 word = high 8 | low ; word = high * 256 + low ; while (ch = getchar() != EOF) . 尽量避免使用返回错误的函数 让函数始终正确工作 将同样的错误处理部分独立开来,实现(消除冗余,改进算法),提示 一个任务应该一次完成(如果多段代码重复做同一件事,意味者存在问题) 避免无关紧要的if语句(草率设计、粗心实现的结果) 避免
13、使用嵌套的?:运算符 对特殊情况,只在程序的一个地方处理 理由 避免维护中无意识地遗漏而导致错误。 简单地解决让程序员不再话时间寻找更号的解决方法。,实现(消除冗余,改进算法),代码(一) void * memchr(void *pv, unsigned char ch, size_t, size) unsigned char * pch = (unsignecd char *) pv ; unsigned char * pchEnd = pch + size ; while (pch pchEnd ,实现(消除冗余,改进算法),代码(二) if (NULL = pHead-next) pHe
14、ad-next = pNew ; else TNode * pGo = pHead-next ; while (pGo-next != NULL) pGo = pGo-next ; pGo-next = pNew ; 换一种做法 pGo-next = pHead ; while (pGo-next != NULL) pGo = pGo-next ; pGo-next = pNew ;,进一步考虑(设计),设计一个特征前,先仔细考虑是否是用户需要 不设自由特征 不允许没有必要的灵活性 对关键的算法使用二个算法来确认前者 不要等待错误发生,在代码启动前使用初始检查程序以保证程序运行环境的一致性,进
15、一步考虑(实现),时刻注意表达式是否会上溢、下溢 明确设计,并精确(不是近似)实现设计 避免使用有风险的语言惯用语 只引用属于自己的存贮空间 注意是否引用已经释放的空间 指向输出的指针不是指向工作缓冲区的指针 避免向静态(全局)变量存贮区传递数据 不要编写依赖于其他函数内部实现的函数 不要使用希奇古怪的C惯用语 不要追求紧凑的代码(不代表高效的机器码) 考虑你的代码将给新手读,超越编码,消除代码运行的随机性,使错误可再现。去除未定义的(随机的)特性、无用的数据内容等。 在DEBUG版中将无用的信息抹掉(换以固定的数字),以免被错误使用 如果某件事很少发生,设法使其经常发生。确定子系统会发生哪些
16、事情,并使它们经常发生;如果发现子系统中有很少发生的行为,千方百计使其重现。 保存内部调试信息,进行更强的错误检查 主动出击,建立子系统检查,在适当时候确认子系统的状态 仔细设计程序的测试代码,任何选择都应该经过考虑 设计透明的一致性检查,在正常的程序运行过程中自动检查一致性 保证DEBUG版本的运行,即使其大小和速度不尽人意,超越编码(让错误固定出现),消除代码运行的随机性,使错误可再现。去除未定义的(随机的)特性、无用的数据内容等。 在DEBUG版中将无用的信息抹掉(换以固定的数字),以免被错误使用 如果某件事很少发生,设法使其经常发生。确定子系统会发生哪些事情,并使它们经常发生;如果发现
17、子系统中有很少发生的行为,千方百计使其重现。 代码 void FreeMemory(void *pv) ASSERT(pv != NULL) ; #ifdef DEBUG memset(pv, bGarbage, sizeofBlock(pv) ; #endif free(pv) ; ,超越编码(主动出击),保存内部调试信息,进行更强的错误检查 主动出击,建立子系统检查,在适当时候确认子系统的状态 仔细设计程序的测试代码,任何选择都应该经过考虑 设计透明的一致性检查,在正常的程序运行过程中自动检查一致性 代码 flag fCreatBlockinfo(byte * pbNew, size_t sizeNew) ;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年物位仪项目发展计划
- 税务筹划与合规管理策略计划
- 2025年磁共振成像装置项目发展计划
- 2025年房屋整体质量无损检测分析系统项目建议书
- 加速网络传输的配置方法
- 文化艺术品交易免责协议书
- 宿舍舍长述职报告
- 货物铁路运输合同
- Tectoquinone-Standard-生命科学试剂-MCE
- O-2545-hydrochloride-生命科学试剂-MCE
- 保障性住房配套公建工程项目可研报告
- 【基于杜邦分析的雅戈尔盈利能力分析9900字】
- 桥面系小型构件遮板等预制场施工方案
- 高二语文早读材料积累(1-20周)课件159张
- 2023版教科版二年级下册科学课堂作业本参考答案
- 规划收费标准
- 大连理工大学信封纸
- 读《教师成长力-专业成长图谱》有感
- 自动化仪表工程施工及质量验收规范
- 邵阳市职工劳动能力鉴定表
- 中华人民共和国环境保护法
评论
0/150
提交评论