现在的位置: 首页 > 综合 > 正文

c++高级—关于C++指针大小和Void*使用的总结

2013年10月03日 ⁄ 综合 ⁄ 共 943字 ⁄ 字号 评论关闭

一、指针大小问题:【这条内容我还不确定是否准确,网上说法纷纭,但对于现代的编译器来说我更相信是准确的】

C++中任何指针的大小在同一编译器下一定是相同的,一般为32位即4个字节,但对于64位机子也可能是64位,但同一编译器下,各种类型的指针要么同位32位要么同为64位。正因为如此,所以很多C++库函数都使用Void*作为形参且可以保证跨平台(不会出现实参作为一种具体指针类型转换为形参Void*是出现数据截断现象)。

另外,有时常常听说C++中普通函数、成员函数、虚函数等的不同类型的函数指针大小不同,也是对的,但实际上C++中函数指针并不算真正的指针,只不过挂了指针的名字而已,所以并不和上面冲突,讨论C++中任何类型的指针大小时并不包含函数指针。

举个例子:

一下c++标准,里面提到了:把任何一个类型的指针先转换成void*类型,然后在转换回来,原指针的值不改变。即:
也就是如果T *p=100;那么 static_cast<T*>(static_cast<void*>(p)) == 100一定成立。

 

二、Void*作为形参的理解:【这条内容是准确的】

以库函数memset来说吧,第一,形参是void*,它表示memset不关心传入指针的类型,因为memset本身就设计为字节操作的,指针类型对于memset是多余的东西,memset关心的是使用者要给我一个位置,当然这个位置还包括后面n个字节;第二,形参不指向const类型,表示使用者不仅要给我一个位置,而且这个位置还是可修改的。第三条,这一条是隐含的,就是这个可修改的位置必须是有意义的。

使用者传入的指针不能违反这三条接口规范,否则结果才是不可预测的。接口规范需要使用者自觉遵守,由程序员自己处理自己的事情,这是C/C++的宗旨,也是C/C++给予程序员的自由和权利,当然对程序员的素质提出了较高的要求。这些自由和权利不能乱用、滥用,例如使用memset覆盖栈现场数据、堆管理链表等等,即使你要故意这样做,不同的环境也可能会产生不同的结果,亦即不可预测。

补充:

(1)任何类型的指针都可以显式转换为void类型,且不会丢失数据

(2)使用void*类型的指针不能直接访问内存,必须将void*显示的转换为具体类型的指针才能访问内存。

抱歉!评论已关闭.