将带有随机 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*' [重复]