null,NULL,nullptr和””区别
C和C++对大小写敏感,null和NULL是区别对待的。
NULL代表空地址,null只是一个符号。
null和NULL都是字符串,具体看它们宏定义被定义成为什么值。在VS中NULL被定义为0,因为习惯上把宏定义的所有字符都大写,当把NULL它赋值给指针时意思为空,当然也可以把null定义为0。当它们都没定义时就只能叫符号,定义后就有另外的意思,直接把0赋值给指针也行,只要指针指向0就表示空。
NULL在有些编译器中已经赋值为0,不能再用#define定义它,会导致重定义问题。
C的NULL与C++的NULL
在C语言中使用NULL表示空指针,可以写如下代码:
int *i = NULL;
实际上在C语言中,NULL通常被定义为:#define NULL ((void *)0)
也就是说NULL实际上是一个void *的指针,然后把void *指针赋值给int *和foo_t *的指针时,隐式转换成相应的类型。
如果换做一个C++编译器来编译是要出错的,因为C++是强类型的,void *不能隐式转换成其他指针类型,所以通常情况下,编译器提供的头文件会这样定义NULL:
#ifdef __cplusplus //简称:cpp c++ 文件
#define NULL 0
#else
#define NULL ((void *)0)
#endif
在C++环境下情况不能写这样的代码:
FILE* fp = (void*)0; //将void*直接赋值给一个指针是不合法的,编译器会报错
只能这样写代码
FILE* fp = (FILE*)0;
// or
FILE* fp = 0;
C++的0
因为C++中不能将void *类型的指针隐式转换成其他指针类型,而又为了解决空指针的问题,所以C++中引入0来表示空指针(注:用0表示还是有缺陷),这样就有了类似上面的代码来定义NULL。实际上C++的书都会推荐说C++中更习惯使用0来表示空指针而不是NULL,尽管NULL在C++编译器下就是0。
为什么C++的书都推荐使用0而不是NULL来表示空指针呢?我们看一个例子:
在foo.h文件中声明了一个函数:
void bar(sometype1 a, sometype2 *b);
这个函数在a.cpp、b.cpp中调用了,分别是:
a.cpp:
bar(a, b);
b.cpp:
bar(a, 0);
这些代码都是正常编译运行。但是如果需要使用重载对bar函数进行扩展,现在foo.h的声明如下:
void bar(sometype1 a, sometype2 *b);
void bar(sometype1 a, int i);
这个时候a.cpp和b.cpp中的调用代码就不能按照期望运行。但能够很快发现问题在于b.cpp中的0是整数,也就是在overload resolution时它调用的是void bar(sometype1 a, int i)这个重载函数,可以如下修改让代码按照期望运行:
bar(a, static_cast<sometype2 *>(0));
假设调用代码是这样的:
foo.h
void bar(sometype1 a, sometype2 *b);
void bar(sometype1 a, int i);
a.cpp
bar(a, b);
b.cpp
bar(a, NULL);
出错时b.cpp中调用代码的问题可能被忽略,因为使用NULL空指针容易直接认为调用的void bar(sometype1 a, sometype2 *b)这个重载函数。实际上NULL在C++中就是0,编程使用NULL时错误不够“明显”,使用0表示空指针更“明显”,因为0是空指针,它更是一个整型常量。所以在C++中,使用0来做空指针会比使用NULL来做空指针更加让人警觉。
C++ 11的nullptr
C++11中有一个新的关键字nullptr,如果编译器支持nullptr应该直接使用nullptr来替代NULL的宏定义。正常使用过程中它们是完全等价的。
虽然上面说明了0比NULL可以让我们更加警觉,但是并没有避免这个问题。C++ 11的nullptr能够解决这个问题,代码如下:
foo.h
void bar(sometype1 a, sometype2 *b);
void bar(sometype1 a, int i);
a.cpp
bar(a, b);
b.cpp
bar(a, nullptr);
代码还是能够如预期的一样正确运行。
某些编译器不支持c++11的新关键字nullptr,可以模拟实现一个nullptr
[cpp]
const
class nullptr_t_t
{
public:
template<class T> operator T*() const {return 0;}
template<class C, classT> operator T C::*() const { return 0; }
private:
void operator& () const;
} nullptr_t = {};
#undef NULL
#define NULL nullptr_t
C和C++的“”
“”也表示空,但是和null有很大区别:null没有分配空间,""分配了空间
string str1 = null; //str引用为空
string str2 = ""; //str引用一个空串
null没有分配空间,""分配了空间,因此str1不是一个实例化的对象,而str2已经实例化。
注意:
因为null不是对象,""是对象,所以在进行比较时应该
if(str1==null){...}
if(str2.equals("")){...}
//对象用equals比较,null用等号比较
下面写法错误:
if(str1.equals("")||str1==null){//如果str1没有值,则.... }
正确的写法是
if(str1==null||str1.equals("")){//先判断是不是对象,如果是再判断是不是空字符串}
//str1==null为真不会判断str1.equals("");str1==null为假即str1是对象,才会判断str1.equals("")
打个比方:一个空玻璃杯不能说它里面什么都没有,因为里面有空气,当然也可以把它弄成真空,null与" "的区别就象真空与空气一样。
本文介绍了C和C++中null、NULL、0以及空字符串的区别。NULL通常被定义为0,但在C++中使用0作为空指针更安全。C++11引入了nullptr,解决了类型安全问题。空字符串则是一个分配了空间的字符串对象,不同于未分配空间的null。

388

被折叠的 条评论
为什么被折叠?



