数组的首地址,数组名取地址,地址的强制转换为int
来源:http://blog.csdn.net/normal_cai/article/details/8252603
#include <stdio.h>
int main() { int a[5]={7,8,9,10,11}; int *ptr1=(int *)(&a+1);
int *ptr2=(int *)((int)a+1);
printf("%d\n",&a); printf("%d\n",(int)a); printf("%d,%d\n",ptr1,ptr2); printf("%d,%x\n",ptr1[-1],*ptr2);
return 0; }
输出结果:
1245036 1245036 1245056,1245037 11,8000000 Press any key to continue 结果怎么会是这样的呢???特别是&a,(int)a的值都是1245036 那么分别加以后怎么结果不是一样的???还有就是*ptr2的值(十六进制)是:80000这个值不是随机数呢??(我开始认为是的,但实际不是的),让我们来一起分析一下:
首先我们要知道a[5]={7,8,9,10,11};的意思:在内存中开辟一个数组大小是: sizeof(int)*5=4*5=20个字节(一个整形占4个字节),那么数组名a的值就是这片内存单元的首地址
我们看到printf("%d\n",&a);printf("%d\n",(int)a);输出的结果:1245036 1245036,我们可以知道&a是上面内存单元的首地址,(int)a是把首地址转换成int的数据。
int *ptr1=(int *)(&a+1); 其中&a+1,不是简简单单的加一,而是加上数组的大小(表示指针移到数组内存单元的最后的下一个单元地址)为什么???那是因为系统在内存中(具体的说应该是栈中)为数组分配一个连续大小为20字节的大小,并把首地址赋值给数组名a,那么&a+1就是表示这个内存的下一个地址,这个加一不是我们平时说的整数1,而是数组的大小即1245036+20=1245056,那么指针变量ptr1就是指向此内存单元,那么*ptr表示地址为1245056单元的内容,而ptr1[-1]等价于*(ptr1-1),ptr1-1即先把指针后移一个,不是指向数组的最后一个元素吗??,那么*(ptr1-1)不就是数组最后的值吗???即11,十六进制是b
而int *ptr2=(int *)((int)a+1); 就是在1245036+1=1245037,这又是为什么???原因很简单那是因为:(int)a表示的把数组地址即内存单元的编号转换成整数,那么此时的(int)a+1加一相当于加一个整数!!
注意1245037在于数组第一个和第二个元素地址中间(可以数组数组的第一元素和第二个元素的地址分别是:1245036 1245040),那么*ptr2的值就是第一个元素的二进制和第二个元素的二进制的组合:那我们看看数组第一元素和第二个元素的二进制是:
7的二进制:0000 0000 0000 0000 0000 0000 0000 0111
8的二进制:0000 0000 0000 0000 0000 0000 0000 1000
那么*ptr2的值就是从7的二进制的第二个字节开始数四个字节(即取7的后三个字节和8的第一个字节):
0000 0000 0000 0000 0000 0111 0000 0000
注意在内存是先放低字节,然后是高字节,那么计算的时候的到过来即:0000 0000 0111 0000 0000 0000 0000 0000 0000
那么对应的十六进制是:0080000,即80000