指针和多维数组

       弄清楚多维数组的关键在于搞懂层层解引用和取址后的数据类型;
一、一维数组
1、&a和a的区别
     这两个的值都是一样的,但是它们两个的含义却是不同的。int* p=a;数组名字代表指向数组中一个int型元素的指针,它记录的是数组首元素的地址,可以根据它通过下标访问数组中的各个元素。而int (*p)[]=&a,当对一个多维数组取址时,它不再是一个 int *类型,而是一个指向一维数组的数组指针。因为数组指针指向这个数组,所以它存放的也是这个一维数组的首元素的地址;

#include
int main()
{
 int a[]={1,2,3,4};
 int (*p)[4]=&a;
 printf("%d %d %d %d %d %d %d",a,&a,a+1,&a+1,p,**p,*(*p+1));
}

      指针和多维数组

      可以发现经过编程测试,a+i和&a+i的值确实也是不一样的。对于a+i,是int*数据类型解一次引用求sizeof(int)*i,也就是a+4*i;而&a数组指针它一次加的话就是加一个数组长度,也就是sizeof(int)*4=16。

二、多维数组
      在上个例子中,大家可以发现对一个数组指针解两次引用访问到数组里的元素,这里用到了一个重要的规律:(a+i)=p[i];不管是在几维的数组中,它都是遵循这个规律的;用数组名a访问这个数组的时候,我们会发现*(a+i)=a[i];所以当用数组指针访问一维数组的时候其实它就是一个特殊的二维数组了,我们先看二维数组和一维数组用数组名访问的对比图。
指针和多维数组
       通过这张图想必大家也清楚了,所以在上个例子中的**p可以解释为*(*(p+0)+0)=p[0][0],*(*p+1)=
*(*(p+0)+1)=p[0][1];还有一些利用这个规律的一些题目如下:
        int array[4][5][3],把指针转化为下标表达式;
        1、*array                                  =*(array+0)=array[0];
        2、*(array+2)                           =array[2];
        3、*(*(array+1)+4)                  =array[1][4];
        4、*(array+1)+4                      =&array[1][4]
       (注:因为第4个只解了一次引用,而两个下标相当于解了两次引用所以需要取址一次补回去)