阅读:1364回复:0
老生常谈:提高程序质量的注意事项Author: brike.huang Email: brike.huang@163.com QQ: 24558102 Date: 2008.05 -------------------- 以下是我从事windows开发的一些心得,希望对各位有所帮助 软件开发,比较重要是软件需求、进度控制、质量管理等,本主题主要讨论质量——程序的质量 程序的质量,主要表现在以下几方面: 1稳定性 2可移植性 3兼容性 4可维护性 ....... ================= 1.使用中性的数据类型,避免使用绝对数据类型(除非有需求) 在程序中尽量使用INT,TCHAR,LPTCSTR,DWORD等类型,如果是指针,可以使用VOID,PVOID或DWORD_PTR、ULONG_PTR、UINT_PTR类型在UNICODE环境下,TCHAR定义为unsigned short,在ASCII环境下定义为char类型...... 在64位环境下,PVOID、XXXX_PTR等类型长度为8Bytes,在32位环境下,为4Bytes。xxxx_PTR数据类型需要SDK支持,该类型对64位服务器版本的程序影响比较大,程序有可能会使用到大于4G的地址空间 2.使用中性的函数 很多函数有多种形态,最常见的是UNICODE与ASCII,64位与32位。 如:_tcslen,UNICODE环境下定义为wcslen(用于处理UNICODE字符串长度),ASCII环境下定义为strlen(用于处理ASCII字符串长度) 使用GetWindowLongPtr代替GetWindowLong,有很多类似的API,具体请参考SDK 3.使用UNICODE编译环境 windows2000及以后的系统,已经是纯UNICODE环境了。ASCII环境下处理亚洲文字时,容易出现乱码。 具体方法:在编译条件中加入_UNICODE、UNICODE符号定义,在链接时指定程序入口 windows程序入口:wWinMainCRTStartup console程序入口:wMainCRTStartup dll程序入口:wDllMainCRTStartup 在程序中,有可能必须使用ASCII(比如与COM通讯),程序中应该增加相应处理: #ifdef UNICODE ... #else ... #endif 4.使用安全的字符处理方法 使用strsafe.h中的函数,而不是默认的 如StringCbCopy代替_tcscpy(ASCII对应strcpy),StringCbCat代替代_tcscat(ASCII对应strcat)。能有效的防止内存溢出 5.初始化变量 比如,定义了TCHAR szBuffer[254],然后通过一个API取得一个字串。但该API调用失败,此时反应到UI上是一串乱七八糟的东西,更严重的后果是导致程序运行崩溃。 一般把变量全部初始化0,如:TCHAR szBuffer[254] = {0}; 6.条件运算时,常数或不能改变的变量作为第一目运算符 如经常犯的错误: if (n == 3) ...错写成 if (3 = n) .... 编译时直接给出错误信息 如果写成 if (n = 3),在成千上万的代码中,要找到它,会让人发狂 7.注意API版本的说明 有部分API在新版本的OS中才支持,如果程序要在旧版本的OS运行,因在DLL中找不到链接符号,而终止运行 比如:SetupDiCreateDeviceInfoListEx,SDK中的相关描述如下: Client: Requires Windows XP or Windows 2000 Professional. Server: Requires Windows Server 2003 or Windows 2000 Server. 如果程序是隐性链接并对应的Setupapi.dll没附带进安装路径,程序在windows2000以下版本上将不能运行 8.在程序中使用调试用语 如_RPTF0、_RPTF1、.....可以在VC的Output窗口或DbgView之类型的工具查看程序运行状态,在容易出生错误的地方使用assert之类的用语,在程序崩溃时会告诉开发人员哪行代码出现问题 9.分配的内存一定要初始化,并说明在什么条件下使用什么函数释放(free?delete?HeapFree?.....) 一般情况下初始化为0,理由与第5条“初始化变量”相同。 如果是小型程序,并申请的内存不多,很多人偷懒不做这个烦人的动作。我有一擅长VB与.net的同事,做图形处理,程序处理不到几张图片,就消耗掉所有内存,最先想到的办法就是买内存条,结果只是增加了几张图片的吞吐量,后来采取关程序,再开程序的方法运行。一个小组七八人花了一个多月都找不到问题。最后在我拜访他们部门时,花了不到半小时就解决了。 10.提升编译警告级别 如果使用VC6,默认为/W3,SDK默认为/W4。SDK在编译时就能发现更多隐性问题。 --------------------- 以上几个规则都是很容易做到的,我个人比较喜欢使用UNICODE、64BIT的AMD编译链接SDK环境,在这个环境下写程序,一般不会遇到兼容或移植上的问题,代码不用做多大的变化,就可以应用到WINDOWS各个版本上,只需要在不同的编译条件下重新Rebuild。 以下提供一个SAMPLE: #include <windows.h> #include <tchar.h> #include <crtdbg.h> #include <strsafe.h> #define OPTIONAL_LEN 10 #ifdef _DEBUG #define DEBUG_PRINT1(IF, msg, arg1) if (!(IF)) _RPTF1(_CRT_WARN, msg, arg1) #else #define DEBUG_PRINT1 // Release版本该语句为空 #endif INT _tmain(INT argc, TCHAR* argv[]) { TCHAR szOptional[3][OPTIONAL_LEN] = {0}; DEBUG_PRINT1(3 <= argc, ("arg number: %d\n"), argc); // 如果参数数量小于3,则输出调试信息 [5/12/2008] if (3 > argc) return -1; for (INT n = 0; 3 > n; ++n) { StringCbCopy(szOptional[n], sizeof(TCHAR) * OPTIONAL_LEN, __argv[n]); // 保存参数的长度不超过 OPTIONAL_LEN个字符 [5/12/2008] _tprintf(_T("arg%d: %s\n"), n, szOptional[n]); } return 0; } --------------- 以上程序兼容UNICODE、防止内存溢出 |
|
最新喜欢:![]() |