建议1:区分0的4中面孔

0在c/c++语言中有4中形态:
整形0,空指针NULL,字符串结束标记‘\0’,和逻辑FALSE/false。
这四种都是有差异的。
它们所占的内存空间:
整形的0占32位的空间,指针和整形所占的空间是一样的。
字符占空间8位,而逻辑符不太一样,FALSE是int类型,占32位,而false是bool类型,占1位。

#ifndef NULL
#ifdef _cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

在c语言中,NULL被强制转化了一次。
可以看出,在C中,NULL表示的是指向0的指针,而在C++中,NULL就直接跟0一样了。

但有一点值得注意的是:在C语言中,“ 当常量0处于应该作为指针使用的上下文中时,它就作为空指针使用 ”

int * p=3;
int * p=0;

第一句代码就会出错,而第二句代码则不会,说明0在这里的角色已经不是整形了。

另外

char a[4]={'0',5,2,NULL};
//warning: converting to non-pointer type 'char' from NULL [-Wconversion-null]|

这句代码会给出警告,这里的NULL和’\0’是不一样的,这是codeBlocks环境下的,在别的环境下可能会报错。

逻辑FALSE的定义和false是不一样的。

#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif

这里可以发现,FALSE/TRUE是int类型,而我们用的false/true是bool类型。
这两个也是有区别的。

其二进制表示如下:
false -> 0
FALSE -> 00000000 00000000 00000000 00000000

//如果不够细心,0的多重性可能会让程序产生一些难以发现的Bug,比如:
// 把pSrc 指向的源字符串复制到pDes 指向的内存块
while(pSrc)
{
   * pDes ++ = * pSrc ++;
}
//正常情况下,当pSrc指向的字符为字符串结束符'\0'时,while循环终止;但不幸的是,这里的条件写错了,while终止条件变成了pSrc指向地址0。结果while循环写入到内存中了,直至程序崩溃。

//正确的写法应该是:
// 把pSrc 指向的源字符串复制到pDes 指向的内存块中
while(*pSrc)
{
   * pDes ++ = * pSrc ++;
}

我觉得这个应该是指针问题,不应该归结于0的误用。这里需要指向地址0才会停止循环。

//#include<cstdio>
#include<iostream>
using namespace std;

int main(){
    cout<<sizeof(NULL)<<endl;//sizeof(NULL)=4
    cout<<sizeof(0)<<endl;//sizeof(0)=4
    cout<<sizeof('\0')<<endl;//1
    cout<<sizeof(false)<<endl;//1
    cout<<sizeof(((void*)0))<<endl;//4
    //printf("%d %d %d %d %d\n",sizeof(NULL),sizeof(0),sizeof('\0'),sizeof(false),sizeof(((void*)0)));
    return 0;
}

大家可以看这一段代码,不同的0的形态都是不一样的,指针类型和整形的空间是一样的。

你可能感兴趣的:(建议1:区分0的4中面孔)