改变指针有什么用?

问题描述 投票:0回答:2

我只是对输出到屏幕的无关数字(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;
}
c++ c++11
2个回答
3
投票

一句警告

将一个指向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]别名为wickedbaboom[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;这样的命令来告诉我的代码。


2
投票

您正在尝试打印出整数数组的第二个值,该值指向字符串“Papa Dadi”

您应该知道整数是4个字节,char是1个字节。所以整数数组中的每一个元素都会跳过4个字节(字符)你看到的打印输出是十六进制的“0x64614420”,当你想到big-endian时你会看到以下内容

0x20是空格字符。

0x44是'D'

0x61是'a'

'64'是'd'

因此,如果您关心订单,则需要将big-endian转换为little-endian。但是我不确定你想要达到什么目的。

© www.soinside.com 2019 - 2024. All rights reserved.