我只是对输出到屏幕的无关数字(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故障,因此,像这样的代码可能会或可能不会在运行时因“总线错误”而崩溃。
这里的编译器在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
和baboom[1]
字节4-7的字节0-3。因此,在您测试的实现中,您碰巧找回了字节“Dad”,或者在Hex,20 44 61 64中。
接下来,你碰巧正在为一个小端机器进行编译,所以它以“背单词顺序”0x64614420
从内存中加载。
这有十进制值1684096032
。
根据你的评论:2
cout << (int)wicked[1];
1显然,您没有运行唯一的例外,即IBM大型机编译器。这些仍然默认使用EBCDIC。
2 The consensus here永远不会写using namespace std;
。就个人而言,我学会了在<iostream.h>
之前使用namespace std
和C标准库,我仍然更喜欢省略std
,所以你可以通过像using std::cout;
这样的命令来告诉我的代码。
您正在尝试打印出整数数组的第二个值,该值指向字符串“Papa Dadi”
您应该知道整数是4个字节,char是1个字节。所以整数数组中的每一个元素都会跳过4个字节(字符)你看到的打印输出是十六进制的“0x64614420”,当你想到big-endian时你会看到以下内容
0x20是空格字符。
0x44是'D'
0x61是'a'
'64'是'd'
因此,如果您关心订单,则需要将big-endian转换为little-endian。但是我不确定你想要达到什么目的。