首页 > 其他分享 >计算机初级选手的成长历程——指针(4)

计算机初级选手的成长历程——指针(4)

时间:2023-12-11 20:02:15浏览次数:32  
标签:二级 下标 初级 元素 选手 数组名 数组 指针

进阶指针

计算机初级选手的成长历程——指针(4)_C语言


导言

大家好,很高兴有和大家见面啦!

经过前面的学习,大家现在对指针的内容应该有了一个初步的印象。为了帮助大家将指针的知识点好好的消化吸收,今天开始我们将对指针的内容进行深入的探讨。下面我们就开始今天的内容吧!

九、二级指针与指针数组

通过前面的介绍,我们知道,对于一维数组来说,一维数组的数组名在除了计算数组所占空间大小以及进行取地址操作这两种情况外,数组名就等价于数组首元素的指针。 大家现在思考一下,如果我们将一维数组的元素替换成指针类型,那与这个数组名等价的数组首元素的指针又应该是什么样的呢?

为了搞清楚这个问题,下面我们来分析一下;

指针存放的是数组首元素的地址,此时的数组首元素的类型不是指针类型;

当数组首元素的类型为指针类型时,此时存放首元素地址的指针存放的应该是一个指针的地址;

在前面的介绍中我们有提到过,存放指针地址的指针我们将其称为二级指针。也就是说指针数组首元素的指针是一个二级指针,根据指针与数组的关系我们可以得到:

  • 在除了计算指针数组所占内存空间大小以及进行取地址操作这两种情况外,指针数组的数组名等价于一个二级指针

有了这个结论后,下面我们来探讨一下对于二级指针与指针数组我们应该如何使用;

9.1 二级指针+-整数

对于一级指针来说,指针+-整数得到的值是指针+-对应数据类型所占空间大小*整数。那二级指针进行加减整数时又会是什么情况呢?下面我们就来测试一下:

计算机初级选手的成长历程——指针(4)_二维数组_02

从测试结果中我们可以看到,对于不同类型的二级指针来说,在进行加1或者减1时,变化的大小都是4个字节。既然这样,那我们就用char**的指针ppa为例子来继续测试加减整数:

计算机初级选手的成长历程——指针(4)_二级指针_03

可以看到二级指针ppa在进行加减整数时,指针变化的值为4的整数倍。

通过这两次的测试结果,我们就能得到以下结论:

  • 不同类型的二级指针进行加1和减1后,指针变化的值都为4;
  • 同一类型的二级指针进行加减整数后,指针变化的值为4的整数倍;

此时有朋友可能就会好奇了,为什么是4这个值呢?我们先来回顾一下指针加减整数的规则:

计算机初级选手的成长历程——指针(4)_指针数组_04

下面我们来看一下一级指针的创建格式:

//一级指针的创建格式
type* p = &name;
//type——指针对应的数据类型
//*——表示此时的变量为指针类型
//p——指针变量名
//name——被指针指向的变量

从这个格式中,我们可以看到,在type*中,type表示的就是指针对应的数据类型;

前面我们在介绍二级指针时,我们是将其中一颗*给了指针变量也就是type* *p = &p;的格式。下面我来给大家介绍一个新的思路,我们将二级指针看做一个一级指针,然后我们就能得到二级指针的格式:

//二级指针的创建格式
(type*)* pp = &p;
//type*——指针对应的数据类型
//*——表示此时的变量为指针类型
//pp——指针变量名
//p——被指针指向的变量

可以看到,在这种格式下,我们就可以很清楚的看到,二级指针对应的数据类型为指针类型。在前面我们也介绍过,对于不同的指针类型在32位操作系统下所占内存空间大小都是4个字节,在64位操作系统下所占内存空间大小都是8个字节。而前面我们是在32为操作系统下进行测试的,这就是为什么对于二级指针进行+-整数时变化的值为4的整数倍。

9.2 二级指针-二级指针

对于一级指针来说,在数组中,指针-指针的值为指针之间的元素个数。二级指针也满足这个运算规则,如下所示:

计算机初级选手的成长历程——指针(4)_二维数组_05

我们如果将二级指针看做一级指针的话,那这里就相当于是一个指针对应的数据类型为整型指针类型的两个一级指针在进行相减,所得的结果也是两个一级指针之间的元素个数。

9.3 二级指针的关系运算

同理,对于指针指向的目标为指针类型的一级指针,它也是可以进行关系运算的。如下所示:

计算机初级选手的成长历程——指针(4)_二维数组_06

现在大家应该都能理解二级指针和指针数组之间的关系了。与其说是二级指针与指针数组之间的关系,倒不如说是一级指针与移位数组之间的关系,只不过此时的指针所指向的元素的数据类型为指针类型,数组元素的数据类型也为指针类型;

计算机初级选手的成长历程——指针(4)_指针数组_07

可以看到,此时对数组名进行解引用操作也是可以像指针一样找到数组各个元素的,不管是整型数组也好还是整型指针数组也好,都是能够正常访问的;

  1. 使用指针[下标]来访问数组元素;

计算机初级选手的成长历程——指针(4)_指针数组_08

可以看到,此时对指针使用下标引用操作符也是能够正常访问数组的各个元素的,不管是整型一级指针还是整型二级指针,都是可以正常访问的;

  1. 进行数组传参时,通过指针接收;

计算机初级选手的成长历程——指针(4)_二级指针_09

通过指针来接收数组的传参,是没有任何问题的,这里我们可以看到指针接收完后,还能通过下标引用操作符来找到数组的各个元素;

  1. 进行指针传参时,通过数组接收

计算机初级选手的成长历程——指针(4)_C语言_10

通过数组来接收指针的传参也是没有任何问题的,这里我们看到数组在接收完后,还能通过解引用操作符来访问指针指向的各个对象;

经过上面的例子,我相信大家对指针与数组名之间的相互转换已经非常熟悉了,下面我给大家介绍一些关于指针与数组之间的有趣的变形;

现在咱们已经将二级指针与指针数组之间的关系介绍完了。不知道有没有朋友会有疑惑,我们这里一直在强调除了用sizeof计算数组所占空间大小和通过取地址操作符取出数组的地址这两种情况外,其他的时候指针与数组名是等价的,那它们之间可不可以进行相互转换呢?下面我们就来探讨一下;

9.4 指针与数组名的相互转换

为了探讨指针与数组名能否进行相互转换,下面我们先进行第一个测试:

  1. 使用*(数组名+下标)来访问数组元素;

计算机初级选手的成长历程——指针(4)_C语言_11

可以看到,此时对数组名进行解引用操作也是可以像指针一样找到数组各个元素的,不管是整型数组也好还是整型指针数组也好,都是能够正常访问的;

  1. 使用指针[下标]来访问数组元素;

计算机初级选手的成长历程——指针(4)_C语言_12

可以看到,此时对指针使用下标引用操作符也是能够正常访问数组的各个元素的,不管是整型一级指针还是整型二级指针,都是可以正常访问的;

  1. 进行数组传参时,通过指针接收;

计算机初级选手的成长历程——指针(4)_二级指针_13

通过指针来接收数组的传参,是没有任何问题的,这里我们可以看到指针接收完后,还能通过下标引用操作符来找到数组的各个元素;

  1. 进行指针传参时,通过数组接收

计算机初级选手的成长历程——指针(4)_二维数组_14

通过数组来接收指针的传参也是没有任何问题的,这里我们看到数组在接收完后,还能通过解引用操作符来访问指针指向的各个对象;

经过上面的例子,我相信大家对指针与数组名之间的相互转换已经非常熟悉了,下面我给大家介绍一些关于指针与数组之间的有趣的变形;

9.5 有趣的变形

  1. 下标[数组名]

计算机初级选手的成长历程——指针(4)_指针数组_15

可以看到对于下标引用操作符,下标与数组名的位置是可以进行互换的;

  1. 下标[指针]

计算机初级选手的成长历程——指针(4)_二级指针_16

既然数组名就是指针,那么对于指针来说,在使用下标引用操作符时也是同样可以将指针与下标的位置进行互换的;

  1. &指针[下标]

计算机初级选手的成长历程——指针(4)_二级指针_17

当我们对指针使用下标引用操作符时,就等价于对指针进行解引用,再进行解引用后再对其取地址,还能得到指针;

  1. *数组名

计算机初级选手的成长历程——指针(4)_二维数组_18

我们可以通过对数组名进行解引用来访问数组的各个元素,但是,数组名并不能像指针一样进行自增操作:

计算机初级选手的成长历程——指针(4)_指针数组_19

这里是因为对于数组名来说,数组名是整个数组在内存中的起始位置,此时如果对数组名进行自增,就相当与是把整个数组的起始位置进行移动,所以此时的数组名表示的也是整个数组,并不是数组的首元素,这个一定要牢记;

9.6 总结

介绍到这里,关于指针与数组的关系我们就全部介绍完了,下面我们来对这些内容做个总结:

  1. 三种情况数组名表示的是整个数组
  • 通过sizeof计算数组所占空间大小
  • 使用取地址操作符&对数组名进行取地址操作
  • 对数组名进行自增自减操作等赋值操作
  1. 在其它情况下,数组的本质就是指针:计算机初级选手的成长历程——指针(4)_二维数组_20
  2. 计算机初级选手的成长历程——指针(4)_C语言_21
  3. 计算机初级选手的成长历程——指针(4)_指针数组_22
  4. 我们可以修改指针指向的内容,但不能修改数组名指向的内容;

即:我们可以对指针进行自增/自减等赋值操作,但不能对数组名进行自增自减等赋值操作

十、指针数组模拟二维数组

在搞清楚了指针与数组的关系后,我们再来探讨一下指针数组。

既然数组的本质就是指针,而对指针数组来说,数组元素为指针,也就是说我可以认为指针数组的元素可以是数组

在前面介绍二维数组时,我们有介绍过一种理解——二维数组可以看做是一维数组的集合

既然指针数组的元素可以是数组,而二维数组可以看做是一维数组的集合,那是不是说指针数组与二维数组等价呢?

很遗憾的告诉各位,指针数组与二维数组并不等价,同理二级指针与二维数组也是不等价的。之所以不等价,是因为对于指针数组来说,数组元素存放的地址可以是不连续的地址,但是对于二维数组来说,数组元素的地址是连续存放的,如下所示:

计算机初级选手的成长历程——指针(4)_二级指针_23

从结果中我们可以看到:

  • 对于二维数组的元素地址间的差值刚好是8,也就是说,二维数组可以看做是三个地址连续存放的一维数组的集合
  • 而对于指针数组来说,我们可以看到指针数组的元素的地址之间并不相邻

因此指针数组与二维数组并不等价,又因为指针数组与二级指针等价的,所以二级指针与二维数组并不等价

既然我们从地址连续存放的一维数组的集合的角度来看待二维数组的话,那我们就可以通过指针数组来模拟实现二维数组。如下所示:

计算机初级选手的成长历程——指针(4)_C语言_24

在前面对指针与数组的探讨中我们得到的结论是在对数组元素进行访问时解引用操作符*<==>下标引用操作符[]。因此我们可以通过第二个下标引用操作符来访问指针数组中各元素的数组元素。

结语

对于指针数组的内容我们先介绍到这里,今天的这些内容可谓是干货中的干货,大家一定要好好消化一下哦!!!

在下一篇内容中,我们会对指针的内容继续深入,大家记得关注哦!!!

最后,感谢各位的翻阅,咱们下一篇再见!!!

标签:二级,下标,初级,元素,选手,数组名,数组,指针
From: https://blog.51cto.com/u_16231477/8777240

相关文章

  • 【C系列5.4】指针专题之分割字符串(strtok与gets的应用)(hznuoj)
    Description Alex的好朋友都去生猴子了,所以她只好百无聊赖地继续玩字符串游戏。输入一个长度不超过10000的字符串,字符串中只含字母和空格,空格用于分隔单词,请将字符串中用空格分隔的单词输出来。 Input 输入含多组测试数据,每组占一行,是一个长度不超过10000的字符串,只含字......
  • 初学指针,刷题(hznu【C系列5.6】指针专题之翻译)
    题目如下Description (本人学艺不精,写了很久才写出了一个臃肿的代码,malloc也不咋会用,只能向ai请教了T_T)Alex在朋友们都去生猴子了的日子里,日复一日、年复一年地敲代码,终于,在经年累月的摧残下,她的手指变得不那么利索了,比如“how are you”她会哆嗦着打成“hhoow areee youu......
  • c语言指针
    【C语言】中的指针说明:只是学习中的一些感悟,如有错误,欢迎指正一、指向指针的指针指向指针的指针是C语言中的一种数据类型,通常简称为"指针的指针",使用两个星号('**')表示。指向指针的指针是一个变量,其值是另一个指针的地址。|1.用法:1>如下定义了一个指向指针的指针char**......
  • 极客时间邓明初级go工程师训练营
    获取完整版--》请留言1.变量变量的声明有四种方式:声明一个变量,默认的初始化值为0:varaint声明一个变量,初始值为100:varaint=100初始化时候省略数据类型,通过值自动推导变量的数据类型:vara=100省略掉var关键字,直接自动匹配,但要使用:=a:=100一个注意的点:第四种声明变量的方......
  • 计算机初级选手的成长历程——指针(2)
    初阶指针导言大家好,很高兴又和大家见面了!!!在上一个篇章中,我们介绍了指针、指针变量以及野指针的相关知识点。在今天的篇章中,我们将探讨一下指针是如何进行运算的。五、指针运算对于指针的运算,共有三种运算方式:指针+-整数指针-指针指针的关系运算5.1指针+-整数对于不同类型的指针加/......
  • C++(智能指针)
    在C++中,智能指针是一种用于管理动态分配内存的智能化工具。它们提供了对动态分配资源的自动管理,以减少内存泄漏和资源泄漏的风险。C++标准库提供了两种主要的智能指针类型:std::shared_ptr和std::unique_ptr。以下是这两种智能指针的基本解释:1.std::shared_ptr:std::shared_......
  • 两种方法求字符串个数(函数递归和指针)
    前言:我先想讲一个关于指针的问题,由于我一开始学习指针的时候很困惑,现在分享给大家。假设我们定义一个指针p,我们首先要区分p、&p与*p的区别(对于初学者应该和我一开始一样迷茫)p:p是一个指针变量的名字,表示此指针变量指向的内存地址,如果用%p输出的话它将是一个16进制位的数。*p:*是解引......
  • 2023最新初级难度前端面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-初级难度前端面试题合集问:请详细描述HTML、CSS、JavaScript的基本结构?HTML、CSS、JavaScript是web前端开发中最常用的三种技术,它们分别负责页面结构、表现形式和交互行为。HTML(HyperTextMarkupLanguage)是一种用于构建网页的标......
  • 2023最新初级难度react面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-初级难度react面试题合集问:请详述React.js是什么?React.js是一个由Facebook开发的开源JavaScript库,用于构建用户界面(UserInterface,UI)。它是目前Web开发领域最流行和广泛使用的库之一。React.js主要提供了一个虚拟DOM(Virtua......
  • 2023最新初级难度PHP面试题,包含答案。刷题必备!记录一下。
    好记性不如烂笔头内容来自面试宝典-初级难度PHP面试题合集问:请解释什么是PHP?PHP是一种开源的脚本语言,用于开发动态网站和Web应用程序。它是一种嵌入HTML中的语言,可以用来执行简单的任务,例如显示特定的图形或记录访客人数等。它可以轻松地插入到HTML页面中,并且支......