#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[4] = { 1, 2, 3, 4 };
//数组a在内存的分布为
// a[0] a[1] a[2] a[3]
//
//
//
int *p = (int*)((int)a + 1);//a是数组首元素的地址,值为0x003efb1c,
//前面带一个强制类型转换,就转换成了
//普通类型的int 变量,与后面的1相加
//结果就为0x003efb1d,加上win32中的
//小段模式,*p指向的内存区域为0x003efb1d
//开始的4个字节(0x003efb20),
//内容为0x02000000,十进制就为33554432
int *q = (int*)(&a + 1);//&a是数组的地址,
//&a + 1表示数组最后一个元素的下一位元素的地址
int *m = (int*)(a + 1); //a是数组首元素的地址
printf("a的地址:%p\n", a);
printf("p的地址:%p\n", p);
printf("p指向的数值:%d\n", *p);
printf("q的地址:%p\n", q);
printf("q指向的数值:%d\n", *(q - 1));
printf("m的地址:%p\n", m);
printf("m指向的数值:%d\n", *m);
system("pause");
return 0;
}
a是一个含有4个元素的int类型的数组,a的每个
元素都是int类型的数据,占有四个字节,在win32
环境下数据存储类型是小段模式,即数据的高位存
储在高地址位,数据的低位存储在地地址
处,如右图所示,a[0]元素
中的数据1,高字节0x01放
在地址处,高字节0x00放
在高字节处。
再看数组的定义,a[4]={1,2,3,4}
a为数组的名字,同时a也是
一个地址,a是这个数组的地址
而&a[0]是元素a[0]的地址。
所以在int *q = (int*)(&a + 1)中,&a是数组的地址,&a + 1表示数组最后一个元素的下一位元素的地址,注意此时q已经越界,指向图中的0x003efb2c处!
int *m = (int*)(a + 1); //a是数组首元素的地址,这个好理解。
int *p = (int*)((int)a + 1);// a是数组首元素的地址,值为0x003efb1c,前面带一个强制类型转换,就转换成了普通类型的int 变量,与后面的1相加结果就为0x003efb1d,加上win32中的小段模式,*p指向的内存区域为0x003efb1d开始的4个字节(0x003efb20),内容为0x02000000,十进制就为33554432。