先谈一下C/C++的强制类型转换Type cast。与强制类型转换相对应的是自动类型转换。或者强制类型转换叫显示类型转换,自动类型转换叫隐式类型转换。自动类型转换会在赋值运算、混合运算、参数传递、返回函数返回值、格式化输出时且当类型出现不一致时发生,转换按数据长度增加的方向进行。 如果不希望一个类型按照自动类型转换的原则发生变化,就需要使用强制类型转换。
C的强制类型转换:TYPE a=(TYPE)b,即当a与b的类型不相同时,可以将b的类型强制转换为a的类型再进行赋值,其格式为在要转换的变量前面加小括号,里面写上要转换为的类型。
C++的强制类型转换:static_cast,从命名上理解是静态类型转换。如int转换成char;dynamic_cast,从命名上理解是动态类型转换。如子类和父类之间的多态类型转换;const_cast,从命名上理解就是去除变量的const属性;reinterpreter_cast,仅仅重新解释类型,但没有进行二进制的转换。四种操作符的使用方法一致:TYPE B = static_cast<TYPE>(a)。
下面说一下C/C++中NULL指针。*(int*)100 = 25; 将整数100强制类型转换为一个指向int型的指针,且该指针指向的位置是100,然后在100这个位置上储存的内容赋值为25。如果给位置恰好是指针a,a也为int型指针,则a的内容为25。但是,一般不建议在非保留区域内用整数直接赋值给指针,因为会发生很多意想不到的错误。在C中定义NULL: #define NULL 0 直接将NULL赋值为整型0,当free(p)后,指针p=NULL,此时发生了隐式转换,即p=(TYPE*)0,注意p的指针类型为TYPE*类型。此时指针p指向的位置就是0。 #define NULL (void*)0 此时NULL为void*类型的指针,且指向的位置为0,其指向的类型是void(无类型),即可以是任何类型的数据。此时p=NULL,会隐式转换成相应的类型,即p指向位置0,其指向的类型仍为p指向的内容(不变)。。而如果换做一个C++编译器来编译的话是要出错的,因为C++是强类型的,void *是不能隐式转换成其他指针类型的,所以通常情况下,编译器提供的头文件会这样定义NULL:
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
因为C++中不能将void *类型的指针隐式转换成其他指针类型,而又为了解决空指针的问题,所以C++中引入0来表示空指针,这样就有了类似上面的代码来定义NULL。