0

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

#include <iostream>

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

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

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

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

4

5 回答 5

1

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

例如,编译器有权期望 ashort*永远不会引用一个double对象,因此它几乎可以随心所欲地解释*pInt

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

于 2013-05-17T17:24:19.127 回答
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;
}
于 2013-05-17T17:29:04.127 回答
0

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

于 2013-05-17T17:24:30.597 回答
0

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

于 2013-05-17T17:24:33.853 回答
0

pVoid指向代表 a 的位模式double。一旦使用void*. 在转换void*to 时short*,您声称指向的位模式是 a short,但事实并非如此。ashort和 adouble在内存中的表示是完全不同的。当您取消引用pInt时,该位置的内存恰好为 0。编译器此时不再知道该值的类型是真的double,因此如果这是您所期望的,则不可能进行隐式转换。

于 2013-05-17T17:25:18.077 回答