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

C里面的指针怪问题,很困惑

楼主ej(辉)2004-12-02 18:24:21 在 C/C++ / C语言 提问

程序如下:  
   
  main()  
  {  
          int   a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};  
          int   *p;  
          p=a;  
          p=p+1;  
  }  
   
  调试时候,  
  a的地址:0x240ff30  
  p=a   所以p的地址:0x240ff30  
  但是最后p=p+1后   p的地址:0x240ff34  
   
  问题:  
  p开始的时候已经指向a,即数组的行地址,所以理论执行p+1后,地址应该为0x240ff40。但是调试结果并不相同。  
  另外,我试过将最后两句改成:  
  p=a+1;     0x240ff40  
  p=p+1;     0x240ff44  
   
  结果显示p+1指向下一列元素,为何?  
  问题点数:0、回复次数:28Top

1 楼milozy1983(Detective)回复于 2004-12-02 18:38:01 得分 0

我把p=p+1理解为基址寻址法偏一地址改变,而p=a+1是基址改变Top

2 楼BlackEagle_(黑鹰)回复于 2004-12-02 18:51:10 得分 0

p   =   a[0]   才是指向数组的首行地址Top

3 楼pikaqiu96(学无止境)回复于 2004-12-02 18:59:59 得分 0

p=p+1后,p地址应该为0x240ff38,你怎么认为是0x240ff40?  
  每一行不是8个字节吗?Top

4 楼great_chenliang(Eric)回复于 2004-12-02 19:00:27 得分 0

p=a   所以p的值(注意,不是地址):0x240ff30  
  但是最后p=p+1后   p的值:0x240ff34  
   
  不对吗?32位int为4字节呀。Top

5 楼cyberkit(木子)回复于 2004-12-02 19:04:40 得分 0

注意   int   *p   这个语句  
  指针p是int型的!当你对它进行p=p+1时,是与类型相关的,但跟前面的数组大小无关。  
  int的大小是4,所以p=p+1比原来大了一个int,就这么简单啦。  
   
  问题1和问题2本质是一样的,关键是你没理解指针的加减跟自己的类型是相关的!Top

6 楼raining(下雨了)回复于 2004-12-02 19:06:48 得分 0

没有分?Top

7 楼yangsiqun(灌水是我有声的抗议)回复于 2004-12-03 18:23:18 得分 0

cyberkit木子:   正解Top

8 楼jnch(*ω*小笨)回复于 2004-12-03 19:07:13 得分 0

UPTop

9 楼bingbing1981(^_^)回复于 2004-12-03 19:39:39 得分 0

木子说的好Top

10 楼clwforluv(上海紧缺人才)回复于 2004-12-03 20:54:02 得分 0

a的地址:0x240ff30  
  p=a   所以p的地址:0x240ff30  
  大部分的问题大家都说完了,我也不多说了,不过有个地方还是希望楼主注意一下,从以上楼主说的这两句话我相信楼主有一点还有误区,int   *p;p=a;这里,p指向了a的地址,但是p本身的地址并不是a的地址,楼主可以用这个语句验证:  
  int   *p,x=5  
  p=&x;  
  printf("%p,%p",p,&p);  
  我们说将某个地址赋个某个指针变量时候,被赋值的指针变量他本身是有自己的地址的,不会随着被赋值的变化而变化的,只是他所指向的地址是变化了。Top

11 楼bsnhk((void *)0)回复于 2004-12-03 21:06:44 得分 0

木子说的不全对,p的类型是int*而不是int.  
  在c语言中,任何维数组本质上都是一维数组,所以考察任何维数组的指针问题时,绝对必须从一维数组的角度去考察。数组名a除去应用于sizeof和&这两个运算符的场合外,其意义都是指数组a中下标为0的那个元素的指针,这时的下标为0的数组元素就是a[0],所以数组名a也就是&a[0],a+1就是(&a[0])+1,也就是&a[1]。  
  对于任何维的数组a,&a的意义是“指向一维数组a的指针”(而不是指向一维数组a中元素的指针)。  
  小结:a、&a[0]是同类型的指针,都是“指向一维数组a中下标为0的那个元素的指针”;&a是指向一维数组a的指针;&a[0][0]是指向一维数组a[0](   注意,a[0]就是一维数组a[0][4]的名称,下标[4]是指这个一维数组有4个元素)中下标为0的元素的指针。再次提醒注意“指向数组的指针”和“指向数组元素的指针”是有区别的,在多维数组中,各个层次上的“指向数组的指针”和“指向数组元素的指针”也都是不同的(指针类型不同)。  
  呵呵,这些问题要上机实践才能体会到!Top

12 楼ej(辉)回复于 2004-12-03 21:29:19 得分 0

解答多样性啊,等我了解一下Top

13 楼bbn9435(bbn)回复于 2004-12-03 21:37:44 得分 0

指针的算术运算只有加和减.  
  指针每加一次,它就指向他的基本类型的下一个元素的内存位置;  
  指针每减一次,它就指向前面一个元素的内存位置.  
  就是说:所有的指针的算术运算都是根据指针的具体类型来计算的:-)Top

14 楼ej(辉)回复于 2004-12-03 23:01:59 得分 0

我理解是这样的:  
  a[3][4]是一个二维数组。“a”与“a[0]“都是数组的首地址,但“a”是指向行的,“a[0]”是指向列的。  
  所以若数组首地址为:0x240ff30  
  则a由于指向行,所以a+1应该就指向下一行,地址应该是:0x240ff40(一行有4个数据,一个4字节)  
  a[0]由于指向列,则a[0]+1的地址应该指向下一列,地址应该是:0x240ff34  
   
  大家觉得有没错?Top

15 楼great_chenliang(Eric)回复于 2004-12-03 23:18:23 得分 0

人家白讲了。Top

16 楼great_chenliang(Eric)回复于 2004-12-03 23:21:06 得分 0

[]这个东西在标准里不叫类型标识符,而叫存储标识符。所以,你可以推得,C/C++没有数组类型。这下懂了吧。Top

17 楼luyg614(CouCou)回复于 2004-12-03 23:29:03 得分 0

int   (*   p)[4];  
  p是指向指针的指针  
  p=a   p是a的地址  
  *(p+i)   应该是第i行的地址..Top

18 楼bbn9435(bbn)回复于 2004-12-03 23:40:36 得分 0

我是这么认为的:  
  一个"数",可以认为它表示一个"数值",也可以表示一个"地址"  
  对于n维数组a[1维][2维]...[n维]来说  
  可以看作是多个1维数组嵌套组成的  
  只不过1维数组包含的是"数值"  
  而n维数组包含的是"地址",由这些"地址"指向另一个(n-1)维数组,一直到1维数组罢了  
  所以  
  对于n维数组a[1维][2维]...[n维](n>=1)来说  
  a表示的是数组a第1个元素的"数",即a[0].至于这个数表示的意思是"数值"还是"地址",就看这个数组的维数了  
  a+2表示的是数组a第3个元素的"数",即a[2].同理,这个数表示的意思是"数值"还是"地址",也看这个数组的维数了  
  如果a[0]这个"数"表示的是"地址",那么就分析a[0]这个数组喽.  
   
  Top

19 楼bsnhk((void *)0)回复于 2004-12-04 00:02:36 得分 0

有些东西听别人解释是没多大用处的,要自己冥思苦想后才能得道!Top

20 楼bbjt()回复于 2004-12-04 00:11:48 得分 0

开始觉得木子说的不错,后来想想bsnhk(欲哥)说的也有理。Top

21 楼pig_liang(朱)回复于 2004-12-04 02:11:02 得分 0

bsnhk(欲哥)对p=a+1;     0x240ff40作出了很好的解释.  
  而对于另外一个问题则是:在C/C++语言中指针的大小就是4字节,所以当p+1时,地址加4,所以p=p+1;     0x240ff44Top

22 楼bbn9435(bbn)回复于 2004-12-04 08:47:51 得分 0

TO:   pig_liang(朱)  
  好像错了吧??  
  c中的指针运算应该是跟本身指向的数据类型有关的  
  比方说:  
  int   *pn   和   char   *   pch都加1  
  如果起始地址都为1000的话  
  那么pn+1=1004,而pch+1=1001  
  就是说pn是int   *类型的,而pch是char   *类型的  
  Top

23 楼sink()回复于 2004-12-04 10:37:52 得分 0

p和a的移动粒度是不同的,a+1,a指向a[1]的首地址,可以把这个二维数组看成3行4列的,a+1指向第二行的首地址,在你的系统中每个int占4个字节,所以p=a+1=+4*4=a+16=a+0x10=0x240ff40  
  p=a时,p++,p指向第一个元素的地址,你的系统中int4位,所以p+1=0x240ff34Top

24 楼ej(辉)回复于 2004-12-04 11:54:46 得分 0

我已经瞑想了两天了。。。。。  
   
  看了大家说的,就是说  
  p=a   0x240ff30  
  p=p+1   0x240ff34     这时的p+1的值是按照p原来的类型累加的,因为原来是是int型,所以0x240ff34  
   
  如果要另p=p+1移动到下一行,就只有定义改为int   (*p)[4]。  
  大家觉得如何?  
   
  Top

25 楼williamVII(spread)回复于 2004-12-04 16:27:22 得分 0

so   simpleTop

26 楼tcdddd(迷茫男人)回复于 2004-12-04 19:02:57 得分 0

bsnhk(欲哥)+     ej(辉)的解释   ,这样应该足够解释这道题了Top

27 楼bsnhk((void *)0)回复于 2004-12-05 10:19:43 得分 0

to   ej(辉):  
          "如果要另p=p+1移动到下一行,就只有定义改为int   (*p)[4]。"  
          错,应该将定义改为int   (*p)[3][4];Top

28 楼wolfkain()回复于 2004-12-05 13:52:48 得分 0

int   a[n][m],*p;  
  时a的指针类型和p不同,一个指向2*m个字节的类型,一个是指向2*1个字节的类型。  
  同理:  
  int   a[i][j][k],*p;  
  时a的指针类型和p不同,一个指向2*j*k个字节的类型,一个是指向2*1个字节的类型。  
  也就是说对于N维数组a[][][]...[],数组名a相当于一个指向N-1维数组的指针。Top

相关问题

  • 函数指针的困惑
  • c/c++的困惑...
  • C++ ? STL : MFC 困惑
  • 对C++的困惑!!!
  • 掌握 C++ 指针?
  • C++指针问题
  • C++指针问题
  • 一个C语言函数指针的怪问题
  • 学习c++的困惑!?
  • 关于C++的困惑!

关键词

  • c/c++
  • 指针
  • 数值
  • 数组
  • 指向
  • 地址
  • 维数组
  • x240ff
  • 元素
  • 类型

得分解答快速导航

  • 帖主:ej

相关链接

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

广告也精彩

反馈

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