int main()
{ int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int *ptr1 = (int *)(&aa + 1); int *ptr2 = (int *)(*(aa + 1)); printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));system("pause");return 0;
}
很显然aa是一个二维数组,很多人把二维数组抽象的理解成一个矩阵,如
[1,2,3,4,5],
[6,7,8,9,10],
不能说这是错误,这种思维不利于对二维数组更好地理解,那我们该怎么理解呢?维度是空间的一个概念,我们可以抽象的理解为二维空间是由一维空间组成,三维空间是由二维空间组成,同理,二维数组,其实是由多个一维数组组成的,这个二维数组是两行五列,就是说这个二维数组是由2个元素个数为5的一维数组组成,设这两个一维数组为b[5],c[5],令b[5]={1,2,3,4,5},c[5]={6,7,8,9,10}。接下来开始分析代码:
int *ptr1 = (int *)(&aa + 1);
这个&aa+1怎么理解呢?&aa指二维数组aa的地址,&aa+1就是指向下一个数组的首地址(在这里我们可以形象的理解为元素aa[2][5]的地址,很显然aa[2][5]已经越界了,这里只是便于理解而特殊引用的),然后将其进行int*强制转换赋给ptr1。
int *ptr2 = (int *)(*(aa + 1));
aa在单独使用时代表数组aa的首地址,加一表示首地址加一,即指向下一个元素地址,即第二个元素地址(即c[5]的地址,同样代表c[0]地址),再将其解引用后强制转换为int*型赋给ptr2。
printf("%d,%d", *(ptr1 - 1),*(ptr2 - 1));
ptr1-1就表示下一个数组首元素aa[2][5]的前一个元素的地址,即本数组最后一个元素aa[2][4]的地址,解引用后就是10;ptr2表示c[5]的地址,也是c[0]的地址,减一表示指向前一个数组最后一个元素的地址,即b[4]的地址,解引用后就是5。