CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C/C++ >  C语言

指针问题,问了N个人还没明白,100分求助

楼主hedongfu(何东付)2006-10-28 10:52:44 在 C/C++ / C语言 提问

int   a[5]={1,2,3,4,5};  
  int   *ptr=(int   *)((&a)+1);  
   
  printf("%d,%d",*(a+1),*(ptr-1)); 问题点数:100、回复次数:22Top

1 楼wanfustudio(雁南飞:知识之败,慕虚名而不务潜修也)回复于 2006-10-28 11:01:15 得分 0

关键是那个强制转化~Top

2 楼mu_yang(穆扬)回复于 2006-10-28 11:01:25 得分 0

2,5Top

3 楼wanfustudio(雁南飞:知识之败,慕虚名而不务潜修也)回复于 2006-10-28 11:17:42 得分 30

一道笔试题不理解  
  silver6   |   25   十一月,   2005   23:36  
   
   
  main()  
  {  
  int   a[5]={1,2,3,4,5};  
  int   *ptr=(int   *)(&a+1);  
   
  printf("%d,%d",*(a+1),*(ptr-1));  
  }  
   
  int   *ptr=(int   *)(&a+1);   //指向整个数组末尾  
  int   *ptr=(int   *)(a+1);   //指向a的下一个元素  
   
  main()  
  {  
  int   a[5]={1,2,3,4,5};  
  int   *ptr=(int   *)(&a+1);  
   
  printf("%d,%d",*(a+1),*(ptr-1));  
  }  
   
  cout<<*(a+1)<<endl;   output:2   没有什么费话~  
  cout<<*(ptr-1)<<endl;   output   :5  
  因为   int   *ptr=(int   *)(&a+1);  
  这里是(&a   +1)   而非   a+1  
   
  &a的类型是数组,所以加1的话,系统会认为加一个a数组的偏移,即5个int  
   
  &a+1就是首地址+1  
  主要是(int*)做了操作,具体什么操作也不是很了解。等高手回答。  
  如果  
  &a0x0012ff6c   ""  
  则  
  &a+10x0012ff6d   ""  
  这里  
  int   *ptr=(int   *)(&a+1);  
  ptr的地址和(&a   +1)的地址并不相同  
  等待高手回答(int   *)做了什么操作  
   
  &a[0]   才是首地址。  
   
  &a是指向首地址的指针。  
   
  事实证明:  
  *(a+1)就是a[1],*(ptr-1)就是a[4]  
  执行结果是2,5  
  &a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)  
   
  ,&a可以认为是整个数组的地址,因此不能单纯的用首地址+1。  
   
  1.int   *   是强制转换为int型指针。  
  2.对于int   a[5]={1,2,3,4,5};a就是数组首地址。a+1是首地址+1.   a   等价于&a[0].  
  3.   &a不是首地址,可以看作是整个数组的指针。&a+1是   a[5]后面的地址.  
  &a+1≠a+1  
   
  废话少说;接:2,5  
   
  int   a[5]={1,2,3,4,5};  
   
  //  
  //   &a   指向是   a[5]的类型,   &a   +   1指向下一个a[5]类型,等同于指向第6(索引为5)个int  
  //   int   *ptr   =   (int*)(&a   +   1)   强制转换指针为int*  
  int   *ptr=(int   *)(&a+1);  
   
  printf("%d,%d",*(a+1),*(ptr-1));   //ptr   -   1   指向上一个int,即索引号为4的整数  
   
  int   *ptr=(int   *)(&a+1);  
  则ptr实际是&(a[5]),也就是a+5  
  原因如下:  
  &a是数组指针,其类型为   int   (*)[5];  
  而指针加1要根据指针类型加上一定的值,  
  不同类型的指针+1之后增加的大小不同  
  a是长度为5的int数组指针,所以要加   5*sizeof(int)  
  所以ptr实际是a[5]  
  但是prt与(&a+1)类型是不一样的(这点很重要)  
  所以prt-1只会减去sizeof(int*)  
   
  int   *ptr=(int   *)(&a);  
  0040105B   lea   eax,[ebp-14h]   ;a[0]的地址  
  0040105E   mov   dword   ptr   [ebp-18h],eax  
   
  int   *ptr=(int   *)(&a+1);  
  0040105B   lea   eax,[ebp]   ;这里比上边增加了14h,即20个字节  
  0040105E   mov   dword   ptr   [ebp-18h],eax  
   
  &a是数组指针,其类型为   int   (*)[5];  
  同意,谭浩强的c语言编程里讲的很清楚!Top

4 楼mumutingyu(木木)回复于 2006-10-28 11:49:03 得分 10

关键时对于指针加法的理解,是移动指针到该类型的下一个上。&a+1时中是对&a进行加1,而&a是数组的指针,所以+1应该是移动到数组最后也就是a[4]的下一个位置上了。  
  下面int   *ptr=(int   *)((&a)+1);也就是说ptr是指向a[4]的下一个int型指针。  
  所以(ptr-1)应该是指向a[4]的int型指针,所以*(ptr-1)=a[4]=5成立Top

5 楼Jokar(贪睡鼠)回复于 2006-10-28 11:54:28 得分 0

&a:   行指针   :)Top

6 楼chinese_zmm(信誉第一)回复于 2006-10-28 11:59:07 得分 0

int   *ptr=(int   *)((&a)+1);//&a+1相当于&a是一个2级指针a[0][5],它加一的偏移量是5,而  
  *(&a)+1的偏移量才是一。Top

7 楼kookworm()回复于 2006-10-28 12:57:18 得分 10

a是一维数组名,所以&a就是以定义的一维数组a做为一个存储单元,由于数组a有5个整形元素,占10个字节,这样&a+1就相当于一次移动10个字节,即移到了数组后的第一个字节。而(int   *)又将以数组a为一个单元的指针类型,转化为了以整形为一个单元的指针类型(每移动一次为2个字节),结果使得ptr-1指向了数据的最后一个元素Top

8 楼swimmer2000(时间是用来浪费的,所以每当我做了一点事都觉得很自豪)回复于 2006-10-28 14:54:24 得分 0

int   *ptr=(int   *)((&a)+1);   //&a是一个二级指针,加1后谁都不知道会有什么结果.Top

9 楼jie00677(jie)回复于 2006-10-28 15:05:52 得分 0

运行一下看看几个关键变量的变化规律就应该可以  
  分析一下原理了,可惜在网吧,没办法运行,有空看看吧Top

10 楼jixingzhong(瞌睡虫·星辰)回复于 2006-10-28 15:42:35 得分 50

int   a[5]={1,2,3,4,5};  
  int   *ptr=(int   *)((&a)+1);  
   
  printf("%d,%d",*(a+1),*(ptr-1));  
  ================  
  a+1   的结果是明显的,  
  得到的是指向第二个元素的指针,   所以结果输出2,  
  下面说一下第二个式子:  
   
  a   是数组,  
  对数组名字取地址后,   得到是一个指向一个5个元素数组的指针,  
  然后这里   (&a)+1   表示指针下移一个   “元素”,  
  注意,   这里的元素是一个5元素数组,   相当于是指向了   a   的第六个元素,  
  (这里越界溢出了,但是   C   中没有越界保护,只要没有非法操作,   那么程序继续运行)  
  也就是说,   ptr   初始化为指向了   a   的第六个元素!!  
   
  然后有一个强制转换   int   *,  
  这里就把一个   指向   5   元素数组的指针,   变成了一个指向   int   的指针,  
  这个变化导致的结果就是   指针步长变化了,    
  一个   int   指针,   ptr-1   表示退后一个元素位置,  
  注意,   现在   ptr   的类型是   int   指针,   退后一个   int   元素,   就是指向a第五个元素,  
  结果就是输出了   5Top

11 楼jixingzhong(瞌睡虫·星辰)回复于 2006-10-28 15:45:08 得分 0

关键就是   指针类型和它对应的步长!  
   
  对指针   +1     -1   是移动指针“元素长度”距离,  
  一个   int   指针ptr,   -1   就是退后一个   int   元素位置;  
   
  而一个   指向5元素数组   的指针(楼主若还是不清晰,请看   指向数组的指针部分内容)  
  移动一个元素就是移动一个   数组长度空间,  
  或者理解为是一个   2维数组   的行指针也可以   ...Top

12 楼left_zxp(专逃课的左手)回复于 2006-10-28 20:58:30 得分 0

象int   a[i][j]中一样,&a[i][j]是int   *[j],即是一个行指针,对它的操作是以j*sizeof   (size)为单位的Top

13 楼skkcpp()回复于 2006-10-29 00:02:55 得分 0

我觉得是 2,2Top

14 楼gzlyb(冰风)回复于 2006-10-29 00:44:05 得分 0

这里的高手解释得很清楚  
  lz应该满意了Top

15 楼todototry(来csdn,学会扯淡了...)回复于 2006-10-29 00:57:42 得分 0

markTop

16 楼yutongjun108(指南针)回复于 2006-10-29 08:28:48 得分 0

markTop

17 楼zhongfusong()回复于 2006-10-29 08:58:18 得分 0

a的类型可以认为是int[5],所以&a   +   1,就增加5个int的地址,就指向a[4]的下一个int   地址  
  但由于p是int   *,所以p-1只减小一个int类型的地址Top

18 楼ppx3200(知之为知之,不知为不知!)回复于 2006-10-29 10:55:10 得分 0

非常的清楚了。MARKTop

19 楼gxh9314(什么时候结贴呀!!!!)回复于 2006-10-29 11:20:24 得分 0

dingTop

20 楼zjbirdman()回复于 2006-10-29 12:25:14 得分 0

markTop

21 楼lsd1025()回复于 2006-10-29 13:02:28 得分 0

wanfustudio这位已经讲得太清楚了,  
  这个问题我完全同意他的讲法Top

22 楼anchor720(菜鸟)回复于 2006-10-31 19:55:42 得分 0

mark  
  Top

相关问题

关键词

得分解答快速导航

  • 帖主:hedongfu
  • wanfustudio
  • mumutingyu
  • kookworm
  • jixingzhong

相关链接

  • C/C++ Blog
  • C/C++类图书
  • C/C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo