1,szNewFile[_MAX_FNAME]与szIMPINI[256] 在stdio.h中有定义: #define _MAX_FNAME 256 /* max. length of file name component */ 应该用方便理解的szIMPINI[_MAX_FNAME]代替szIMPINI[256]。 char szCdrFilePath[256] = {0};//_MAX_PATH是260. 2,szNewFile[_MAX_LEN]与szNewFile[_MAX_ LEN + 1] 字符串数组申明,应多留一位存储字符串结束符’/0’。 3,变量命名 Char *pRecBegin = data; Char *pRecEnd = strchr(data,’/n’); Int pos = pRecEnd – pRecBegin + 1; Data[pos] ………………………………………………………………………… Int newLinePos = pRecEnd – pRecBegin; Int newRecPos = pRecEnd – pRecBegin + 1; Data[newLinePos] Data[newRecPos] 4,日志记录数组的申明 char szFindFile[_MAX_PATH]; char szNewFile[_MAX_FNAME]; char szLog[500] = {0}; sprintf(szLog,"Copy File [%s] to [%s] failed !",szFindFile,szNewFile); 在极限条件下,sprintf语句会引发内存invalid access异常。 char szFindFile[_MAX_PATH + 1] = {0}; char szNewFile[_MAX_FNAME + 1] = {0}; char szLog[_MAX_PATH + _MAX_FNAME + 50] = {0}; 5,fclose(ptrFile); if(NULL != ptrFile) { fclose(ptrFile); } 6,多处return的问题 原因1:函数流程结构没有理顺。 原因2:函数过于庞大,实现过多功能,需要分解。 7, 文件open、read、write、seek、close,内存malloc,网络send,receive和accept等发生异常比例较高的操作,要对返回值以及状态值进行判断。 8,无用参数传递, TRunStatus ReadCDRFile(TCDRFile* OneCdrFile,const PSpecialCDRSetting cdrSetting),后一个参数所指的是一个全局变量,且在该函数中没有用到。 9,变量赋初值,尤其是指针、结构体和数组。 10, 单位问题 自定义函数的定时操作,通过函数名、变量名和注释说明单位。 11, 确保变量唯一用途 多申请变量也要保证变量的唯一用途。小一点的地方反映在函数内部的变量的使用;大一点的地方反映在程序核心的数据结构和全局变量的定义。 12, 冗余代码 if(0 == u8result) { ……………… if(remove(szFindFile)) { sprintf(szLog,"Remove File [%s] failed !",szFindFile); WriteCDRLog(szLog); } ASEND(CDRSELFNOTIFYEVENT, &nullMsg,sizeof(UINT8),self_Pid); return; } else if(2 == u8result) { ……………… if(remove(szFindFile)) { sprintf(szLog,"Remove File [%s] failed !",szFindFile); WriteCDRLog(szLog); } ASEND(CDRSELFNOTIFYEVENT, &nullMsg,sizeof(UINT8),self_Pid); return; } 13, 函数臃肿 分解函数,提高函数可读性、可维护性和可复用性。 14, 参数合法性判断 对一个文件中的数据批处理,每次从文件中读取一部分数据处理完毕后,再从文件中读下一批数据。 15, 给指针赋值和给指针所指地址赋值的区别 Int num; Int *p = NULL; P = #正确 *p = num;错误 16, 在函数中传递数组或者指向数组的指针作为参数时,最好能够带上长度参数,确保安全的内存引用。 void Function(char *szName, DWORD cbName) { char szBuff[MAX_NAME]; szBuff[cbName] = 0x42; //当内存缓冲区已经溢出时,一旦再向其中写入常量值,就会导致程序代码出错并中止运行。 // 复制并使用 szName if (cbName < MAX_NAME) strcpy(szBuff,szName); } 17, pUserInfo = (User_Info_T *)(pMsg + sizeof(MSG_HEAD_T)); 为了安全起见,最好先把pMsg强制转换为unsigned char指针类型再参与指针运算: pUserInfo = (User_Info_T *)((UINT *)pMsg + sizeof(MSG_HEAD_T)); 18, 变量与常量的等于或不等于判断,常量前置。 if(Msg97Req.OldTeleNum[0]='0')//error …………………………………………………………………… if('0' == Msg97Req.OldTeleNum[0])//如果把等于判断误写成赋值号,则在编译的时候会提示错误信息。 19, 处理字符串中的空格时,除了处理空格符外,不要忘记处理tab键制表符。 //截断“空格符”和“tab制表符” if(32 == str[i] || 9 == str[i]) { str[i] = 0; } 20, 禁止使用C的关键字或者所带的包中定义的类型作为变量命名 void msp_ChgBCDToString(UINT8 *string, UINT8 *Bcd, UINT8 Num) //string为C++类。 21, 谨慎使用str[strlen(str) – 1]操作 g_config.MsgLogPath[strlen(g_config.MsgLogPath) - 1] != PATHCHARSEP 应该先判断strlen(str)是否为0,为0的时候会造成数组越界错误。 本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/lxb_champagne/archive/2009/11/05/4773431.aspx