一维数组地址的分析: 
int a[3]={1,3,4}; 
    for (int i=0; i<3; i++) { 
        printf("a[%d]=%d  该元素的地址%p\n",i,a[i],&a[i]); 
    } 
    /* 
     a[0]=1  该元素的地址0x7fff5fbff80c 
     a[1]=3  该元素的地址0x7fff5fbff810 
     a[2]=4  该元素的地址0x7fff5fbff814 
      
     */ 
    printf("数组名a的代表的地址是%p\n",a);//数组名a的代表的地址是0x7fff5fbff80c 
    printf("a+1 = %p\n",a+1);  //a+1 = 0x7fff5fbff810 
    printf("a+2 = %p\n",a+2);   //a+2 = 0x7fff5fbff814 
   printf("&a+1 = %p\n",&a+1); //&a+1 = 0x7fff5fbff818 
//----------------------------一维数组的存储方式 
存储方式: 
1)计算机会给数组分配一块连续的存储空间 
 
2)数组名代表数组的首地址 
也就是数组第一个元素的地址即a[0]的地址 
从首地址位置,依次存入数组的第1个、第2个....、第n个元素 
 
3)每个元素占用相同的字节数(取决于数组类型) 
 
4)并且数组中元素之间的地址是连续。 
 
 
一维数组的地址 
在内存中,内存从大到小进行寻址,为数组分配了存储空间后,数组的元素自然的从上往下排列 存储,整个数组的地址为首元素的地址。 
 
 
2)数组名存放的是数组的首地址 
数组的首地址:数组的第一个元素首地址(第一个元素的第一个字节地址) 
 
 
 
二维数组的地址的分析: 
 
必须牢记的 
        &a                                二维数组的地址 
        a                                二维数组所指向的第一行元素的地址(第一行地址) 
        &a[0]                        第一行元素的地址 
        a[0]                                指向第一行第一个元素的地址 
        &a[0][0]                第一行第一个元素的地址 
 
尽量理解的: 
&a+1                        以数组长度+1 越界 
a+1                                以第一行元素地址的长度+1 也就是第二行元素的首地址 
&a[0]+1                以第一行元素地址的长度+1 也就是第二行元素的首地址 
a[0]+1                以第一行第一个元素的地址的长度+1 也就是第一行第二个元素的首地址 
&a[0][0]+1         以第一行第一个元素长度+1 也就是第一行 第二个元素的首地址 
 
//--------------------二维数组存储 
存储方式: 
1)计算机会给二维数组分配一块连续的存储空间 
 
2)数组名代表数组的首地址,从首地址位置,依次存入第1行、第2行、..... 
 
3)每一行存储方式,从行首地址还是,依次存储行的第1个元素、第2个元素、第3个元素...... 
 
4)每个元素占用相同的字节数(取决于数组类型) 
 
5)并且数组中元素之间的地址是连续。 
 
 
arr == &arr[0] == arr[0] == &arr[0][0] 
 
 
arr (数组名   指向第一行元素的地址) 
 
&arr[0](第一行元素的地址) 
 
arr[0](指向第一行第一个元素的地址) 
 
&arr[0][0](第一个元素的地址) 
 
int arr[3][4] = {{第一行3个元素(第一行一维数组)},  ---->   arr[0] 
                {第二行4个元素(第二行一维数组)},   ---->   arr[1] 
                {第三行4个元素(第三行一维数组)}};  ---->   arr[2] 
 
 |