对于输出到屏幕上的无关号码( 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;
}
答案 0 :(得分:3)
投射不是从int*
派生的指向int*
的指针是未定义的行为,并且允许编译器执行任何操作。这不仅是理论上的:在我编写过代码的某些工作站上,int*
必须在四字节边界上对齐,而char*
可能不是这样,试图加载未对齐的32-比特值会导致CPU故障,因此,这样的代码在运行时可能会或不会因“总线错误”而崩溃。
这里的编译器正在为2019年的台式机做“常识”工作。可以这样说,通过从您投射到{{ 1}},没有问题。您得到的是CPU指令给您的垃圾。
这是怎么回事,int*
作为字节数组存储在内存中,包括终止的零字节。相当于"Papa Dadi"
。 ({'P','a','p','a',' ','D','a','d', 'i', '\0'}
只是语法糖。您可以用任何一种方式编写它)它们被存储为其ASCII值 1 "Papa Dadi"
。
您恰巧在具有四字节{ 0x50, 0x61, 0x70, 0x61, 0x20, 0x44, 0x61, 0x64, 0x69, 0x00 }
的计算机上进行编译,因此当您将int
别名为wicked
时,int* baboom
别名为{ {1}}和baboom[0]
字节4-7。因此,在您测试的实现中,您碰巧取回了字节“ Dad”或十六进制的20 44 61 64。
接下来,您碰巧正在编译一个低端字节序的计算机,以便从内存中以“反词顺序” wicked
进行加载。
它具有十进制值baboom[1]
。
根据您的评论: 2
0x64614420
1 显然,您并不是唯一的例外,IBM大型机编译器。默认情况下,这些仍然使用EBCDIC。
2 The consensus here 从不写1684096032
。就我个人而言,我早于cout << (int)wicked[1];
就学会了使用using namespace std;
和C标准库,而我仍然更喜欢省略<iostream.h>
,因此您可以通过诸如{ {1}}。
答案 1 :(得分:2)
您正在尝试打印出整数数组的第二个值,该值指向字符串“ Papa Dadi”
您应该知道整数是4个字节,而char是1个字节。因此整数数组中的每个元素都会跳过4个字节(字符) 您看到的打印出来的是十六进制的“ 0x64614420”,当您考虑big-endian时,将看到以下内容
0x20是空格字符。
0x44是'D'
0x61是'a'
0x64是'd'
因此,如果您关心订单,则需要将big-endian转换为little-endian。但是我不确定您要达到什么目标。