为什么我可以将int和BOOL转换为void *,但不能浮动?

时间:2013-01-11 06:59:53

标签: c++ objective-c c

void*是C和衍生语言的有用功能。例如,可以使用void*在C ++类中存储objective-C对象指针。

我最近正在开发一个类型转换框架,由于时间限制有点懒 - 所以我使用了void* ......这就是这个问题的出现:

为什么我可以将int类型转换为void *,但不能浮动到void *?

3 个答案:

答案 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整数可以转换为任何指针类型。没有说明指针浮动转换。