c++ - Char 到 Int 指针转换不工作

标签 c++

我对将 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/

相关文章:

c++ - 没有重复的随机数组生成

c++ - 访问基类函数

c++ - 为什么这个 C++ 程序的输出会在 cmd 中产生一个巨大的困惑?

c++ - Blowfish 加密后字符串长度不正确

c++ - 使用 sigaltstack 动态更改运行信号处理程序的堆栈

c++ - 为什么 FindNextFile 和 FindFirstFile 在开始时打印这两个奇怪的字符串?

c++ - 删除STL vector 中偶数索引上的重复元素

c++ - std::allocate_shared 使用什么类型来分配内存?

c++ - Getline忽略输入的第一个字符

c++ - 如何将多个值 push_back 到一个 vector 中?