我对指向变量地址的指针很困惑
它指向最后两个字节,这是如何工作的
#include <iostream>
using namespace std;
int main()
{
int i = 1;
short *j = (short*)&i;
cout << *j << endl;
}
答案 0 :(得分:11)
指针通常保存引用项目开头的地址。
从事情的声音来看,你显然使用的是小端系统[编辑:这并不奇怪 - 例如,当前(英特尔)Mac和所有Windows机器都是小端],这意味着4字节int的最低有效字节在内存中 first 而不是last:
0000001 00000000 00000000 00000000
使用short指针查看前两个字节时,得到:
0000001 00000000
这正是它期望看到值1表示为两个字节的数字,所以这就是你得到的。
正如名称“little-endian”所暗示的那样,还有big-endian系统,其数据将如上所述进行布局。在这样的机器上,你可能会得到你期望的结果。为了完整,还有一些系统使用相当奇怪的安排,可能运行像byte1 byte0 byte3 byte2。
答案 1 :(得分:3)
这取决于架构。具体的实现应该是完全不相关的(如果不是你做错了什么)。
答案 2 :(得分:3)
这与字节顺序有关。您的架构将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
。
答案 3 :(得分:3)
这取决于系统的字节顺序(x86通常是little-endian)。
在big endian中,i的值将首先存储在最重要的字节中:
00000000 00000000 00000000 00000001
在little endian中,i的值将首先存储在最低有效字节中:
00000001 00000000 00000000 00000000
在任何情况下,指针都将指向数字的开头。但是,由于您的系统是little-endian,将该指针强制转换为short并取消引用以获得一个short值,您将获得little endian值的前两个字节
00000001 00000000
在小端,这是1的短值,这是你得到的结果。如果您在big-endian系统上运行完全相同的代码,那么您将获得值0。
答案 4 :(得分:3)
它没有指向字节;它指向int
类型的实体。怎么样
int在内存中表示取决于实现。如果i
是int
,然后*((short*)&i)
是未定义的行为;你可以得到
任何东西。实际上,在通用平台上,您可以访问类似的东西
这个;你得到的仍然取决于平台和这样的操纵
仅适用于非常低级别的平台特定操作。 (在英特尔,您将获得其他人发布的结果。对于其他平台和其他值,它取决于。)