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

Jas*_*ues 13 c c++ objective-c

void*是C和衍生语言的一个有用的特性.例如,可以使用void*在C++类中存储objective-C对象指针.

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

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

tha*_*ang 20

BOOL不是C++类型.它可能是typedef或在某处定义,在这些情况下,它将与int相同.例如,Windows在Windef.h中有这个:

    typedef int                 BOOL;
Run Code Online (Sandbox Code Playgroud)

所以你的问题减少了,为什么你可以将int转换为void*,但不能浮动到void*?

int to void*是正常的但通常不推荐(并且一些编译器会警告它)因为它们在表示中本质上是相同的.指针基本上是指向内存中地址的整数.

float to void*不正确,因为float值的解释和表示它的实际位是不同的.例如,如果你这样做:

   float x = 1.0;
Run Code Online (Sandbox Code Playgroud)

它的作用是将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
Run Code Online (Sandbox Code Playgroud)

  • `BOOL`是ObjC中的typedef'd`credit char`. (2认同)
  • +1 for*"[...]当你将浮点数转换为void\*时,解释是不明确的.你的意思是指向内存中位置1的指针吗?或者你是指指向位置3f800000的指针(假设小端)在记忆中?"* (2认同)
  • Nitpick:`0000803f`是低位字节序;不管字节序如何,`3f800000`都是`int`。从int到void *并不是严格可以的;看我的答案。 (2认同)

Pot*_*ter 17

指针通常由机器在内部表示为整数.C允许您在指针类型和整数类型之间来回转换.(指针值可以转换为足以容纳它的整数,然后返回.)

使用void*非常规举行的整数值.这种语言不能保证工作,但是如果你想要马虎,并将自己限制在英特尔和其他普通平台上,那么它基本上就会被掠夺.

实际上,您正在使用的void*是作为通用容器,但是机器使用许多字节作为指针.这在32位和64位计算机之间有所不同.因此long long,void*在32位平台上转换为丢失位.

至于浮点数,意图(void*) 10.5f是模棱两可的.你想将10.5舍入为整数,然后将其转换为无意义的指针吗?不,您希望将FPU使用的位模式放入无意义的指针中.这可以通过分配来实现float f = 10.5f; void *vp = * (uint32_t*) &f;,但要注意这只是无意义:指针不是位的通用存储.

char顺便说一句,比特的最佳通用存储是数组.语言标准保证可以通过操作来记忆char*.但您必须考虑数据对齐要求.