原文的问题在此:
代码如下
- #include <stdio.h>
-
int main(int argc, char* argv[])
-
{
-
int iRet = checkSystem();
-
-
int a[4]={1,2,3,4};
-
int *ptr1=(int*)(&a+1);
-
int *ptr2=(int*)((int)a+1);
-
printf("%x,%x",ptr1[-1],*ptr2);
-
return 0;
-
}
实际输出结果: 4,2000000
平台:win32 xp。小端存储方式。
解释:1、ptr1[-1] = 4。
源于 int *ptr1=(int*)(&a+1);
&a是取的数组a的首地址,也是数据‘1’所在的地址。
+1:&a是一个指针,指针的加法运算要根据指针所指向的数据类型决定这次+1要跳过几个字节。这是就要知道&a这个指针所指向的内容的数据类型,无疑int [4]。这时,即可判断这个指针要向后跳过一个 int [4]的大小,即 4*8 个字节。
此时ptr1指向的是数据a最后一个字节的后一个字节。(比如a的最后一个字节是0x11111111,那么ptr1指向0x1111111112)。
ptr1[-1],在取内容是的计算是 ptr1+(-1)。这时又设计到指针的加法运算了。ptr1 指向的数据的类型是int,ptr1+(-1)代表,ptr1所指向的位置,要向前跳过一个int类型的字节数。即 ptr1 只向了a[3]的位置。
所以ptr1[-1] = 4;
2、*ptr2 = 2000000
下面解释int *ptr2=(int*)((int)a+1);
(int*)a,显然这是把a的地址转成int型的数据了(这个数据就是数据a的首地址的int型表示形式)。(int*)a + 1,表示数据a首地址的下一个字节。(此时要区分,为什么不用a+1,不懂就看上面红色的指针算法计算方法)。
此时ptr2 指向数据a的首地址的下一个字节。即存放a[0]的第二个字节(a[0]总共占4个字节)。
如果此时您已经对大小端有了了解,那下面的存储方式您一定也能看明白了。
如此看来,ptr2 指向的位置是 0x0012ff49 这个字节。而ptr2指向的数据类型是int型,所以呢,*ptr2取出来的内容也是int,即4个字节的内容作为 *ptr2 的值。 也就是 *ptr2 = 下图的数据:
既然是小端存储,那读取当然也要按小端读取,即 低地址的内容在数据的低位,高地址的内容在数据的高位,即可拼成一个int 数据为 0x02000000。所以ptr2 就是 2000000 了。
阅读(780) | 评论(0) | 转发(0) |