编程精粹理解.pptVIP

  • 0
  • 0
  • 约7.06千字
  • 约 25页
  • 2017-01-12 发布于江苏
  • 举报
编程精粹理解

编写无错的程序 作为一个程序员,你在写每一行代码时应该始终保持如履薄冰的危机感。 由来 《编程精粹》,Steve Maguire,电子工业出版社 作者是Microsoft公司资深项目主管 以下的内容是个人对此书的理解,与大家共同探讨 概述 基本要求 总则 函数的设计 函数的实现 编译、调试、修改、合版本 进一步的建议 设计 实现 超越编码 攻击错误 总则 确立并坚持编码的优先顺序 我们推荐的编码优先顺序: 正确性 可维护性/可读性 可测试性 全局效率 一致性 大小 局部效率 个人表达方式/个人方便性 建立程序的DEBUG版本,同时维护DEBUG版本和发行版本。在DEBUG版本中加入能暴露程序错误的代码。 坚持彻底测试代码(单元测试),即使延误进度。不要依靠测试组测试你的代码。 不要责怪测试员发现你的错误(惊讶,怎么会有这样的问题?然后感谢测试员在问题到用户手中之前发现了它) 函数的设计 函数不仅仅要正确,而且在使用时要安全 (糖果机的界面) 函数的返回值不要同时作为错误代码和正常的返回结果,让使用者不容易忽视错误情况 仔细考虑函数的界面,是否容易被误用(函数名称、参数、返回值) 不要定义多用途且面面俱到的函数 不要设计太灵活的(无确切含义、空空洞洞)函数参数 让你的函数在调用点显得易读 不要使用布尔参数输入 编写函数,使其在有效输入情况下不会失败,减少调用者的错误检查 使用注释突出使用时可能的异常情况 返回值 函数的返回值不要同时作为错误代码和正常的返回结果,让使用者不容易忽视错误情况 风险的代码 char c ; c = getchar() ; if (c == EOF) { ???? } 问题 getch()返回int型 在stdio.h种,#define EOF (-1) 如果变量 c 是无符号字符,if语句永远不会成立 换一种做法 flag fGetChar(char * pch) ; char ch ; if (fGetCh( pch)) // ... else // ... 特洛伊木马(仔细考虑一下) 风险的代码 pbBuf = (byte *)realloc(pbBuf, sizeNew) ; if (pbBuf != NULL) { … … } 问题 如果仅有pbBuf引用其指向的内存,在分配失败时出现内存泄露 换一种做法 flag fResizeMemory(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 如果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 = strTo ; while (size -- 0) * strTo ++ = * strFrom ++ ; *strTo = ‘\0’ ; return strStart) ; } 问题 如果size大于strFrom的长度,??? 换一种做法 明确规定,strFrom必须包含size个字符 ASSERT(strTo!=NULL strFrom!=NULL) ASSERT(size = strlen(strFrom) 让函数在调用点易读 避免使用布尔参数输入 风险的代码 // 如果fDecimal为TRUE,转换为十进制字符串,否则转换为十六进制字符串 void UnsignedToStr(unsigned u, char *

文档评论(0)

1亿VIP精品文档

相关文档