0:空指针
在C和C++中,有关指针的上下文中出现的0代表空指针:
int i =0; //i now contains theinteger zero
char*s=0; //s now contains the nullpointer
(注3: 不要认为0是一个地址,尽管空指针实现时常被作为地址0,但是实际上不必这样。)
这里0是用作整数的,它代表空指针。
为了使意图更为明了,当要表示空指针时,许多程序员都使用空指针宏NULL:
/*Ccode*/
#defineNULL (void *)0 /*typical definition ofnull-pointer macro*/
Foo* x =NULL; /*works fine in c*/
NULL宏包括void*的类型转换,以便解释这个宏时,一直把它当做指针而不是整数,尤其是在函数调用的时候。但如前所述,在C++中如果没有类型转换,void* 是不能赋给任意的指针的。如果你想在C++中使用NULL宏,而且不想每次都进行类型转换,那么NULL必须被定义为0:
//C++code
#define NULL 0 //most reasonable definitionof null-pointer //macro in C++
Foo *x = NULL; //works fine in C++
在C++中,使用0而不必进行到void*的类型转换这一机制运
行的很好, 因为无论你认为它是指针还是整数,通常都会
在上下文中澄清。实际上,许多C++程序员都抛弃了宏而
在代码中使用0作为空指针。
int* p = 0; //many C++ programmersavoid NULL
也有一些程序员不愿意抛弃自己所喜爱的宏。在本书中我们
使用0,因为他已经成为C++的标准了。你可能会在其他程
序员的代码中见到NULL或0。
要慎用NULL的一个很好的原因是,当一个重载函数的参数
即可以是整数也可以是指针时,NULL就会引起麻烦。编译器
会认为0与整数更匹配,而不是指针:
#define NULL 0
void snafu (int i); //first snafu
void snafu (char* c); //second snafu
main () {
snafu(0); //danger: calls first snafu
//thisis not what you meant if you
//wereusing 0 as the null pointer
snafu(NULL); //error: calls first snafu
//this is almost certainly not //what youmeant
}
对函数snafu()的两次调用使用的都是snafu(int)。最好不要对参数为指针和整数的函数进行重载,这样会引起混乱,除非你在调用函数时从不使用空指针。如果重载无法避免,那么可以使用类型转换:
voidsnafu (int i); //firstsnafu
voidsnafu (char* c) //second snafu
main () {
snafu((int) 0); //calls first snafu, the cast is unnecessary
//butmakes your intention clear
snafu((char *) NULL); //calls second snafu,the cast is //essential
}
我们在这里加入了类型转换以后告诉编译器应该调用那
个一函数。