取地址运算符&返回的值

来源:互联网 发布:歪歪语音官方下载 mac 编辑:程序博客网 时间:2024/05/20 11:51

本文适合C++初学者阅读。

#include <iostream>using namespace std; int main()
{
int a[5]={1,2,3,4,5};int*ptr1=(int*)(&a+1);int*ptr2=(int*)((int)a+1); cout<<ptr1[-1]<<endl; cout<<hex<<*ptr2<<endl;  return0;
}
昨天在QQ群里回答了一个问题。代码如上。这是C++ Primer Plus的一道练习。
如果sizeof(int)的值是4,小端存储,这个程序的输出应该是:
5
2000000

下面仅对sizeof(int)的值是4,小端存储的情况说明。先解释什么叫小端存储,清楚这个概念之后,就容易了。
int i = 1;
对于i,在内存占四个字节,16进制形式是:0×00000001,如果&i的值是0×1000,那么i占了哪四个字节?
取地址运算符&返回的值是一个对象所占内存的所有字节的最低地址。

如果i所占的内存空间是0×1000, 0×1001, 0×1002, 0×1003。

如果是小端存储,数值的最低位放在地址值最小的字节。如果是大端存储,数值的最低位放在地址值最大的字节。
所以,0×00000001在内存中的分布是:
内存地址 0×1000 0×1001 0×1002 0×1003
所存储的值 0×01 0×00 0×00 0×00

取值运算符*怎么取值呢?
既然取地址运算符&取到的是一个对象所占内存的最低字节的地址值,*取值的时候,可如下解释:
int *ptr = &i;
*ptr就是把0×1000, 0×1001, 0×1002, 0×1003四个字节的内容取出来,其中0×1000是最低字节,0×1003是最高字节,然后把这四个字节当成int型来解释。
如果是大端存储,就把0×1000中的内容当成最高字节,0×1003中的内容当最低字节来解释。

现在开始解释最上面的程序,
如果是小端存储,

 
int a[5]={1,2,3,4,5};

数组a的内存分布是:
01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 %%
以上均为16进制数。0×01所在的字节是数组a的起始字节,0x%%是数组a所占空间之后的一个字节。

 
int*ptr1=(int*)(&a+1);

ptr1指向0x%%。因为a的类型是int [5],所以&a的类型是int (*)[5],所以,&a+1的值就是(unsigned)&a + sizeof(int [5])。所以,ptr1的值就是字节0x%%的地址值,类型是int *。

 
int*ptr2=(int*)((int)a+1);

ptr2指向数组a的起始字节的下一个字节,也就是0×01后面的0×00。

 
cout<<ptr1[-1]<<endl;

输出*(ptr1-1),ptr1-1指向a[4],所以输出5。

 
cout<<hex<<*ptr2<<endl;

输出*ptr2的16进制形式。
*ptr2即取出0×00, 0×00, 0×00, 0×02四个字节,*ptr2的最高字节是0×02,次高字节是0×00,然后是0×00,然后最低字节是0×00,所以输出
2000000。

0 0
原创粉丝点击