Author:bakari Date:2012.10.18
这段时间非常有幸能够跟着一个非常牛的学长学习编程,现将每次学到的内容作为整理,方便以后复习,也分享给需要的网友。
这是学长第一次讲,本次讲的内容比较基础和偏理论,是有关于防御性编程的,关于这方面我之前就记录过一篇文章,详细见:
http://www.cnblogs.com/bakari/archive/2012/08/27/2658215.html
主要内容:防御性编程
概念解释:最简单的说法是:函数在执行前对相关参数的检查,使程序更具健壮性。
问题引出:
1、 bool与BOOL的区别:
1)、类型不同:
bool是布尔型,BOOL一般是int型,microsoft的定义是typedef int BOOL(windef.h),所以BOOL的类型视情况而定。
2)、长度不同 :
bool 是一个字节,BOOL一般是4个字节,视情况而定。
3)、取值不同
bool属二值逻辑,false和true,对应0和1。 BOOL属三值逻辑,TRUE/FALSE/ERROR,TRUE > 1, FALSE = 1, ERROR = -1。
在语句printf("%d\r\n", sizeof(BOOL));中 sizeof(BOOL)的值在编译时确定,而非运行时。即在生成 .OBJ 文件的时候确定。
2、 学会调试错误
0xC0000005表错误号,意思是非法访问。
3、 编译器的增量编译
大体意思:在源程序空间中对程序稍作修改,改动之后的程序若和源程序相差不多,则编译时编译器仍然对源程序空间进行编译,这久叫编译器的增量编译,若要编译改动之后的程序,则选rebuild即可。
4、 Offsetof宏
1)、标准定义:
在stddef.h头文件中,该宏的定义如下:
1 #ifdef __cplusplus 2 #ifdef _WIN64 3 #define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) ) 4 #else 5 #define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) 6 #endif 7 #else 8 #ifdef _WIN64 9 #define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) ) 10 #else 11 #define offsetof(s,m) (size_t)&(((s *)0)->m) 12 #endif 13 #endif /* __cplusplus */
该宏用于求结构体中一个成员在该结构体中的偏移量。
在msdn上,该宏被写作:
size_t offsetof( structName, memberName );
第一个参数是结构体的名字,第二个参数是结构体成员的名字。
该宏返回结构体structName中成员memberName的偏移量。偏移量是size_t类型的。
E.g:下面的程序:
1 typedef struct{ 2 int iVal; 3 double dVal; 4 }Test; 5 6 int _tmain(int argc, _TCHAR* argv[]) 7 { 8 Test t = {1, 2.5}; 9 printf("address of t: %p\naddress of iVal:%p\naddress of dVal:%p\n", 10 &t, &t.iVal, &t.dVal); 11 12 printf("\n%p\n", offsetof(Test, iVal)); 13 printf("%p\n", offsetof(Test, dVal)); 14 15 return 0; 16 }
输出:
dVal的偏移量不是4而是8,这涉及到了C语言的内存对齐机制。
2)、自己实现offsetof宏
1 struct TXXX{ 2 int iF; 3 double dF; 4 }; 5 6 int _tmain(int argc, _TCHAR* argv[]) 7 { 8 TXXX *oBj = NULL; 9 printf("%p\n", &(((TXXX *)oBj)->dF)); 10 11 printf("%p\n", offsetof(TXXX, dF)); 12 printf("%d\n", &(oBj->dF)); 13 14 return 0; 15 }
输出:
结果非常明显。