Chinaunix

标题: [作废]再议int (*a)[n]等指针用法 [打印本页]

作者: ddvv    时间: 2007-09-20 05:02
标题: [作废]再议int (*a)[n]等指针用法
在看了scutan昨天发表的《关于指针与函数的几点小结》(http://bbs.chinaunix.net/thread-993238-1-1.html)后,学到了不少东西,但是还是有些地方没搞清楚。再查阅了有关资料以后,经分析得出一些心得,现与大家分享,有写得不对的地方请指正!
一、关于int (*a)[n]
    下面一句声明:
  1. int b[10]
复制代码
对于b本身,有两种意思:1、代表整个数组本身,代表b的类型为int [10],如使用sizeof(b)时(值为10);2、代表指针int *,指向b[0],如在指针运算中(int *p=b)。由此,对于int (*a) [n],在涉及到指针运算的环境下,(*a)代表指针int *,指向    int (*a)[0]。因此在引用(*a)[n]中的值的时候,要用*(*a+i)的方式。我们可以把(*a)看成一个整体,即和b一样,引用数组b[10]中的值时我们用*(b+i),则引用(*a)[n]中的值的时候自然就是*(*a+i)了。这里的(*a)在内存中是一个指针,指向数组的起始单元,而a则是指向(*a)的指针,所以a可以理解为二级指针。

二、int *p、int **pt与int a[n][m]
  1. int a[n][m];
  2. int *p;
  3. int **pt;
复制代码
这三个声明中a是一个二维数组,p和pt分别为int的一级和二级指针。二维数组与二级指针是截然不同的概念,使用对于a[n-1][1]来引用数组元素相当于*(a+(n-1)(m-1)+1),a实际上是一个一级指针。所以用
  1. p=a;   //正确!
  2. pt=a   //错误!
复制代码
(这里有一个不明白的地方,为什么用pt=&a也错误呢?请大家指教)

三、int (*a)[n]与int b[n]、int c[n][m]
    通过上面的分析,我们直到a是一个指向数组int (*a)[n]的指针因此有:
  1. a=&b;   //正确!
  2. a=&c;   //正确!
复制代码
三、关于指针的运算
   指针的自增(减)运算是非常常见的,那么它们的规则又是什么呢?对于int a[n],a++的结果是令a中的地址向高地址增加(减少)4位(对于32位机);而对于int (*a)[n],a++的结果是令a中的地址向高地址增加(减少)4*n位。两个式子结果的不同缘于它们所指向的类型的不同。对于一个指针,自增(减)运算是地址变化量等于sizeof(Type)。(Type为指针所指向的类型)。因此,直到指针所指向的类型,对于改种指针所指的指针运算的规律也就清楚了。从语法上讲,判断指针所指类型的方法:把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。例如,
  1.      int*ptr;   //指针所指向的类型是int
  2.   char*ptr;   //指针所指向的的类型是char
  3.   int**ptr;   //指针所指向的的类型是int*
  4.   int(*ptr)[3];   //指针所指向的的类型是int()[3]
  5.   int*(*ptr)[4];   //指针所指向的的类型是int*()[4]
复制代码
第一次写那么长的帖子,有什么不妥的地方,请大家指教。共同进步!
参考资料:
http://bbs.chinaunix.net/thread-993238-1-1.html    作者:scutan
http://community.csdn.net/Expert/TopicView3.asp?id=5290998    源自CSDN

[ 本帖最后由 ddvv 于 2007-9-20 11:47 编辑 ]

20070629025951(7)_200706290259517.gif (2.4 KB, 下载次数: 33)

20070629025951(7)_200706290259517.gif

作者: Godbach    时间: 2007-09-20 08:21
LZ这么早起来发帖子啊,不错,顶一下,支持原创啊。

[ 本帖最后由 Godbach 于 2007-9-20 08:24 编辑 ]
作者: ypxing    时间: 2007-09-20 08:40
理解错误的地方太多了
作者: ruoyisiyu    时间: 2007-09-20 08:52
原帖由 ypxing 于 2007-9-20 08:40 发表
理解错误的地方太多了

发现错误给人指出来,才不枉牛人一番
作者: ypxing    时间: 2007-09-20 09:06
>>int b[10]; 对于b本身,有两种意思:1、代表整个数组本身,代表b的类型为int [10],如使用sizeof(b)时(值为10);

>>使用对于a[n-1][1]来引用数组元素相当于*(a+(n-1)(m-1)+1),a实际上是一个一级指针

>>三、int (*a)[n]与int b[n]、int c[n][m]
>>a=&c;   //正确!

>>对于int a[n],a++的结果是令a中的地址向高地址增加(减少)4位(对于32位机);

>>int(*ptr)[3];   //指针所指向的的类型是int()[3]
>>int*(*ptr)[4];   //指针所指向的的类型是int*()[4]

以上都是不对的


原帖由 ddvv 于 2007-9-20 05:02 发表
在看了scutan昨天发表的《关于指针与函数的几点小结》(http://bbs.chinaunix.net/thread-993238-1-1.html)后,学到了不少东西,但是还是有些地方没搞清楚。再查阅了有关资料以后,经分析得出一些心得,现与大 ...

作者: ryuken2000    时间: 2007-09-20 09:08
这篇帖子容易误导初学者啊,楼主赶快修正错误吧。
为什么不先找个编译器试验一下,看看自己的推断是否正确呢?
作者: ryuken2000    时间: 2007-09-20 09:10
int a[n][m];
int *p;

p=a;   //正确!
作者: ypxing    时间: 2007-09-20 09:11
下面是我写的一篇有关指针和数组的帖子,希望有所帮助

http://bbs.chinaunix.net/viewthread.php?tid=960717
作者: ddvv    时间: 2007-09-20 11:12
看来考虑了那么久还是不对啊,里面的语句我在xp+gcc下面试过,好像没发现过什么问题。。。 继续学习~
作者: ddvv    时间: 2007-09-20 11:25
哦,原来我用代码来试的时候,对于二维数组的初始化我用
int a[2][2]={1,2,3,4}而不是{{1,2},{3,4}}
这就引起的误解……
作者: ye888    时间: 2007-09-20 11:37
的确LZ有好多理解不大正确……小心误导好多人!
作者: ddvv    时间: 2007-09-20 11:48
已经声明作废了,还是看大牛的帖子好了,向我这种还没学到家的确实还不应该写这种类型的帖子
作者: Godbach    时间: 2007-09-20 11:51
LZ钻研的精神值的学习,你也会成为大牛的!:wink:




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2