我只是有一个关于输出到屏幕的无关数字 (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/