数组名的意义:  
 
 
 1. sizeof( 
 数组名 
 ) 
 ,这里的数组名表示整个数组,计算的是整个数组的大小。  
 
 
 2. & 
 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。  
 
 
 3.  
 除此之外所有的数组名都表示首元素的地址。  
 
  下面我们来看几道经典的面试题 
 
  1 
 
int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}我们首先要知道此处的(&a + 1)是什么——&a是取出整个数组的地址,原本ptr是指向1的地址,再给它+1就表示跳过这个数组,即
(a+1)此处a表示首元素地址,+1表示第二个元素地址,所以*(a + 1)就是第二个元素,即2;
*(ptr-1)就是指向5的地址,再解引用就是5;所以这道题答案是 2,5;
2
int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int *ptr1 = (int *)(&a + 1);
    int *ptr2 = (int *)((int)a + 1);
    printf( "%x,%x", ptr1[-1], *ptr2);
    return 0;
}
     
  int * 
  ptr1  
  = 
   ( 
  int * 
  )( 
  & 
  a  
  +  
  1 
  );这里的 &a表示取出整个数组的地址,ptr1指向1的地址,+1跳过整个数组即指向4后面的地址,即 
 
 
  
  ptr1[-1]等价于*(ptr1-1)即是指向4再解引用就是4; 
 
 
 
      
   int * 
   ptr2  
   = 
    ( 
   int * 
   )(( 
   int 
   ) 
   a  
   +  
   1 
   );这里的a代表首元素地址,给其强制类型转化成int 再+1,即只跳过了int类型中的1个字节,整型在内存中是小端存储,即1,2,3,4原本在内存中应该是以0x00000001,0x00000002,0x00000003,0x00000004的形式存储,它们以小端存储即 
  
 
   
 
  
    ,所以对ptr解引用*ptr=02000000,以%x的形式打印出来省去前面的0,结果应该是2000000; 
  
 
  
    这道题答案是4,2000000; 
  
 
   
  
    3 
  
 
  #include <stdio.h>
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int *p;
    p = a[0];
    printf( "%d", p[0]);
 return 0;
}a是一个三行两列对的二维数组,注意此处对二维数组的初始化, int a[3][2] = { (0, 1), (2, 3), (4, 5) };,他们中间是用“ ,”隔开,不是“ {}”,所以,他只初始化了3个元素,即1,3,5,剩下的全是0,即这个二维数组应该是
p = a[0];a[0]表示的是&a[0][0], p就指向1的地址,p[0]表示*(p+0)就是*p就是1;
4
int main()
{
    int a[5][5];
    int(*p)[4];
    p = a;
    printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    return 0;
}a是int(*)[5]类型,p是int(*)[4]类型,如图所示

 
    & 
    p 
    [ 
    4 
    ][ 
    2 
    ]  
    - & 
    a 
    [ 
    4 
    ][ 
    2 
    ],就是他们中间有几个元素,如图,结果是-4,分别以%p和%d形式打印,就是 
   
 
   FFFFFFFC和-4
5
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));
    return 0;
} 
 
   
       
    int * 
    ptr1  
    = 
     ( 
    int * 
    )( 
    & 
    aa  
    +  
    1 
    );&aa表示整个二维数组的地址,指向1,+1表示跳过整个数组,指向第10后面的地址,*(ptr1-1)就是指向10的位置解引用就是10; 
   
 
    
     int * 
     ptr2  
     = 
      ( 
     int * 
     )( 
     * 
     ( 
     aa  
     +  
     1 
     ));aa表示二维数组首元素地址即是第一行的地址指向1,+1表示跳过第一行指向第二行首元素的地址6,*(ptr2-1)就是指向5的位置,解引用就是5. 
    
 
     
     所以这道题答案是10,5 
    
 
   


















