二维数组与指针的一些问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<stdio.h>

int main()
{
int A[2][3] = {
{1,2,3},
{4,5,6}
};
printf("=========================\n");
printf("A[0][1]:%d\n",A[0][1]);
printf("*(*(A+0)+1):%d\n",*(*(A+0)+1));
printf("=========================\n");
printf("&A[1][0]:%d\n",&A[1][0]);
printf("*(A+1):%d\n",*(A+1));
printf("=========================\n");
printf("**(A+1):%d\n",**(A+1));
printf("**((int (*)[1])A+1):%d\n",**((int (*)[1])A+1));
return 0;
}

结果:

1
2
3
4
5
6
7
8
9
=========================
A[0][1]:2
*(*(A+0)+1):2
=========================
&A[1][0]:6487612
*(A+1):6487612
=========================
**(A+1):4
**((int (*)[1])A+1):2

分析:

  1. A[0][1]:常规的二维数组索引
  2. *(*(A+0)+1)):利用双重指针来对二维数组进行索引,这里的A应该是一个**int (*)[3]数组指针类型的变量,*(A+0)就是一个int ***类型的变量,所以这里和A[0][1]的结果是一样的。
  3. &A[1][0]:第二行第一列数据的地址
  4. *(A+1):同第二点,这里A是一个int (*)[3]数组指针类型的变量,故A+1指向第二,且A+1仍是一个**int (*)[3]**数组指针类型的变量,取地址后就是第二行行首的地址
  5. **(A+1):同理,A是一个int (*)[3]数组指针类型的变量,A+1指向第二,两次取地址后就是元素A[1][0]
  6. **((int (*)[1])A+1)):这里利用强制类型转化将A的类型由int ()[3]数组指针类型转化为int ()[1],故A+1指向第二,且A+1仍是一个**int (*)[1]**数组指针类型的变量,两次取地址后就是元素A[0][1]