我对将 char 转换为 int 指针
感到困惑。我正在检查指针的转换是如何工作的,下面的代码 int to char
工作正常。
#include <iostream>
using namespace std;
int main(){
int a=65;
void *p=&a;
cout << *static_cast<char*>(p);
}
输出
A
但是当我尝试从 char 转换为 int
时,它没有显示正确的值。
#include <iostream>
using namespace std;
int main(){
char a='A';
void *p=&a;
cout << *static_cast<int*>(p);
}
上面的代码有什么问题?输出是关于垃圾值的。
最佳答案
首先,你要明白x86架构就是所谓的little-endian。这意味着在多字节变量中,字节在内存中从最低位到最高位排序。如果您不明白那是什么意思,马上就会明白。
char
是 8 位——一个字节。当您将 'A'
存储到一个中时,它获得值 0x41
并且很高兴。 int
更大;在许多体系结构上,它是 32 位——4 字节。当您将值 'A'
分配给一个 int 时,它会得到值 0x00000041
。这在数字上完全相同,但 int
中有三个额外的零字节。
因此您的 int
包含 0x00000041
。在内存中,它以字节为单位排列,并且因为您使用的是小端架构,所以这些字节是从最低位到最高位排列的——与我们通常如何编写它们的相反!内存实际上是这样的:
+----+----+----+----+
int: | 41 | 00 | 00 | 00 |
+----+----+----+----+
+----+
char: | 41 |
+----+
当您获取指向 int
的指针并将其转换为 char*
,然后取消引用它时,编译器将获取 的第一个字节int
—— 因为 char
只有一个字节宽 —— 并将其打印出来。其他三个字节被忽略!现在回头看看,如果 int
中的字节顺序颠倒过来,就像在大端架构上一样,您将取回零值!所以这段代码的行为——从 int*
到 char*
的转换如你所愿——完全取决于你运行它的机器.
另一方面,当您获取指向 char
的指针并将其转换为 int*
,然后对它进行 defererence 时,编译器将获取一个字节如您所料,在 char
中,但随后它还会读取超过它的三个字节,因为 int
是四个字节宽!这三个字节是什么?你不知道!你的内存看起来像这样:
+----+
char: | 41 |
+----+
+----+----+----+----+
int: | 41 | ?? | ?? | ?? |
+----+----+----+----+
您在 int
中得到一个垃圾值,因为您正在读取未初始化的内存。在不同的平台或不同的行星排列下,您的代码可能运行得非常好,也可能会出现段错误和崩溃。没有告诉。这就是所谓的未定义行为,这是我们与编译器一起玩的危险游戏。像这样处理内存时,我们必须非常小心;没有什么比不确定性代码更可怕的了。
关于c++ - Char 到 Int 指针转换不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31319261/