2023-10-19 指针与指针的指针,我就不信你脑壳不疼

2023-10-21 21:28
文章标签 指针 2023 19 不信 不疼 脑壳

本文主要是介绍2023-10-19 指针与指针的指针,我就不信你脑壳不疼,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


点击 <C 语言编程核心突破> 快速C语言入门


指针与指针的指针,我就不信你脑壳不疼

  • 前言
  • 一、从一个链表实现说起
  • 二、指针, 指针的指针, 头疼的来源
  • 总结


前言

C实现一个链表,为什么有时候传入指针,有时候传入指针的指针,究竟有什么区别? 今天就简单说说,让你头疼的指针套指针问题。


一、从一个链表实现说起

先看一个简单的链表结构:

我们有一个节点LNode, 包含一个数据data, 一个节点指针next, 将节点指针的类型取名为LinkList, 所以LinkList 本身就是一个指针.

#include <stdio.h>
#include <stdlib.h>typedef struct LNode
{int data;struct LNode *next;
} LNode;typedef LNode *LinkList;

我们实现一个链表的生成函数CreateList, 它的参数是LinkList的指针, 也就是LNode节点的指针的指针.

函数会让你输入节点个数,以及每个节点的数值, 形成一个链表,

int CreateList(LinkList *list)
{LNode *node = NULL;int cnt;scanf("%d", &cnt);for (int i = 0; i < cnt; i++){node = (LinkList)malloc(sizeof(LNode));if (!node){return 1;}scanf("%d", &node->data);node->next = *list;*list = node;}return 0;
}

比如我们输入 3 0 1 2,

代表链表有3个值, 其值分别是 0, 1, 2.

而如果从头节点算起, 它的储值顺序是反过来的,

是 2, 1, 0 这个顺序, 头节点永远得到最后一次输入的值.

链表
这就是输入指针的指针的目的,

我要改变传入参数的那个节点指针的值,

单单传入节点指针, 将无法做到, 因为C语言没有引用,

需要通过指针解引用来引用那个需要改变的指针.

最后是链表的删除, 我还是传入指针的指针,

链表删除的时候我们是从头节点删除,

一个一个直至节点指向NULL.

并且保证, 最后传入函数的 list 指向 NULL.

如果传入的是LinkList, 则删除链表后list就是一个野指针, 需要格外注意.

int DeleteList(LinkList *list)
{LinkList temp = NULL;while (*list){temp = (*list)->next;free(*list);*list = temp;}return 0;
}

链表删除

如果弄懂以上操作, 你可以比较轻松的实现一个栈结构, 后进先出.

下面是个简单的测试用例, 可以通过断点调试, 一步步看看究竟发生了什么.

int main()
{LinkList list = NULL;CreateList(&list);DeleteList(&list);return 0;
}

二、指针, 指针的指针, 头疼的来源

从上面的例子, 你应该可以基本了解, 在什么时候, 需要操作指针的指针,

本来一级指针理解起来就不是太容易, 二级指针可以说就比较晦涩了,

但有的时候, 你不理解二级指针, 可能无法满足一些需求, 同时, 也可能导致野指针的出现,

对于C这种没有gc垃圾回收机制, 也没有C++这种RAII资源管理机制的语言, 谨慎处理指针和内存, 还是挺费头发的.


总结

以上就是在C语言中, 我们运用二级指针作为形参, 实现链表功能的一个简单阐述, 对于C语言, 指针是永远绕不开的话题, 把它玩儿明白, 你就入门了.


点击 <C 语言编程核心突破> 快速C语言入门


这篇关于2023-10-19 指针与指针的指针,我就不信你脑壳不疼的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/257069

相关文章

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

C语言指针入门 《C语言非常道》

C语言指针入门 《C语言非常道》 作为一个程序员,我接触 C 语言有十年了。有的朋友让我推荐 C 语言的参考书,我不敢乱推荐,尤其是国内作者写的书,往往七拼八凑,漏洞百出。 但是,李忠老师的《C语言非常道》值得一读。对了,李老师有个官网,网址是: 李忠老师官网 最棒的是,有配套的教学视频,可以试看。 试看点这里 接下来言归正传,讲解指针。以下内容很多都参考了李忠老师的《C语言非

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多

C和指针:字符串

字符串、字符和字节 字符串基础 字符串就是一串零个或多个字符,并且以一个位模式为全0的NUL字节结尾。 字符串长度就是字符串中字符数。 size_t strlen( char const *string ); string为指针常量(const修饰string),指向的string是常量不能修改。size_t是无符号数,定义在stddef.h。 #include <stddef.h>

【C++】作用域指针、智能指针、共享指针、弱指针

十、智能指针、共享指针 从上篇文章 【C++】如何用C++创建对象,理解作用域、堆栈、内存分配-CSDN博客 中我们知道,你的对象是创建在栈上还是在堆上,最大的区别就是对象的作用域不一样。所以在C++中,一旦程序进入另外一个作用域,那其他作用域的对象就自动销毁了。这种机制有好有坏。我们可以利用这个机制,比如可以自动化我们的代码,像智能指针、作用域锁(scoped_lock)等都是利用了这种机制。

MFC中App,Doc,MainFrame,View各指针的互相获取

纸上得来终觉浅,为了熟悉获取方法,我建了个SDI。 首先说明这四个类的执行顺序是App->Doc->Main->View 另外添加CDialog类获得各个指针的方法。 多文档的获取有点小区别,有时间也总结一下。 //  App void CSDIApp::OnApp() {      //  App      //  Doc     CDocument *pD

C和指针:结构体(struct)和联合(union)

结构体和联合 结构体 结构体包含一些数据成员,每个成员可能具有不同的类型。 数组的元素长度相同,可以通过下标访问(转换为指针)。但是结构体的成员可能长度不同,所以不能用下标来访问它们。成员有自己的名字,可以通过名字访问成员。 结构声明 在声明结构时,必须列出它包含的所有成员。 struct tag {member-list} variable-list ; 定义一个结构体变量x(包含

react笔记 8-19 事件对象、获取dom元素、双向绑定

1、事件对象event 通过事件的event对象获取它的dom元素 run=(event)=>{event.target.style="background:yellowgreen" //event的父级为他本身event.target.getAttribute("aid") //这样便获取到了它的自定义属性aid}render() {return (<div><h2>{

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis