我一直在参加斯坦福大学的“编程范例”讲座。在那里,我遇到了以下代码:
int l = 10;
float m = *(float*)&l;我知道第一次铸造完成,然后取消引用完成。如何分配给m的值?这种铸造的特别之处在于,简单的铸造可以通过简单的(float)来完成。
这种转换有什么特别之处,以及如何分配给变量的值?
注意事项:这段代码可能只用于理论上,但我想了解它背后的概念。
发布于 2017-07-17 16:57:29
声明如下:
*(float*)&l;
使用
&地址-of,*间接和(float*) c型演员,操作员。
所有这些运算符都是运算符优先列表中的第三位,它们都是从右到左读取的。
首先,取l的地址。接下来,该地址被转换到一个float* (浮点指针)。最后,这个地址被取消引用*来读取这个值。最后一步是未定义的行为。
这是违反严格混叠规则的未定义行为。它可能会为你泡一杯茶,或者它可能会把这些碎片重新解读为浮子。
在我的系统中,发生了以下情况:在l (小终端)的地址:
0x000000FC780FFC94 0a 00 00 00在m地址
0x0000004547B5F874 0a 00 00 00l,解释为int是: 10
m,解释为float是: 1.401e-44#DEN
这个结果的原因(在我的系统上)是因为int和float是相同的大小( msvc 64位上的4个字节),浮点数由二进制解释 1010是1.401e-44#DEN:

发布于 2017-07-17 17:05:33
首先,警告:根据C++标准,这是未定义的行为。编译器可以让程序在执行这一行时做任何事情,而且在许多情况下,它不会按照程序员的要求做任何事情。然而,对于那些熟悉C++的人来说,对于他们的意图有一个明确的含义,在大多数情况下编译器可能会这样做。
首先,让我们检查一下,如果您按照预期使用(float)l,会发生什么。程序将接受l的值,将其解释为int,并返回一个浮点数,其值与此值相同;在本例中,是10.0。这通常是你想要的,而且定义得很清楚。
现在,让我们看看您实际拥有的代码:*(float*)&l;。根据这个表达式的特殊语法,它应该从右到左阅读.&l部件的意思是“获取l存储在内存中的位置”,通常称为“指向l的指针”。因为l是一个int,所以这个表达式的类型是“指向int的指针”。
然后,(float*)部分是一个强制转换。它说“把这个指针到-int当作指针到-float”。这应该是指向内存中相同位置的指针,但是当程序访问它时,它将以float的形式读取该位置的位。
第一个*取消这个指向float的指针,并得到一个float。这是未定义的部分;该语言假设您不会访问两个不同类型的相同指针。它被称为“指针混叠”,根据平台、编译器、优化标志等可以做任何事情。预期的行为可能是获得与值为10的float具有相同位模式的int。
要了解这意味着什么,我们需要深入了解float和ints是如何在硬件级别上存储的。int只是存储为具有相同值的二进制数字,而一些并发症则围绕负数存储。float是更复杂,如果floats和ints存储在不同的痴呆症中,则会有更多的复杂情况。
f最有可能的值是,作为雷克斯,1.4e-44 (即1.4乘以10等于负44)。如果floats和ints具有不同的特性,则另一个合理的值约为6.16e-33。
https://stackoverflow.com/questions/45149516
复制相似问题