Chinaunix首页 | 论坛 | 博客
  • 博客访问: 32992
  • 博文数量: 14
  • 博客积分: 255
  • 博客等级: 二等列兵
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2010-06-30 13:47
文章分类
文章存档

2011年(14)

我的朋友

分类: C/C++

2011-11-14 14:23:51

原文的问题在此:

代码如下
  1. #include <stdio.h>
  2. int main(int argc, char* argv[])
  3. {
  4.     int iRet = checkSystem();

  5.     int a[4]={1,2,3,4};
  6.     int *ptr1=(int*)(&a+1);
  7.     int *ptr2=(int*)((int)a+1);
  8.     printf("%x,%x",ptr1[-1],*ptr2);
  9.     return 0;
  10. }

实际输出结果: 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
首先这个问题设计到内存使用方式的问题,即大小端的存放方式。详见:http://blog.chinaunix.net/space.php?uid=22843939&do=blog&id=3017729 
下面解释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个字节)。

如果此时您已经对大小端有了了解,那下面的存储方式您一定也能看明白了。

回答csdn上的一个问题--指针和内存地址的关系 - 一叶菩提 - 一叶菩提
  如此看来,ptr2 指向的位置是 0x0012ff49 这个字节。而ptr2指向的数据类型是int型,所以呢,*ptr2取出来的内容也是int,即4个字节的内容作为 *ptr2 的值。
也就是 *ptr2 = 下图的数据:
回答csdn上的一个问题--指针和内存地址的关系 - 一叶菩提 - 一叶菩提
  既然是小端存储,那读取当然也要按小端读取,即 低地址的内容在数据的低位,高地址的内容在数据的高位,即可拼成一个int 数据为 0x02000000。所以ptr2 就是 2000000 了。

阅读(765) | 评论(0) | 转发(0) |
0

上一篇:内存大小端的概念

下一篇:SQL使用技巧

给主人留下些什么吧!~~