我对指向变量地址的指针感到困惑
它指向最后两个字节这是如何工作的
#include <iostream>
using namespace std;
int main()
{
int i = 1;
short *j = (short*)&i;
cout << *j << endl;
}
.
我对指向变量地址的指针感到困惑
它指向最后两个字节这是如何工作的
#include <iostream>
using namespace std;
int main()
{
int i = 1;
short *j = (short*)&i;
cout << *j << endl;
}
.
指针通常保存被引用项的开始地址。
从事物的声音来看,您显然使用的是小端系统[编辑:这并不奇怪——例如,当前的(英特尔)Mac 和所有 Windows 机器都是小端的],这意味着最低有效字节您的 4 字节 int在内存中排在第一位,而不是排在最后:
0000001 00000000 00000000 00000000
当您使用指向 short 的指针来查看前两个字节时,您会得到:
0000001 00000000
这正是它期望看到的值 1 表示为一个两字节数字的方式,所以这就是你得到的。
正如名称“little-endian”所暗示的那样,还有 big-endian 系统,其中的数据将按照您上面的说明进行布局。在这样的机器上,您可能会得到您期望的结果。为了完整起见,还有一些系统使用了相当奇怪的安排,可能运行类似 byte1 byte0 byte3 byte2 之类的东西。
这与字节顺序有关。您的架构将int
1 存储为:
00000001 00000000 00000000 00000000
^^^^^^^^
this is the address that is stored in the pointer.
|------- -------- -------- --------| int (4 bytes)
|------- -------| short (2 bytes)
其中,截断为short
2 个字节仍然是 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
您的问题中建议的那样。
这取决于架构。并且具体的实现应该是完全无关的(如果不是你做错了什么)。
这取决于系统的字节序(x86 通常是小字节序)。
在大端中, i 的值将首先存储最高有效字节:
00000000 00000000 00000000 00000001
在 little endian 中,i 的值将首先存储最低有效字节:
00000001 00000000 00000000 00000000
在任何情况下,指针都会指向数字的开头。但是,由于您的系统是 little-endian,将该指针转换为 short 并取消引用以获得一个 short 值,您将获得 little-endian 值的前两个字节
00000001 00000000
在 little endian 中,这是 1 的短值,这是您得到的结果。如果您在大端系统上运行完全相同的代码,那么您将获得 0 值。
它不指向字节;它指向一个类型的实体int
。int 在内存中的表示方式取决于实现。如果i
是一个int
,那么*((short*)&i)
是未定义的行为;你可以得到任何东西。在实践中,在通用平台上,您可以访问这样的东西;您得到的仍然取决于平台,并且此类操作仅对非常低级别的平台特定操作有用。(在英特尔上,您将获得其他人发布的结果。对于其他平台和其他值,这取决于。)