C++中指针寻址是如何工作的?

4
我对指针指向变量地址感到困惑,它指向了最后两个字节,这是如何工作的?
#include <iostream>
using namespace std;

int main()
{
    int i = 1;
    short *j  = (short*)&i;
    cout << *j << endl;
}

.

5个回答

11

指针通常保存所引用对象的起始地址。

从您的描述听来,您似乎正在使用一个小端系统 [编辑:这并不奇怪——例如,当前 (Intel) Macs 和所有 Windows 机器都是小端系统],这意味着您的 4 字节整数的最低有效字节在内存中排在第一位,而不是最后一位:

0000001 00000000 00000000 00000000

当您使用指向 short 的指针查看前两个字节时,您会得到:

0000001 00000000

这正是它期望以二字节数字表示值为 1 的方式,因此这就是您得到的结果。

顾名思义,"little-endian" 还有 big-endian 系统,数据的布局方式与您所展示的相同。在这样的机器上,您可能会得到您期望的结果。为了完整起见,还有一些使用非常奇怪排列方式的系统,可能运行如下:byte1 byte0 byte3 byte2。


谢谢Jerry Coffin。所有台式机/笔记本电脑都有小端系统吗? - SRN
你的前两句话让人感觉好像你在说小端系统是不正常的,或者它们的指针不指向所引用项的开头。实际上这只是一个关于哪一端被认为是开头的问题。 - Rob Kennedy
@SRN:大多数情况下是这样的。任何运行Windows的设备都是小端序,目前(Intel)的Mac也是如此。一些基于ARM芯片的设备可能是大端序(ARM可以在小端序或大端序模式下运行)。 - Jerry Coffin
@Robᵩ:我在想,是否有人会认出来... :-) - Jerry Coffin
@RobKennedy:我不确定它怎么可能被理解成那样,但我已经进行了编辑以澄清。 - Jerry Coffin
这里的“though”指的是你现在已经去掉的那个词。它的作用类似于“however”,使第二句话听起来好像是对第一句话所述的内容的一个例外。 - Rob Kennedy

4
这与字节顺序有关。您的架构将int 1存储为:
00000001 00000000 00000000 00000000
^^^^^^^^
  this is the address that is stored in the pointer.
|------- -------- -------- --------| int (4 bytes)
|------- -------|                    short (2 bytes)

将其截断为2个字节的short,仍然是1。

顺便说一下,尝试单独打印所有字节:

unsigned char* p = (unsigned char*)&i;
for (unsigned j = 0; j < sizeof(int); j++) {
  std::cout << p[j] << " ";
}
std::cout << std::endl;

它应该打印出 1 0 0 0,而不是您问题中提到的 0 0 0 1

3
这取决于架构。如果具体实现有关联的话,那么就做错了。

3

这取决于您系统的字节序(x86通常为小端序)。

在大端序中,变量i的值将以最高有效字节为首字节存储:

00000000 00000000 00000000 00000001

在小端字节序中,变量 i 的值将从最低有效字节开始存储:

00000001 00000000 00000000 00000000

无论如何,指针将指向数字的开头。但是,由于您的系统是小端序,将该指针强制转换为short并进行解引用以获取short值,您将获得小端序值的前两个字节。
00000001 00000000

在小端模式下,这是表示数字1的short值,这也是你得到的结果。如果你在大端模式系统上运行完全相同的代码,那么你将得到一个值为0的结果。


3
它并不指向字节;它指向一个名为“int”的实体。如何在内存中表示“int”取决于具体的实现方式。而且,如果“i”是一个“int”,那么“*((short*)&i)”是未定义的行为;你可能得到任何东西。在实践中,在常见的平台上,您可以访问这样的内容;您所得到的结果仍然取决于平台,并且这种操作只对非常低级别、特定于平台的操作有用。(在英特尔(Intel)上,您将获得其他人发布过的结果。对于其他平台和其他值,这取决于具体情况。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接