C语言中结构体指针如何用 -> 取子数据及链表应用示例
在C语言当中指针箭头“-”看起来是简单的然而好多人在学到链表之际会被它难住。此符号从本质上来说那是从一个结构体指针里把内部数据取出的快捷途径要理解它呀得先弄明白变量、指针、结构体这三层概念方可不然的话看链表代码就好似看天书一般。变量不是房间里会变的东西有不少人认为变量乃是值会发生变化的数据只是这样的理解太过浅显变量的实质是一块固定的内存空间它具备不变的地址空间当中存放的内容能够被改变就如同某间教室这个房间一般每天前来上课的学生并不相同然而教室的位置以及大小却是未变的变量的地址就等同于这间房的门牌号变量的值恰似房间里的学生平常我们运用变量名直接对学生进行操作指针却能够让我们依据门牌号去找到房间。声明一个整型变量int a系统会分配一块内存这块内存是4字节给它贴上名叫“a”的标签。当你写下a 5是将5放进这块空间。但要是写int p ap这个指针变量所存的是a那块空间的地址编号例如0x7fff1234。此时p就是门牌号的记录本顺着门牌号找到房间后看到的学生是a而不是p。结构体把多个房间打包成别墅将不同类型数据组合起来的结构体好似把几个功能各异的房间连接成一栋别墅例如定义一个含有学号、姓名、成绩的学生结构体此三个数据于内存之中是连续存放的在用普通变量struct Student stu时能够直接借由stu.id去访问学号然而当使用指针struct Student p指向stu时便无法再靠着p.id去访问原因在于p是一个地址并非结构体自身。到了这个时候“-”便发挥其作用了。p-id等同于(p).id其含义是首先依据p当中的地址去寻找到那座别墅接着再获取别墅里的id房间。当编译器对这个符号进行处理之际会自动去计算结构体成员的偏移量就像id之处在结构体起始位置偏移0字节name偏移4字节成绩偏移20字节。p-id所做的便是取p所指向的地址加上0字节之后的内容。链表里的箭头是串起别墅的锁链链表的节点结构体当中除去存放数据之外有一个同类型的指针成员是必须存在的该指针成员用于指向下一个节点典型的定义呈现为struct Node{ int data; struct Node next; };以上情况里next被当作一个指针变量其所存储的内容是下一个节点的地址。要是你存在一个指针p它指向当前节点那么p-next所做的便是取出这个节点里所存储的下一个节点的地址而p p-next呢就是将下一个节点的地址赋予p从而让p指向接下来的那个节点。对链表进行遍历的过程便是持续不断地重复这样的操作。起始的时候p指向头节点通过访问p-data来获取数据接着p p-next从而移动到下一个节点一直到p变成NULL才停止。此操作容易出错的原因在于有不少人将p-next与p弄混淆了。p是当前节点的地址p-next是下一个节点的地址它们两者的类型是相同的然而含义却不一样。指针的定位器功能决定了链表的灵活性和数组不一样链表并不在内存里连续存放它的节点能够分散于各处。每个节点当中的next指针属于定位器记录着下一个节点的准确地址。当你写下p p-next的时候这就等同于把定位器里的坐标更新成下一个节点的坐标。这种离散存储使得链表能够动态地进行节点的增删操作相较于数组而言不需要提前去申请连续的大块内存。在内存当中一个链表的节点有可能位居地址0x1000、0x2050、0x1A80的位置这些位置彼此并不是相邻的。然而借助next指针串联起来便能够从一个节点找寻到下一个节点。针对p-next这个操作而言在底层实际上是读取当前节点地址偏移某个字节之处的值而这个值就是下一个节点的地址。要是next所存储的是0x2050那么p-next就等同于0x2050当赋值给p之后p便指向了那个崭新的地址。遍历链表时箭头的使用要区分两种情况于链表操作里头存在两种用场会用到箭头。其一乃是去访问当前节点的成员就好比说p-data、p-next这样的情况此时p是节点指针来着箭头是用以取成员的。其二是将next的值赋予p自身也就是说p p-next在这个时候等号右边的p-next所取出的乃是地址值等号左边的p是身为存放指针的变量。好多人把这两步给合并成一句话很容易就忽略掉p-next本身也是属于一个指针类型的值。写链表代码之际时常会出现的一个错误乃是混淆p以及p-next的类型要是p属于struct Node类型那么p-next同样是struct Node *类型此二者能够相互进行赋值然而倘若你写下p-next p那就致使当前节点的next指向自身从而形成环在进行遍历时会陷入死循环要是你写下p p那便什么都未曾改变正确的移动指针唯有p p-next这一种书写方式。掌握箭头含义才能看懂链表核心操作链表所进行的插入操作以及删除操作均是依赖于对箭头作出正确使用的。举例来说当于节点prev的后方插入一个全新节点new时那就需要书写new-next prev-next; prev-next new;。其中第一句是要使得新节点的next去指向prev原本的下一个节点而第二句是要让prev的next去指向新节点。要是这两句书写的顺序颠倒了那么便会造成后面的节点丢失的情况。要是不借助箭头直接写成new.next prev.next那语法立马就错了这是因为new是用于指向的指针并非结构体变量呀。要是在删除节点之际设若当前的这个节点恰恰就是prev那么此时就要去删除prev-next所指向的那个节点其写法应该是prev-nextprev-next-next。在这一句话当中可以看到两次都用到了箭头先是通过取prev-next从而获得了那个待删除节点的地址接着针对这个已经获取到的地址再去取-next进而得到下下个节点的地址最终把这个辛辛苦苦得到的地址赋予给prev-next。而想要弄明白这个链条的关键所在就是要清晰地分辨出每个箭头究竟是从哪一个指针起始去取的。瞧见这儿你理应已然清楚p p-next并非啥神奇法术它仅是把当前节点所存的下一个节点的地址提取出来放置进p这个Pointer变量里头使得p指向接下来的节点。接着问个事儿要是链表节点里存在不止一个指针成员像既有next又有prev那么于删除节点之际就得分别处置这俩指针你能够撰写出正确的代码不欢迎在评论区分享你的写法。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2449797.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!