[TOC]

零基础学C语言,深入理解指针(3)

1 数组名的理解

我们在之前的文章里面提到过,数组名是数组首元素的地址,那么这里我们来证明一下,如图:

在这里插入图片描述
可以看到 & arr[0],和 arr 打印出来的结果是一样的。

但是在某些特殊的情况下,数组名的含义是不一样的。
第一个是 sizeof (数组名),这里的数组名代表整个数组;
第二个是 &(数组名),这里的数组名代表的是整个数组的地址;

我们来证明一下,首先看第一种情况,如图:

在这里插入图片描述
可以看到打印的结果是40,是整个数组的大小。

来看第二种情况,如图:

在这里插入图片描述
我们看到arr 和&arr 在数值上是一样的,而对 arr + 1,跳过了四个字节,对 &arr + 1 ,跳过了四十个字节(十六进制就是28)。

2 使用指针访问数组

我们已经知道了数组名的含义,那么我们就可以很轻松的用指针来访问数组了。
如果我们创建一个指针变量 p 并把 arr 放入 p 里,这时,p 和 arr 就是等价的。
arr[1]也就可以写成 p[1]。
如下图:
在这里插入图片描述
这里再来解释一下下表访问操作符 “[ ]” ,下表访问操作符本质上是解引用操作。比如 arr[i],本质上就是 *(arr + i),以此来访问第 i 个元素的地址。

有下表访问操作符的本质可知,我们访问第 i 个元素的时候也可以写成 i [arr],这样一转化就是 *( i + arr ),和 arr [i] 是一样的。

3 一维数组传参的本质

我们知道数组传参可以写成数组的形式,但我们传过去的真的是一个数组吗?
答案是不是的。
如下图:

在这里插入图片描述

在这里插入图片描述
我们发现并没有输出数组的大小。这是因为数组传参本质上传过去的 arr 数组首元素的地址。

所以,数组传参时的形参的类型也就可以写成指针的样式,这和写成数组是一样的。

由此我们也可以知道,实参数组和形参数组是一个数组,因为它们数组名是一样的,都指向实参数组的首元素。

4 二级指针

我们知道创建变量就是向内存申请空间,就有对应的地址,所以指针变量也有它自己的地址,二级指针就是存饭指针变量的地址的指针。如图:

在这里插入图片描述
那么二级指针变量要怎么定义呢?如图:

在这里插入图片描述
类比一级指针变量的定义,int * 是二级指针指向的元素的类型,第二个 * 是指针的标志。

同样的,如果对二级指针解引用,* pp 拿到的是 p 的地址,**pp,拿到的是 a 的值。

三级指针 四级等等,都是类似的。

5 指针数组

顾名思义就是元素是指针的数组,怎么定义呢?
如图:
在这里插入图片描述
其实和普通数组的定义是一模一样的。这里注意,0 这个地址是存在的,只是不允许访问。

6 数组指针模拟二维数组

指针数组有什么应用呢?用它可以来模拟二维数组。如图:

在这里插入图片描述
指针数组 arrp 的,每一个元素都指向一个数组的首元素地址,所以我们对 arrp 数组解引用,就可以访问,其中一个数组。(刚才我们讲过 “[ ]”,本质上就是解引用)。

这样我们就用指针数组模拟了二维数组。但它不是完全的二维数组,因为它不是连续的,arr1 , arr2 , arr3三个数组的地址是不连续的。

在这里插入图片描述

本篇完