【C语言学习笔记】:一维数组指针,二维数组指针

数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element)。数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存。以int arr[] = { 99, 15, 100, 888, 252 };为例,该数组在内存中的分布如下图所示:

定义数组时,要给出数组名和数组长度,数组名可以认为是一个指针,它指向数组的第 0 个元素。在C语言中,我们将第 0 个元素的地址称为数组的首地址。以上面的数组为例,下图是 arr 的指向:

数组下标为啥从0开始?

  • 数组下标实际上是每个元素的地址相对于第一个元素地址的偏移量

【C语言学习笔记】:一维数组指针,二维数组指针_第1张图片 

【C语言学习笔记】:一维数组指针,二维数组指针_第2张图片

访问数组元素除了可以通过下标法之外,还可以通过指针法访问。

  • 下标法

    for(int i = 0;i < 6;i++)
    {
       printf("%d ",arr[i]);
       //printf("%d ",i[arr]);
    }
  • 指针法

    for(int i = 0;i < 6;i++)
    {
       printf("%d ",*(arr + i));
    }

    这就是为什么在某些地方大家会看到 i[arr] 这种访问数组元素的方法的原因,实际上下标法就是通过指针法来实现的,只不过编译器帮助我们做了这个操作,简化了操作难度。

指向数组的指针

我们也可以定义一个指向数组的指针,例如:

int arr[] = { 99, 15, 100, 888, 252 };
int *p = arr;

arr 本身可以看做是一个指针,可以直接赋值给指针变量 p。arr 是数组第 0 个元素的地址,所以int *p = arr;也可以写作int *p = &arr[0];。也就是说,arr、p、&arr[0] 这三种写法都是等价的,它们都指向数组第 0 个元素,或者说指向数组的开头。

如果一个指针指向了数组,我们就称它为数组指针(Array Pointer)

数组指针指向的是数组中的一个具体元素,而不是整个数组,所以数组指针的类型和数组元素的类型有关,上面的例子中,p 指向的数组元素是 int 类型,所以 p 的类型必须也是int *

反过来想,p 并不知道它指向的是一个数组,p 只知道它指向的是一个整数,究竟如何使用 p 取决于程序员的编码。

使用指针访问数组元素和使用函数名没有任何区别,值得注意的是我们不同通过指针获得数组的大小,但是通过数组名却可以。

printf("%d\n",sizeof(arr));//数组所占字节数 20 Byte
printf("%d\n",sizeof(p));//指针所占字节数 4 Byte

也就是说,根据数组指针不能逆推出整个数组元素的个数,以及数组从哪里开始、到哪里结束等信息。不像字符串,数组本身也没有特定的结束标志,如果不知道数组的长度,那么就无法遍历整个数组。

关于数组指针的谜题

假设 p 是指向数组 arr 中第 n 个元素的指针,那么 *p++、*++p、(*p)++ 分别是什么意思呢?

*p++ 等价于 *(p++),表示先取得第 n 个元素的值,再将 p 指向下一个元素。

*++p 等价于 *(++p),会先进行 ++p 运算,使得 p 的值增加,指向下一个元素,整体上相当于 *(p+1),所以会获得第 n+1 个数组元素的值。

(*p)++ 就非常简单了,会先取得第 n 个元素的值,再对该元素的值加 1。假设 p 指向第 0  个元素,并且第 0 个元素的值为 99,执行完该语句后,第 0  个元素的值就会变为 100。

数组名和数组指针的区别

虽然说数组名可以当做指针使用,但实际上数组名并不等价于指针。

  • 数组名代表的是整个数组,具有确定数量的元素

  • 指针是一个标量,不能确定指向的是否是一个数组

  • 数组可以在某些情况下会自动转换为指针,当数组名在表达式中使用时,编译器会把数组名转换为一个指针常量,是数组中的第一个元素的地址,类型就是数组元素的地址类型(通过sizeof也可以看出来)

二维数组指针

二维数组可以理解为每一个元素都是一个一维数组的数组,这样就可以很好的理解二维数组与指针了。

下面定义了一个2行3列的二维数组,并画出了对应的内存模型。

【C语言学习笔记】:一维数组指针,二维数组指针_第3张图片

 我们可以使用arr[0]获得第0个一维数组,然后再加上一个小标就可以获取到对应的元素,如arr[0][0]获取了第0行第0列的元素。

你可能感兴趣的:(C语言,C++,数据结构,算法,排序算法,c语言,c++)