void*
是 C 和衍生语言的一个有用特性。例如,可以用来void*
在 C++ 类中存储 Objective-C 对象指针。
我最近正在研究一个类型转换框架,由于时间限制有点懒惰 - 所以我使用void*
了......这就是这个问题的出现方式:
为什么我可以将 int 类型转换为 void*,但不能将浮点类型转换为 void*?
void*
是 C 和衍生语言的一个有用特性。例如,可以用来void*
在 C++ 类中存储 Objective-C 对象指针。
我最近正在研究一个类型转换框架,由于时间限制有点懒惰 - 所以我使用void*
了......这就是这个问题的出现方式:
为什么我可以将 int 类型转换为 void*,但不能将浮点类型转换为 void*?
BOOL is not a C++ type. It's probably typedef or defined somewhere, and in these cases, it would be the same as int. Windows, for example, has this in Windef.h:
typedef int BOOL;
so your question reduces to, why can you typecast int to void*, but not float to void*?
int to void* is ok but generally not recommended (and some compilers will warn about it) because they are inherently the same in representation. A pointer is basically an integer that points to an address in memory.
float to void* is not ok because the interpretation of the float value and the actual bits representing it are different. For example, if you do:
float x = 1.0;
what it does is it sets the 32 bit memory to 00 00 80 3f (the actual representation of the float value 1.0 in IEEE single precision). When you cast a float to a void*, the interpretation is ambiguous. Do you mean the pointer that points to location 1 in memory? or do you mean the pointer that points to location 3f800000 (assuming little endian) in memory?
Of course, if you are sure which of the two cases you want, there is always a way to get around the problem. For example:
void* u = (void*)((int)x); // first case
void* u = (void*)(((unsigned short*)(&x))[0] | (((unsigned int)((unsigned short*)(&x))[1]) << 16)); // second case
指针通常由机器在内部表示为整数。C 允许您在指针类型和整数类型之间来回转换。(指针值可以转换为足够大的整数来容纳它,然后返回。)
用于以void*
非常规的方式保存整数值。语言不能保证能正常工作,但如果你想马虎,把自己限制在 Intel 和其他普通平台上,它基本上会勉强过关。
实际上,您正在做的是void*
用作通用容器,但机器使用了许多字节作为指针。这在 32 位和 64 位机器之间有所不同。所以在 32 位平台上转换long long
为会丢失位。void*
至于浮点数, 的意图(void*) 10.5f
是模棱两可的。您想将 10.5 舍入为整数,然后将其转换为无意义的指针吗?不,您希望将 FPU 使用的位模式放入无意义的指针中。这可以通过分配来完成float f = 10.5f; void *vp = * (uint32_t*) &f;
,但请注意,这只是胡说八道:指针不是位的通用存储。
顺便说一下,最好的位通用存储是char
数组。语言标准保证可以通过char*
. 但是您必须注意数据对齐要求。
标准规定752 整数可以转换为任何指针类型。没有说任何关于指针浮点转换的内容。