指针类型

时间:2013-05-17 17:20:47

标签: c++ pointers casting void-pointers

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

#include <iostream>

int main() {
    double nValue = 5;
    void *pVoid = &nValue;

    short *pInt = static_cast<short*>(pVoid);

    std::cout << *pInt << std::endl; 
    return 0;
}

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

5 个答案:

答案 0 :(得分:1)

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

例如,编译器拥有期望short*永远不会引用double对象的所有权利,因此它可以解释*pInt但它想要它。

或者编译器可能会按字面解释代码,而在您的平台上,5.0的二进制表示形式会以两个(或sizeof(short))个零的字节开头。

答案 1 :(得分:0)

您正在将带有double数据的内存块投射到short。由于您在该块中存储了一个小值,因此它不会存储在第一位中。因此,第一个bits为零。但它依赖于内部double表示和short大小,因此不保证在不同平台上保持相同

答案 2 :(得分:0)

您尝试将double的内容解释为short。这会调用未定义的行为 - 您的程序可以自由执行任何操作。

答案 3 :(得分:0)

pVoid指向代表double的位模式。使用void*后,编译器将丢失类型信息。将void*转换为short*时,您声称指向的位模式为short,而不是short。内存中doublepInt的表示完全不同。当您取消引用double时,该位置的内存恰好为0.编译器此时不再知道值的类型实际上是{{1}},因此不可能进行隐式转换,如果这就是你的意思期待着。

答案 4 :(得分:0)

只是为了好玩,很可能是你机器上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;
}