指针定型

Pointers typecast

本文关键字:定型 指针      更新时间:2023-10-16

我有以下代码,我想知道为什么我有以下输出:

#include <iostream>
int main() {
    double nValue = 5;
    void *pVoid = &nValue;
    short *pInt = static_cast<short*>(pVoid);
    std::cout << *pInt << std::endl; 
    return 0;
}

它输出给我'0'。我想知道为什么会这样。谢谢你!

你有UB(未定义行为),因为你违反了指针混叠规则。这意味着任何事情都可能发生。

例如,编译器有权期望short*永远不会引用double对象,因此它几乎可以按照自己的意愿解释*pInt

也有可能编译器按字面意思解释代码,而在您的平台上,5.0的二进制表示以两个(或sizeof(short))字节的零开始。

您正在将double数据的内存块转换为short。由于您在该块中存储了一个小值,因此它不会存储在第一个位中。因此,首先bits为零。但是它依赖于内部double表示和short大小,所以不能保证在不同的平台上是相同的

您试图将double的内容解释为short。这会调用未定义的行为——您的程序可以自由地做任何事情。

pVoid指向一个表示double的位模式。一旦使用了void*,编译器就会丢失类型信息。当将void*转换为short*时,您声称指向的位模式是short,实际上不是。shortdouble在内存中的表示是完全不同的。当对pInt解引用时,该位置的内存恰好为0。此时,编译器不再知道该值的类型是否真的是double,因此,如果您希望这样做,则不可能进行隐式转换。

只是为了好玩,在你的机器上5的双表示形式很可能是这样的

                *double  = (5)
0000000000000000000000000000000000000000000000000000000000000101
^^^^^^^^^^^^^^^^
   *short = (0)

这应该会告诉你为什么会发生这种情况

int main() {
    double nValue = 5;
    short nValue_short = 5;
    std::bitset<sizeof(double)*8> bit_double(nValue);
    std::bitset<sizeof(short)*8> bit_short(nValue_short);
    std::cout << bit_double << std::endl; 
    std::cout << bit_short << std::endl; 
    return 0;
}