这个可不是老师故意为难的,而是作为IT一员所必须理解的.
对于编译器来说,"[]"是个优先级很高的单目运算符,它是这样解析这运算符的:
array[m1][m2][m3][m4]...[mn]=*(*(*(*(*(array+m1))+m2)+m3)+m4)+...+mn);(n>=1)
这里来讨论简单点的咯,就取n=2时吧,此时有: array[m1][m2]=*(*(array+m1)+m2);
要透彻理解这表达式,得先弄清楚指针的加法是怎样的.
指针p=指针q+n(n为整数,p,q为同类型指针),意思即:指针p指向了指针q所指向内存处的后n*q所指向的单位的大小.
举个例子吧:
int array[4][6];
array是个二维数组,由4个一维数组array[0],array[1],array[2],array[3]组成.array也是个二维常量指针,它指向array[0].所以,对于(array+2)这个指针,它是指向array所指向内存地址处的后(2*sizeof(array[0])),即(12*sizeof(int))个字节处.(即array+2指向array[2]). 而array[2]这个一维指针则指向array[2][0]
而(*array)(即array[0])便为一维指针了,它指向array[0][0],所以,对于(*(array+2)+3)这个指针,由于array+2指向array[2],所以*(array+2)指向array[2][0].所以(*(array+2)+3)便是指向(*(array+2))所指向内存处的后(3*sizeof(array[2][0])),即(3*sizeof(int))个字节处.(即(*(array+2)+3)指向array[2][3]).
所以,便有了array[2][3]=*(*(array+2)+3). 2代表指针要后移2*sizeof(array[0])个字节,3代表指针要移动3*sizeof(array[2][0])个字节.所以,指针一共要移动多少也就清楚了.
因为不知道你学得怎样,所以讲的有些啰嗦呃,但尽量清楚些....
再举个典型例子:
int array[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
printf("%d\n", array[1][7]);
这该输出多少呢?还是越界错误?
解答:array[1][7]被编译器解析为:*(*(array+1)+7),后移的总字节为1*sizeof(array[1])+7*sizeof(array[1][0]),即11*sizeof(int). 而该数组大小为12*sizeof(int),array指针是可以后移11*sizeof(int)个字节的,所以不会越界.所以,(*(array+1)+7)这个指针指向了该数组第12个单位(第一个单位为a[0][0]),即array[2][3],即12,所以程序输出12.
也可以这样快速看出array[1][7]值为什么:arra[1]指向array[1][0],是数组的第5个元素.7表示让array[1]这个指针再后移7个单位.所以array[1][7]便是该数组的第12个单位也即array[2][3]了.所以输出12.
追问谢谢,回答得超详细,不过这个*(*(a+6))还是不是很明白,我可以降它理解为这个数组的第七个数吗?但是它的结果是1245152,怎麼会有这麼多数字?
追答你首先得明白指针a指向什么,然后你才能知道*(*(a+6))指向什么。a是数组名,即常量二维指针。它指向a[0]这个一维数组。所以a+6便是指针得后移6*sizeof(a[0])即6*4*sizeof(int)个字节。所以*(*(a+6))是该数组的第25个数,明显越界了。