您的位置:首页 > 编程语言

大神洗礼第一讲——防御性编程相关

2012-10-18 23:44 169 查看
Author:bakari Date:2012.10.18

这段时间非常有幸能够跟着一个非常牛的学长学习编程,现将每次学到的内容作为整理,方便以后复习,也分享给需要的网友。

这是学长第一次讲,本次讲的内容比较基础和偏理论,是有关于防御性编程的,关于这方面我之前就记录过一篇文章,详细见:

/article/5171916.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头文件中,该宏的定义如下:

#ifdef __cplusplus
  #ifdef _WIN64
  #define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) )
  #else
  #define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
  #endif
  #else
  #ifdef _WIN64
  #define offsetof(s,m) (size_t)( (ptrdiff_t)&(((s *)0)->m) )
  #else
  #define offsetof(s,m) (size_t)&(((s *)0)->m)
  #endif
#endif /* __cplusplus */


该宏用于求结构体中一个成员在该结构体中的偏移量。  

在msdn上,该宏被写作:   

size_t offsetof( structName, memberName );

第一个参数是结构体的名字,第二个参数是结构体成员的名字。

该宏返回结构体structName中成员memberName的偏移量。偏移量是size_t类型的。

E.g:下面的程序:

typedef struct{
int       iVal;
double dVal;
}Test;

int _tmain(int argc, _TCHAR* argv[])
{
Test t = {1, 2.5};
printf("address of t:   %p\naddress of iVal:%p\naddress of dVal:%p\n",
&t, &t.iVal, &t.dVal);

printf("\n%p\n", offsetof(Test, iVal));
printf("%p\n", offsetof(Test, dVal));

return 0;
}


输出:



dVal的偏移量不是4而是8,这涉及到了C语言的内存对齐机制

2)、自己实现offsetof宏

struct TXXX{
int    iF;
double dF;
};

int _tmain(int argc, _TCHAR* argv[])
{
TXXX *oBj = NULL;
printf("%p\n", &(((TXXX *)oBj)->dF));

printf("%p\n", offsetof(TXXX, dF));
printf("%d\n", &(oBj->dF));

return 0;
}


输出:



结果非常明显。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: