记住很重要的一点:数组名=&数组名[0],比如,对于二维数组a[3][4] ,a等同于&a[0],a[0]等同于&a[0][0]
int main()
{ int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};int *p1;p1=a[0]; //表示数组a第一个元素的地址,相当于p1=&a[0][0]//上面可以这么理解:对于一维数组a[],数组名a是第一个元素a[0]的地址,那么对于二维数组a[][],一维数组名a[0]是它的第一个元素a[0][0]的地址p1=*a; //和上面的p1=a[0]是等同的,因为二维数组名a表示第一个一维数组a[0]的地址,则*a是表示第一个一维数组中的第一个元素即a[0][0]的地址cout<<*p1<<endl; //输出a[0][0]cout<<*(p1+1)<<endl; //输出a[0][1]int (*p2)[4];p2=&a[0]; //对整个一维数组a[0]求地址,此时p2是数组指针,指向4个int的一维数组//此时p2是一维数组a[0]的首地址,虽然p2在数值上与&a[0][0]相等,但与&a[0][0]的意义完全不一样p2=a; //和上面的p2=&a[0]是等同的,因为二维数组名a表示第一个一维数组a[0]的地址cout<<*p2<<endl; //虽然加了取值符号,但此时*p2仍然是地址,表示所指向的a[0]的第一个元素的地址,即&a[0][0]cout<<**p2<<endl; //输出a[0][0]cout<<*p2+1<<endl; //表示所指向的a[0]的第二个元素的地址,即&a[0][1]cout<<*(*p2+1)<<endl; //输出a[0][1]cout<<p2+1<<endl; //因为p2是指向4个int的数组指针,所以指针+1会跳过4个int的地址,移动到下一个一维数组a[1]的首地址//此时p2+1是一维数组a[1]的首地址,虽然p2+1在数值上与&a[1][0]相等,但与&a[1][0]的意义完全不一样cout<<*(p2+1)<<endl; //表示所指向的a[1]的第一个元素的地址,即&a[1][0]cout<<**(p2+1)<<endl; //输出a[1][0],即输出5cout<<*(p2+1)+1<<endl; //表示所指向的a[1]的第一个元素的地址,即&a[1][1]cout<<*(*(p2+1)+1)<<endl; //输出a[1][1],即输出6int (*p3)[3][4];p3=&a; //对整个二维数组a求地址,此时p3是数组指针,指向int [3][4]型数组//虽然下面三句输出的内容一样,但它们表示的意义完全不一样cout<<p3<<endl; //此时p3是二维数组a的首地址cout<<*p3<<endl; //此时*p3表示a第一个一维数组的地址,即&a[0]cout<<**p3<<endl; //此时**p3表示a第一个一维数组的第一个元素的地址,即&a[0][0]cout<<***p3<<endl; //输出a[0][0]cout<<p3+1<<endl; //因为p3是指向int [3][4]的数组指针,所以指针+1会跳过12个int的地址,移动到下一个二维数组的首地址//因此,p3+1相当于二维数组a最后一个元素的下一个地址,即&a[2][3]+1return 0;
}