1、a+1(是地址)和*(a+1)(是内容)为什么表示的是同一个值呢?
a+1是二维数组a中序号为1的行的首地址(序号从0开始算),而*(a+1)并不是a+1单元的内容(值),
因为a+1并不是一个变量的存储单元,也就谈不上他的内容了。*(a+1)就是a[1],而a[1]是一维数组名,所
以也是地址,它指向a[1][0]。a[1]和*(a+1)都是二维数组中地址的不同表示方式。
2、int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
a代表的是首行的首地址,a+1代表序号为1的行的首地址。如果二维数组的首行的首地址为2000,因为
一个整型数据占4哥字节,则a+1的值应该是2000+4*4=2016。
但是a[0]+1代表首行的第一个(从0开始算)数据的地址,和a+1不同,a[0]+1的值是2000+4*1=2004,
而不是2016。以此类推,a[0]+2、a[0]+3分别代表首行第二个、第三个数据的地址。
a[0]和*(a+0)是等价的,a[1]和*(a+1)是等价的,一次类推,因此,a[0]+1和*(a+0)+1都是&a[0][1]。
a[1]+2和*(a+1)+2的值都是&a[1][2]。但是注意:且不要将*(a+1)+1写成*(a+1+1),后者会变成*(a+2).
切记:*(a+1)和a[1]是等价的,上面所说的都是地址,并不是所代表的二维数组的值,因此,*(a[0]+1)
和*(*(a+0)+1)都表示的是a[0][1]的值。*(a[i]+j)和*(*(a+i)+j)都表示的是a[i][j]的值。
3、为什么a+1和*(a+1)都是2016呢?
a+1是二维数组a中序号为1的行的首地址,而*(a+1)并不是a+1单元的内容(值),因此a+1并不是一个
变量的存储单元,也就谈不上它的内容了,*(a+1)就是a[1],而a[1]是一维数组,在二维数组中只是表示第一
行的首地址,指向a[1][0],所以,a[1]和*(a+1)都是二维数组中地址的不同表示形式。
4、int a[4];和int (*p)[4];
前者表示包含4个整型元素的以为数组,而后者表示的是,(*p)有4个元素,每个元素为整型,也就是p所指
的对象是有4哥整型元素的数组,即P是指向以为数组的指针。此时,P只能指向一个包含4个元素的一维数组,不
能指向一维数组中的某一个元素。P的值就是该一维数组的起始地址,此时p不是int 型,而是int(*)[4]型,p的基类型
是一维数组,其长度为16个字节。对于*(p+1)+1,p每加一,地址就增加16个字节(4个元素,每个占4个字节)。
而对于括号外面的加一,则不是已基类型为基础单位的,每次地址增加4个字节。
5、用指向数组的指针做函数的参数
多维数组也可以像一维数组那样做函数的参数,用指针变量做形参,以接收实参数组名传递来的地址。有两种方法:
第一:用指向变量的指针变量
第二:用指向一维数组的指针变量
#include <stdio.h>
void main()
{
...........
average(*score ,12); //此时是&score[0][0]
search(score, 2); //此时是该数组0行起始地址,即score[0]地址
...........
}
void average(float *p,int n) //
{
.........
}
void search(float (*p)[4],int n) //指向包含4个元素的一维数组的指针变量
{
........
printf("%5.2f", *(*(p+n)+i)); //p+n是score[n]的起始地址
*(P+n)+i是score[n][i]的地址
*(*(p+n)+i)是score[n][i]的值
}
实参与形参如果是指针类型,应当注意他们的类型必须一致。不应把int *型的指针(即元素的地址)
传给int(*)[4]型(指向一维数组)的指针变量,反之亦然,应当是“门当户对”。
这点很重要,也是非常容易忽视的地方,比如,将上面的main函数中,调用search函数时,实参是
score,即score[0]的起始地址,对应的形参p指向包含4个整型元素的一维数组,二者是一致的类型,但是
如果将search(score,2)改为search(*score,2)将会产生错误,虽然score和*score都是地址,但是*score
和形参P的类型不匹配。