【问题标题】:Can someone explain part *(int*) and how it have any relations to the bitset?有人可以解释部分 *(int*) 以及它与位集有什么关系吗?
【发布时间】:2022-01-04 15:25:20
【问题描述】:
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
    //from float to bits
    float f;
    cin >> f;
    int x = *(int*)&f;
    cout << x << "\n";
    bitset<sizeof(int) * 8> binary(x);
    cout << binary;
}

*(int*)&amp; 做了什么让bitset 工作?

我可以理解&amp;f 使它成为地址和x= sizeof 地址f? (也许)但它在bitset&lt;sizeof(int)&gt; 中是如何工作的,* 8 有什么作用?

【问题讨论】:

  • 请注意 int x = *(int*)&amp;f;a strict aliasing violation 和未定义的行为。
  • 出于好奇,您在哪里找到了该代码?
  • 这实际上是一个古老的 C hack。 floatint 可能具有相同的大小(可能但不是必须)。 *(int*)&amp;f 是一个“重新解释”的演员。它将float f 的存储重新解释为int。使用int,可以应用位算术来评估/隔离位。尽管如此 - 这是一个旧的 C hack,在 C++ 中不再有效。 (我什至不确定现代 C 中是否仍然允许这样做。)
  • sizeof(int) * 8int 的大小乘以 8 得到位数。 (sizeof 返回字节数。)
  • C++ 等价物使用std::memcpy 将位从float 复制到int

标签: c++ pointers bitset


【解决方案1】:

*(int*)&amp; 做了什么让 bitset 工作?

这是三个一元运算符的序列,*(int *)&amp;。如代码所示,*(int*)&amp;f 首先计算指向ffloat * 类型)的指针,然后 C 样式转换将其转换为 int * 类型,最后是 * 取消引用以获取int 类型的值。总的来说,这...

int x = *(int*)&f;

... 大致相当于 ...

int x = reinterpret_cast<int&>(f);

...包括都会引发未定义的行为。但其意图是将f 的值的表示形式解释为int

它与bitset有什么关系?

std::bitset 有一个接受整数参数的构造函数,它从参数值的位初始化位集。没有这样的构造函数接受float,并且从float 类型到int 类型的正常值转换不会保留float 的位模式。

最好使用union来执行这样的转换:

union { float f; int x; } u;

cin >> u.f;
cout << u.x << "\n";
bitset<sizeof(int) * 8> binary(u.x);
cout << binary;

在 C 中,您可以为此使用联合,但在 C++ 中,您需要另一种解决方案,例如 memcpy()

float f;
int x;

cin >> f;
memcpy(&x, &f, sizeof(x));
cout << x << "\n";
bitset<sizeof(int) * 8> binary(x);
cout << binary;

【讨论】:

  • 在 C++ 中是否也禁止使用联合的类型双关语? (与 C 相反,在某些(合理的)约束下仍然允许它)我也相信(就像在其中一个 cmets 中提到的那样),正确的方法是使用 memcpy() 或者,也许,使用强制转换为 @ 987654345@.
  • 你是对的,@Scheff'sCat。答案已修改。
猜你喜欢
  • 1970-01-01
  • 2021-03-05
  • 2018-09-24
  • 2012-06-27
  • 2012-07-27
  • 2011-04-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-20
相关资源
最近更新 更多