将带有随机 char 元素的 char[] 转换为一个 int

Posted

技术标签:

【中文标题】将带有随机 char 元素的 char[] 转换为一个 int【英文标题】:Convert char[] with random char element(s) into one 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 个字节),第二个一,我相信只是将指针值(从数组名称衰减到指针)转换为整数。 【参考方案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 的严格对齐注意事项。

以上是关于将带有随机 char 元素的 char[] 转换为一个 int的主要内容,如果未能解决你的问题,请参考以下文章

带有构造函数的简单类引发警告:ISO C++ 禁止将字符串常量转换为 'char*' [重复]

如何使用 atoi() 将 char 数组的元素转换为 int? [复制]

返回带有随机选项和局部变量的 char 函数

将char数组转换为字符串并将其用作标签文本[重复]

C++中如何将int或者char转化为string类

在 C 代码中将 char 数组元素转换为等效的十六进制