C++咬文嚼字-'0 or NULL'
C程序员和C++程序员在声明空指针时做法常常是不相同的。
C程序员常常如下做:
int *ptr = NULL;
C++程序员则是听从Bjarne Stroustrup或者其他C++大师的教诲,坚定地如下做:
int *ptr = 0;
也许没有谁对谁错之分,也许只是习惯不同罢了,毕竟C语言是老大哥,诞生的早;而在早期C编程时人们也许不习惯在程序里使用0这样的magic number,转而使用了#define NULL ((void*)0)来统一进行空指针的声明或者赋值。
在'Effective C++'中明确提出避免使用使用macro的issue,广大C++信徒自然也就将NULL抛掷脑后,并逐渐形成习惯,用0给指针赋值以意会这是个空指针的方式就流传了下来。
还是那句话没有谁对谁错,在'The C++ Programming Language Special Edition'中Bjarne Stroustrup在5.1.1小节用了不到200个words来说明了关于'0'或NULL的问题,这段叙述也是堪称经典,我们可以来回顾一下:
Zero(0) is an int. Because of standard conversions, 0 can be used as a constant of any integral, floating-point, pointer, or pointer-to-member type. The type of zero will be determined by context. Zero(0) will typically (but not necessarily) be represented by the bit patternall-zerosof the appropriate size.No object is allocated with the address 0 . Consequently, 0 acts as a pointer literal, indicating that a pointer doesn’t refer to an object.
0是一个整型数,通过标准的转型操作,0可以被用作各种数据类型常量,这些数据类型包括整型、浮点型、指针型或者指向类成员的指针类型。这时这个常量0的类型需要通过上下文才能判断出来。0通常(但不是必要的)用特定大小的全二进制0的bit串表示。没有object会被分配到0地址上,0只是字面值,其含义是这个指针变量没有指向(参考到)任何object。
举例:
int i = 0; //整型
long l = 0; //整型
float f = 0; //浮点型
double d = 0; //浮点型
int *p = 0; //整型指针
double *dp = 0; //浮点指针
class T {
public :
int func(int a){…};
};
T *pT = 0; //用户自定义类型指针
int (T::*PTR)(int) = 0; //指向类成员的指针类型
Bjarne Stroustrup继续说明了C与C++程序员习惯上的差异并给出了自己的建议:
In C, it has been popular to define a macro NULL to represent the zero pointer. Because of C++’s tighter type checking, the use of plain 0, rather than any suggested NULL macro, leads to fewer problems. If you feel you must define NULL, use const int NULL = 0;
The const qualifier prevents accidental redefinition the NULL and ensures that NULL can be used where a constant is required.
在C中,定义一个macro NULL代表空指针是很流行常见的做法。由于C++编译器更严格的类型检查,使用0比使用NULL macro给你带来的麻烦更少。如果你一定要用NULL,那么建议作如下定义: const int NULL = 0; 这行定义会阻止意外的重定义NULL,而且会保证NULL在一个需要常量的场合被使用。
由此看来,在C++中0的灵活性和适应性更强一些,至于到底用哪个还是个见仁见智的问题,谁也不能强迫谁^_^。
评论