C语言指针的简单介绍与入门基础(2)

前言:

通过上一节的学习,我们已经对指针有了一定的了解,这一节,我们将更加深入地去了解指针的各个知识点。大家也可以按照下面的目录各取所需,希望看的每个人都有所收获。

目录

前言:

1.数组名的理解

2.使用指针访问数组

3.一维数组传参的本质

4.二级指针

5.指针数组


1.数组名的理解

让我们通过一段代码引入这节内容:

我们发现,当我们使用&arr[0]取到了数组的第一个元素的地址,且&arr取到的地址也是数组第一个元素的地址。其实数组名本来就是地址,而且是数组首元素的地址。

也就是说:

数组名就是数组首元素(第一个元素)的地址。

可要是这样的话,可能会与我们平时打的一些代码相违背,就像下面的例子:

上述列子中,我们创建了一个元素个数为6且类型为int的数组,我们在sizeof函数(sizeof函数是用于计算变量所占内存空间的大小,单位是字节)中输入数组名,如果按上文写的数组名ar是数组首元素的地址的话,那sizeof计算的便是首元素的地址,打印出的结果也应该是¥/8才对啊,难道我们先前学的知识出错了?其实不然:

数组名就是数组首元素(第一个元素)的地址是对的,但是有两个例外

  1. sizeof(数组名),sizeof中单独放数组名,这里的数组名表示整个数组,计算的是整个数组大小,单位是字节。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)

除此之外,任何地方使用数组名,数组名都是表示首元素的地址。

因此,我们上面代码中的打印是24是没错的,因为sizeof(arr)求的是整个数组的大小,数组中有6个元素,每个元素又是int型即4个字节,所以4*6=24,一切就合理起来了。

我们再接着下一组代码:

有敏感的同学可能已经发现了,arr + 1,跳过的是一个元素的大小;而&arr + 1跳过的是整个数组的大小。我们不禁会想,那arr和&arr有什么区别呢?

让我们看最后一组代码:

至此,我们可以得出结论:

&arr和arr的区别:

&arr[0]和&arr[0]+1相差4个字节,arr和arr+1相差4个字节,是因为&arr[0]和arr都是首元素地址,+1就是跳过一个元素

但是&arr和&arr+1相差40个字节,这就是因为&arr是数组的地址,+1操作是跳过整个数组。

2.使用指针访问数组

继续上代码:

在看到前两行代码大伙们可能还觉得合理,但后两行代码显然就有点反直觉了。但事实上就是:

p[i]本质上是等价于*(p + i )

i[arr] == *(i + arr) == arr[] == *(arr + i) == p[i]

数组元素的访问在编译期处理的时候,也是转换成成首元素的地址(arr)+偏移量(i)求出元素的地址,然后解引用(*)来访问的,即*(arr + i )

  1. 数组就是数组,是一块连续的空间(数组的大小和数组元素个数和元素类型都有关系)
  2. 指针变量就是指针变量,是一个变量(4/8个字节)
  3. 数组名是地址,是首元素的地址
  4. 可以使用指针来访问数组

3.一维数组传参的本质

在平日里写代码的时候,我们有时需要计算一些位置数组的元素个数,有些同学棵能就会想着自己写一个求数组元素个数的函数,就像下面的函数test,但我们发现整个函数好像失灵了,这是为甚为什么呢?要解开这个疑问,我们就必须学习数组传参的本质了,我们通过上面数组名的理解的学习得知,数组名是首元素的地址,而我们在数组传参的时候传递的也是数组名,也就是说:本质上数组传参本质上传递的是数组首元素的地址。而这也是为什么上面的函数test的传参是用int* p接收。

所以我们可以得出结论:

  1. 数组传参的本质是传递了数组首元素的地址,所以形参访问数组和实参的数组是同个数组。
  2. 形参的数组是不会单独再创建数组空间的,所以形参的数组是可以忽略掉数组大小的

总结:一维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。

4.二级指针

指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?我们还是通过指针来认识/

上图中ppa存放的地址是pa的地址,我们通过画图来滤清思路

就是二级指针

二级指针的运算

*ppa通过对ppa中地址进行解引用,这样找到的是pa。*ppa其实访问的就是pa

**ppa先通过*ppa找到pa,然后对pa进行解引用操作:*pa,那就找到的是a。

5.指针数组

指针数组是存放指针的数组。

指针数组的每个元素都是用来存放地址(指针)的。

指针数组的每个元素是地址,又可以指向一块区域。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值