Chinaunix首页 | 论坛 | 博客
  • 博客访问: 335595
  • 博文数量: 82
  • 博客积分: 2602
  • 博客等级: 少校
  • 技术积分: 660
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-10 08:48
文章分类

全部博文(82)

文章存档

2008年(17)

2007年(65)

分类: C/C++

2007-09-20 10:46:37

最近一段时间论坛上有很多关于多维数组与指针的讨论,也许大家不屑看老谭的解释,现在本人结合老谭的c和自己的看法总结如下:
下面以二维数组为例
现有一个二维数组,它的定义如下:
int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}}
a是数组名,a数组包含三行即三个元素:a[0],a[1],a[2]。每一个元素又是一个一维数组,它包含4个元素(即四列)。这样看来,a数组相当于一个3行4列的矩阵。在内存中存放规则是:先存放a[0][0]~a[0][3]接着往下存放a[1][0]~a[1][3],依次类推。。
从二维数组的角度来看,a代表二维数组首元素的地址,现在的首元素不是一个整型变量,而是由4个整型元素所组成的一维数组,因此a代表的是首行(第0行)的首地址,a+1代表的是第1行的首地址。如果二维数组的首行的首地址是2000,则a+1为2008,因为第0行有4个整型数据,因此a+1的含义是a[1]的地址,即a+4x2=2008。同理,a+2代表a[2]的首地址,它的值是2016.
a[0]、a[1]、a[2]既然是一维数组名,而c又规定了数组名代表数组首元素的地址。因此a[0]=&a[0][0].
a[0]为一维数组名,该数组中的第2个元素显然应该用a[0]+1来表示。此时"a[0]+1"中的1代表1个列元素的字节数,即2个字节。a[0]=2000,那么a[0]+1=2002,同理a[0]+2是a[0]这个一维数组的第3个元素。
由于a[0]和*(a+0)等价(int a[6];int *p=a;a[5]=*(p+5)=*(a+5)),因此a[0]+1和*(a+0)+1的值都是&a[0][1] (*(a+i)+j=&a[i][j]),那么*(*(a+0)+1)或*(*a+1)就是a[0][1]的值了(*(a[i]+j)=*(*(a+i)+j)=a[i][j])
现在对a[i]的性质作进一步说明:a[i]从形式上看是a数组的第i个元素。如果a是一维数组名,则a[i]代表a数组的第i个元素所占内存单元的内容。但如果a是二维数组,则a[i]是代表一维数组名。它只是一个地址(a、a+i、a[i]、*(a+i)、*(a+i)+j、a[i]+j都是地址)。
 表示形式  含义  地址
 a  二维数组名,指向一维数组a[0] 2000 
 a[0],*(a+0),*a 第0行第0列元素的地址  2000 
 a+1,&a[1] 第1行首元素地址 2008
 a[1],*(a+1) 第1行第0列元素a[1][0]的地址  2008

 a[1]+2,*(a+1)+2,&a[1][2]

第1行第2列元素的地址   2012
 *(a[1]+2),*(*(a+1)+2),a[1][2]  第1行第2列元素的值  13
需要强调的是:
1、二维数组名a是指向行的,因此a+1中的1代表一行中全部元素所占的字节数
2、一维数组名a[0]/a[1]是指向列元素的,a[0]+1中的a代表一个元素所占的字节数指向。
3、在指向行的指针前面加一个*就转换为指向列的指针
4、在指向列的指针前面加&就成为指向行的指针
在3、4转换过程中的关键点是:a[i]=*(a+i)
在二维数组中:a+i=a[i]=*(a+i)=&a[i]=&a[i]=&a[i][0]即他们的地址值是相等的
 
 
阅读(1057) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~