读《微软C编程精粹》的一些收获
- 要使用断言对函数参数进行确认
- 为了不必要的开销,可以仅使用断言,而不要return
网上有人写的strcpy代码,做了太多的出错处理,导致性能低下,其实没必要,用assert就行了,这样在debug模式下能捕捉错误,release下又不影响性能。
- 书上提供的memcpy的范例
void memcpy(void* pvTo, void* pvfrom, size_t size)
{
void* pbTo = (byte*)pvTo;
void* pbfrom = (byte*)pvfrom;
ASSERT(pvTo != NULL && pvfrom != NULL);
/* 内存块重叠吗?如果重叠,就使用memmove */
ASSERT(pbTo>=pbfrom+size || pbfrom>=pbTo+size);
while(size-->0)
*pbTo++ == *pbfrom++;
return(pvTo);
}
- 不使用ASSERT的危害
这个小组的代码与Word代码之间一个明显的区别是Word代码从过去到现在一直都使用断言和调试代码,而他们的代码却几乎没有使用断言。因此,其程序员没有什么好的办法可以确定其代码中的实际错误情况,错误只能慢慢地暴露出来。如果他们在代码中使用了断言,这些错误本该在几个月之前就被检查出来。
同样,xeyez由于没有使用Debug版,导致了很多的内存错误在客户的电脑上暴漏了出来。
- 一个错误的使用ASSERT的例子
char* strdup(char* str)
{
char* strNew;
ASSERT(str != NULL);
strNew = (char*)malloc(strlen(str)+1);
ASSERT(strNew != NULL); // 这里使用错误
strcpy(strNew, str);
return(strNew);
}
第一个断言的用法是正确的,因为它被用来检查在该程序正常工作时绝不应该发生的非法情况。第二个断言的用法相当不同,它所测试的是错误情况,是在其最终产品中肯定会出现并且必须对其进行处理的错误情况。
虽然这一程序更精确地反应了相应的算法,但有经验的程序员很少会这样编码。否则好机会就来了,我们可以把他们塞进一辆既没有安全带又没有车门的双人Cessna车中。上面的程序使人感到太危险了。
在该函数的交付版本中,相应的防错措施可以保证当出了毛病时,用户可以不受损失;而在该函数的调试版本中,错误仍然可以被报告出来。
相关文档:
Reading and Writing Excel file with pure C api in windows system. tested on windows 2000, hope it can help you:
#ifndef _WINXLS_H_
#define _WINXLS_H_
/*============================================================================*
* Include Files
*================== ......
用c语言做了个通讯录,系统一运行时便将数据文件加载进内存,并用链表存储。退出系统时,自动将链表中的所有节点再存入文件。
可是现在,每次退出系统,文件里都会比链表多存储一条记录。
如:现在只有两条记录,退出后在启动时一查询,就会多一条乱记录(系统自己加的)。
加载文件的部分代码如下:
/*判断文件是否 ......
1,防止一个头文件被重复包含
#ifndef COMDEF_H
#define COMDEF_H
//头文件内容
#endif
2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。
typedef unsigned char boolean; /* Boolean value type. */
typedef ......
通常,在C语言的头文件中经常可以看到类似下面这种形式的代码:
#ifdef __cplusplus
extern "C" {
#endif
/**** some declaration or so *****/
#ifdef __cplusplus
}
#endif /* end of __cplusplus */
那么,这种写法什么用呢?实际上,这是为了让CPP能够与C接口而采用的一种语法形式。之所以采用这种方式 ......