首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >很少有人怀疑C++中的指针?

很少有人怀疑C++中的指针?
EN

Stack Overflow用户
提问于 2017-07-17 16:42:20
回答 2查看 148关注 0票数 1

我一直在参加斯坦福大学的“编程范例”讲座。在那里,我遇到了以下代码:

代码语言:javascript
复制
int l = 10;
float m = *(float*)&l;

我知道第一次铸造完成,然后取消引用完成。如何分配给m的值?这种铸造的特别之处在于,简单的铸造可以通过简单的(float)来完成。

这种转换有什么特别之处,以及如何分配给变量的值?

注意事项:这段代码可能只用于理论上,但我想了解它背后的概念。

EN

回答 2

Stack Overflow用户

发布于 2017-07-17 16:57:29

声明如下:

*(float*)&l;

使用

  • &地址-of,
  • *间接和
  • (float*) c型演员,

操作员。

所有这些运算符都是运算符优先列表中的第三位,它们都是从右到左读取的。

首先,取l的地址。接下来,该地址被转换到一个float* (浮点指针)。最后,这个地址被取消引用*来读取这个值。最后一步是未定义的行为。

这是违反严格混叠规则的未定义行为。它可能会为你泡一杯茶,或者它可能会把这些碎片重新解读为浮子。

在我的系统中,发生了以下情况:在l (小终端)的地址:

代码语言:javascript
复制
0x000000FC780FFC94  0a 00 00 00

m地址

代码语言:javascript
复制
0x0000004547B5F874  0a 00 00 00

l,解释为int是: 10

m,解释为float是: 1.401e-44#DEN

这个结果的原因(在我的系统上)是因为intfloat是相同的大小( msvc 64位上的4个字节),浮点数由二进制解释 1010是1.401e-44#DEN:

票数 4
EN

Stack Overflow用户

发布于 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

要了解这意味着什么,我们需要深入了解floatints是如何在硬件级别上存储的。int只是存储为具有相同值的二进制数字,而一些并发症则围绕负数存储。float更复杂,如果floats和ints存储在不同的痴呆症中,则会有更多的复杂情况。

f最有可能的值是,作为雷克斯,1.4e-44 (即1.4乘以10等于负44)。如果floats和ints具有不同的特性,则另一个合理的值约为6.16e-33。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45149516

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档