【问题标题】:Convert char[] with random char element(s) into one int将带有随机 char 元素的 char[] 转换为一个 int
【发布时间】:2016-05-07 07:54:22
【问题描述】:

我一直在尝试使用 C++ 读取 STL 文件中的二进制数据。我在网上找到了一些方法,其中包括一个我无法理解的过程:

char f1[4] = { facet[0],facet[1],facet[2],facet[3] };
float xx = *((float*)f1); 

我知道每个 char 都可以通过它们的 ASCII 数字转换为 int,但我不知道 char 数组如何转换成一个int

char foo[3] = { 'a','b','c' };
int x = (int)foo;
/*x is now 6513249*/
/*And the char[] can be converted into float as well*/

这种转换背后的原因是什么?是什么让 char[] 成为特定的 int 或 float?

【问题讨论】:

  • 就转换而言,我认为第一个是将一系列 4 个字符 解释为单个浮点数(假设 float 是 4 个字节),第二个一,我相信只是将指针值(从数组名称衰减到指针)转换为整数。

标签: c++


【解决方案1】:

让我们分别举两个例子:

char f1[4] = { facet[0],facet[1],facet[2],facet[3] };

这声明了一个由四个char 组成的数组,并给它们一些值。

f1

作为表达式,这是“四个 char 元素的数组”类型,但在大多数情况下,它会衰减为“指向 char 的指针”(指向第一个元素)。

((float*)f1)

这会将“指向 char 的指针”转换为“指向浮动的指针”。它产生一个指针,编译器被告知指向内存中的浮点数(尽管实际上它指向一个 char 数组)。这也可以写成:

reinterpret_cast<float*>(f1)

这使得事情变得更加明显。

*((float*)f1)

这间接通过指针,并将四个字符视为浮点数。它非常接近 strict-aliasing 规则的边缘,我认为它跨越了它们。避免这种代码。 (除了严格的别名规则外,如果 CPU 需要对齐浮点变量,并且 char 数组没有适当对齐,它也会崩溃。

float xx = *((float*)f1); 

最后,这声明了一个浮点变量,并将我们上面计算的值分配给它。这可能会在 xx 中产生陷阱值。

您可以通过以下方式避免大部分危险:

char f1[4] = { facet[0],facet[1],facet[2],facet[3] };
float xx;
memcpy(&xx, f1, 4);

这会将 f1 中的四个字节复制到 xx 的内存中。它仍然可以是一个陷阱值,但至少不会违反严格的别名规则,也不会错位。

char foo[3] = { 'a','b','c' };
int x = (int)foo;

这要简单得多。它将foo 的地址转换为int,并将int 存储在x 中。这可能很有用,但通常没有用(尤其是int 在 64 位应用程序中通常不够大)。

【讨论】:

  • 我特别喜欢你提到的一些 CPU 的严格对齐注意事项。
猜你喜欢
  • 2013-10-16
  • 2017-02-17
  • 2014-09-12
  • 2016-11-14
  • 2012-08-07
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
相关资源
最近更新 更多