void*
是C和衍生语言的有用功能。例如,可以使用void*
在C ++类中存储objective-C对象指针。
我最近正在开发一个类型转换框架,由于时间限制有点懒 - 所以我使用了void*
......这就是这个问题的出现:
为什么我可以将int类型转换为void *,但不能浮动到void *?
答案 0 :(得分:21)
BOOL不是C ++类型。它可能是typedef或在某处定义,在这些情况下,它将与int相同。例如,Windows在Windef.h中有这个:
typedef int BOOL;
所以你的问题减少了,为什么你可以将int转换为void *,但不能浮动到void *?
int to void *是正常的但通常不推荐(并且一些编译器会警告它)因为它们在表示方面本质上是相同的。指针基本上是指向内存中地址的整数。
float to void *不正确,因为float值的解释和表示它的实际位是不同的。例如,如果你这样做:
float x = 1.0;
它的作用是将32位存储器设置为00 00 80 3f(IEEE单精度中浮点值1.0的实际表示)。当您将浮点数转换为void *时,解释是不明确的。你的意思是指向内存中位置1的指针吗?或者你的意思是指向内存中位置3f800000(假设小端)的指针?
当然,如果您确定自己想要的两种情况中的哪一种,总会有办法解决问题。例如:
void* u = (void*)((int)x); // first case
void* u = (void*)(((unsigned short*)(&x))[0] | (((unsigned int)((unsigned short*)(&x))[1]) << 16)); // second case
答案 1 :(得分:17)
指针通常由机器在内部表示为整数。 C允许您在指针类型和整数类型之间来回转换。 (指针值可以转换为足以容纳它的整数,然后返回。)
使用void*
保存非常规的整数值。这种语言不能保证工作,但是如果你想要邋and并将自己限制在英特尔和其他普通平台上,那么它基本上就会被掠过。
有效的是,您正在使用void*
作为通用容器,但机器使用的指针数量很多。这在32位和64位计算机之间有所不同。因此,将long long
转换为void*
会丢失32位平台上的位。
至于浮点数,(void*) 10.5f
的意图是模棱两可的。你想将10.5舍入为整数,然后将其转换为无意义的指针吗?不,您希望将FPU使用的位模式放入无意义的指针中。这可以通过分配float f = 10.5f; void *vp = * (uint32_t*) &f;
来完成,但要注意这只是无意义:指针不是位的通用存储。
顺便说一下,最好的位通用存储是char
数组。语言标准保证可以通过char*
操纵内存。但您必须考虑数据对齐要求。
答案 2 :(得分:1)
Standard表示 752整数可以转换为任何指针类型。没有说明指针浮动转换。