数组与指针的天生姻缘

一、两种访问数组元素的方式

数组元素只能单独访问不能整体访问,访问数组元素有两种方式:


  1. 数组访问
    a[下标]
  2. 指针访问
    *(指针+偏移量);如果指针是数组首元素的地址(a或者&a[0])那么偏移量就是下标,指针也可以不是首元素地址,此时偏移量要考虑叠加。

数组下标方式和指针方式均可以访问数组元素两者的实质其实是一样的,在编译器内部都是用指针方式访问的,数组下标只是c语言封装好的工具(语法糖)而已。

#include 
int main(void)
{
        int a[5]={1,2,3,4,5};
        printf("a[3]=%d.\n",a[3]);    //数组方式访问数组元素
        printf("*(a+3)=%d.\n",*(a+3));    //指针方式访问数组元素
        int b=*(a+3);    //相当于
//此时a做右值,代表数组首元素的地址,可以当作指针来用。
        int *p;
        p=a;    //a做右值时表示数组首元素地址,等同于&a[0]
        printf("*(p+3)=%d.\n",*(p+3));      
}

二、从内存角度理解指针访问数组的实质

  • 数组的特点
    数组中各个元素的地址是依次相连 ;而且数组各个元素的类型是一样的(也是数组的一个限制)类型相同就决定了每个元素所占内存字节数是相同的。数组中的元素其实就是地址相连接、占地大小相同的一串内存空间。只要知道了数组中一个元素的地址就可以很容易的推算出数组其他位置的地址。
  • 指针和数组类型匹配问题
    用指针访问数组时类型一定要是匹配的。
#include 
int main(void)
{
        int a[5]={1,2,3,4,5};
        int *p;
        p=a;    //类型匹配
        p=&a;    //类型不匹配,因为p是int *,&a是整个数组的指针,是一个数组指针类型,不是int 指针类型,所以不匹配。
}

&a、a、&a[0]从数值来看是一模一样的但是从意义来看是不一样的。从意义来看,a与&a[0]是数组首元素地址,而&a是整个数组的首地址;从类型来看,a和&a[0]是元素的指针,也就是int 类型,而&a是数组指针,是int()[5]类型。当指针参与运算时,指针变量本身存储的数值是表示地址的,这个运算也是地址的运算,指针变量加1并不是真的加1,而是加上1xsizeof(指针类型)。主要原因是希望指针加1后刚好指向下一个元素,而不希望错位。
练习

#include 
int main(void)
{
        int a[5]={1,2,3,4,5};
        int *p;
        p=a;
        printf("*(p+1)=%d.\n",*(p+1));
        char *p2;
        p2=(char *)p;
        printf("*(p2+1)=%d.\n",*(p2+1));
}

你可能感兴趣的:(数组与指针的天生姻缘)