c++ - 改变指针有什么用?

标签 c++ c++11

我只是有一个关于输出到屏幕的无关数字 (1684096032) 的快速问题。我希望输出整数 ASCII 值 (97),因为这是小写 'a' 的 ASCII 值。控制台给了我一个巨大的数字......

using namespace std;

int main(){
    char dadum[50] = "Papa Dadi";
    char* wicked = dadum;
    int* baboom = (int*)wicked;
    cout << baboom[1] << endl;
    cout<<"Hello World";

    return 0;
}

最佳答案

一句警告

将不是从 int* 派生的指针转换为 int* 是未定义的行为,编译器实际上可以做任何事情。这不仅仅是理论上的:在我编码的一些工作站上,int* 必须在四字节边界上对齐,而 char* 可能不是,尝试加载未对齐的 32 位值会导致 CPU 故障,因此,这样的代码可能会或可能不会在运行时因“总线错误”而崩溃。

1684096032从何而来

这里的编译器正在为 2019 年的台式计算机做“常识性”的事情。它让你“搬起石头砸自己的脚”,可以这么说,通过从你转换为 int* 的地址发出加载指令,无话可问。你得到的是 CPU 指令给你的垃圾。

发生的事情是 "Papa Dadi" 作为字节数组存储在内存中,包括终止零字节。它相当于 {'P','a','p','a',' ','D','a','d', 'i', '\0'} 。 ( "Papa Dadi" 只是语法糖。您可以用任何一种方式编写它)这些存储为它们的 ASCII 值1 { 0x50, 0x61, 0x70, 0x61, 0x20, 0x44, 0x61, 0x64, 0x69, 0x00 }

你碰巧在一台机器上用四字节 int 编译,所以当你将 wicked 别名为 int* baboom 时,baboom[0] 别名为 wicked 的字节 0-3 和 baboom[1] 字节 4-7。因此,在您测试的实现中,您碰巧取回了字节“Dad”,或者十六进制,20 44 61 64。

接下来,您恰好正在为一台小端机器进行编译,因此它会以“反向词顺序”0x64614420 从内存中加载。

这有十进制值 1684096032

你想做什么

根据您的评论:2

cout << (int)wicked[1];

1 显然,您并不是在运行唯一的异常(exception),即 IBM 大型机编译器。这些仍然默认使用 EBCDIC。

2 The consensus here 从不写入 using namespace std; 。就个人而言,我早在 <iostream.h> 之前就学会了使用 namespace std 和 C 标准库,我仍然更喜欢省略这些 std,因此您可以通过命令 block 告诉我的代码,例如 using std::cout;

关于c++ - 改变指针有什么用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54838878/

相关文章:

c++ - C++中的异常被捕获后找出源头?

C++ SFML Sprite 未绘制,但未发生错误

c++ - 部分模板特化错误

c++ - 使用参数包扩展调用具有可变参数的函数,但修改第 i 个参数

c++ - 如何从命令行在 Visual Studio 2019 for C++ 中生成 .pdb 文件

c++ - 在 C++ 应用程序中存储、跟踪和更新 SQLite 数据库版本

c++ - 如何对 Boost Spirit Parser 进行基准测试?

c++ - 在 C++11 中打印 std::bitset

c++ - std::once_flag 相当于 BOOST_ONCE_INIT

c++ - 在 C++ 中定义离散概率分布