c语言指针和多重指针

2023-05-16

数据结构是一种思想,不限制于某一种语言,但再各种语言实现中却有许多小细节不可忽视,比如c语言中的指针,是个让人十分头疼的问题。

先以链表为例,这里定义了链表的结点表示,data为该结点存储的数据,next是指向该节点的数据,
注:下文的所有代码都只是简化的代码,并不能上机运行。

typedef struct node
{
	Element data;
	struct node *next;
}Node;

这是链表一个结点的样子
在这里插入图片描述

为防止C初学者迷惑,做个例子
Node a -->int b; 这里Node就是类型,声明一个Node结构体a,跟声明整型变量b是一样的。

Node *c -->int *d; c是指向Node结构体的指针,d是指向整型数据的指针。他们的本质也是一样的。

在链表的操作中,有对指针的初始化,清空链表,增加和删除链表等等,接下来我们分两种情况讨论,第一种是没有头节点,第二种是有头节点

1: 没有头节点的单链表中,即第一个结点就存储数据的链表,如下图所示是有四个结点的无头结点单链表。
在这里插入图片描述
下面演示无头节点空链表的添加结点操作,在实际中没有意义,但很好理解c数据结构指针的问题。

//第一段代码
void Add(int num,Node *list2)
{	
	list2 = (Node *)malloc(sizeof(Node));
}
int main()
{	
	Node *list = NULL;
	Add(1,list);
	return 0;
}

第一段代码是错误的操作,下面是正确的

//第二段代码
void Add(int data,Node **list2)
{
	*list2 = (Node *)malloc(sizeof(Node));
}
int main()
{
	Node *list = NULL;
	Add(1,&list);
	return 0;
}

因为第一段代码在main函数中声明了指向Node的指针,想通过调用Add函数使list指向新的结点,但实际程序是这样做的,在Addt中临时创建指向Node的指针list2,把list的值赋给了list2,然后把list2指向新节结点,然后Addt函数执行完,list2变量被销毁,list原封不动,还是指向NULL。

而第二段代码中,把list的地址传递给InitList函数,在InitList中创建了指向指针的指针list2,即list2指向一个指针,这个指针是指向Node结构体的指针。即list2 = &list,然后又执行*list2 = (Node *)malloc(Node),因为指针list2的值就是指针list的地址,即list = (Node *)malloc(Node)。实参list的值原先指向NULL,现指向新结点。
这种现象在无头节点的链表的许多操作中都会出现,比如头插法,清空链表,初始化链表等等

接下来看有头节点的链表添加操作,即头节点不存储数据的单链表,如下图所示是有四个结点的有头结点单链表,四个节点中,三个是存放真实数据,头节点的数据域也不是没用,一般用来存放链表个数。

在这里插入图片描述
下面的代码是有头节点链表的添加操作

//第三段代码
void Add(int data,Node *list2)
{	
	list2->next = (Node *)malloc(sizeof(Node));
	list2->data ++;
}
int main()
{
	Node *list = (Node *)malloc(sizeof(Node));
	list->data = 0;//链表数据域是有效数据的结点个数
	Add(1,list);
	//执行完Add(list)后,list->data已变为1;
	return 0;
}

可能会以为第三段代码是错误的,添加不上代码,其实是正确的,程序在Add函数中声明了指向结构体Node的指针list2,并且list赋值给list2,即list和list2都指向了同一个结点
在这里插入图片描述
然后执行了 list2->next = (Node *)malloc(sizeof(Node));即通过形参list2改变了实参list所指向的Node结构体中指针null的值,list的值并未发生改变,也与第一段代码失败的结论相照应。执行完函数,list2被摧毁,而链表已完成添加结点的操作。

可以看出当没有头节点时,在空链表中添加元素,改动的是头指针本身的值,所以需要在函数中传递指针的指针,而有头结点时,改变的是头指针所指向结构体的值。从而发现有头节点的链表很大程度上简化了无头结点链表的操作,使很多需要单独判断的情况消失。

树和图也有类似需要注意的指针现象,因为树结构没有头节点等等原因。

补充:如果想在没有头节点的链表的操作中不使用双重指针的函数,可以用下面的思想,在函数中返回指针,并在main函数中用头指针list接收

Node *Add(int data,Node *list2)
{
	//添加结点的代码
	return list2;
}

int main()
{
	Node *list = NULL;
	list = Add(1);
	list = Add(2);
	return 0;
}

c的指针是真的有魅力,java实现的数据结构都看不到好多细节。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c语言指针和多重指针 的相关文章

  • asp不能正常用的原因

    前几天做网站时 xff0c 机子出现了这种症状 xff0c 重装过IE和IIS一样也无法解决 xff0c 在百度里找了一下 xff0c 下面的方法真的很适用 症状 xff1a 运行asp程序 包括其他动态网页程序 出现500内部错误信息 x
  • 用DLL实现把数据库的记录导出到EXCEL中(VB)

    39 新建一个ActiveX DLL工程工程名为DbToExcel 39 工程 gt 引用 引用Microsoft ActiveX Data Objects 2 6 Library 39 Microsoft Excel 9 0 Object
  • MySQL转换为SqlServer数据库

    如何将MySQL数据导入到SqlServer中 xff0c 请看以下步骤 xff1a 1 安装mysql数据库的ODBC驱动 xff0c mysql connector odbc 3 51 19 win32 msi 2 打开控制面板管理工具
  • DataTimePicker数据绑定遇到Null时异常的原因

    DateTimePicker1 DataBindings Add 34 Value 34 bindingSource1 34 assessortime 34 如果字段 assessortime的值 为 null 时 就会出现异常 后来发现
  • c#中DataTable与实体集合相互转换

    以下是将集合类转换成DataTable lt summary gt 将集合类转换成DataTable lt summary gt lt param name 61 34 list 34 gt 集合 lt param gt lt return
  • 用Linux命令行生成随机密码的十种方法

    转载自 极客范 xff0c 不得不夸夸强大的Bash啊 xff01 xff01 xff01 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
  • C++20 Ranges

    VS2019 C 43 43 20的Ranges 01 引入范围的动机02 范围 ranges 03 range v3库04 C 43 43 20 range demo 01 引入范围的动机 C 43 43 17以前的标准库中大多数通用算法
  • 面向对象分析设计步骤

    一 创建用例 初步确定用例 xff1a 1 确定参与者 2 确定用例 xff08 系统操作 xff09 3 确定参与者与用例之间的关系 用例细节描述 xff1a 1 用例名称 2 操作详细描述 3 前置条件描述 4 部署约束 5 正常事件流
  • collect2: ld terminated with signal 9 错误解决办法

    编译android是出现如下错误 xff1a target Java CameraEffectsTests out target common obj APPS CameraEffectsTests intermediates classe
  • 浅谈Stein算法求最大公约数(GCD)的原理及简单应用

    一 Stein算法过程及其简单证明 1 一般步骤 xff1a s1 当两数均为偶数时将其同时除以2至至少一数为奇数为止 xff0c 记录除掉的所有公因数2的乘积k xff1b s2 如果仍有一数为偶数 xff0c 连续除以2直至该数为奇数为
  • 【已解决】@Configration爆红

    64 Configration爆红 问题原因 xff1a 一 xff1a 没有添加依赖 二 xff1a 添加依赖了 xff0c 但是依赖版本过低 解决方法 xff1a 把依赖的版本改的高一点 span class token generic
  • 关于冒泡排序的程序( 第三次作业)

    此前想过把两种排序方式都一起写在一个工程文件里 xff0c 但做了下 xff0c 能力有限 xff0c 没法写完整 xff0c 所以就只能分别写 xff0c 这个是冒泡排序 xff0c 代码已尽量做到准确的注释 xff0c 希望提醒自己往后
  • BSS段

    深入理解计算机系统 bss段 xff0c data段 text段 堆 heap 和栈 stack 1 关于BSS段的大小 2 1 BSS段中的内容 2 2 BSS段在加载运行前的处理 3 3 BSS段的作用 3 4 代码优化对BSS段的影响
  • Java 比较两个List对象差集(根据某一值)

    很多都是比较List lt String gt 的 xff0c 和自身业务不符 xff0c jdk1 8 新特性强大的Stream API xff0c 具体是什么方法 xff0c 什么作用自行百度 xff0c 复制粘贴可以解决问题就OK 4
  • Windows10 安装Redis(图文教程)

    Redis xff08 Remote Dictionary Server xff0c 即远程字典服务 xff0c 是一个开源的使用ANSI C语言编写 支持网络 可基于内存亦可持久化的日志型 Key Value数据库 一 下载redis客户
  • e17 enlightenment 介绍及配置

    为什么要有一个窗口管理器 为什么一定要有一个桌面背景 xff0c 甚至是标题栏 或是如果把一个应用程序如firefox当成桌面背景行不行 桌面能不能再快一点 我不想把资源浪费在那些用不到的地方 Linux那么多虚拟桌面 xff0c 为什么我
  • Vim: Warning: input is not from a terminal 后退出 vim 终端异常

    Vim Warning input is not from a terminal 后退出 vim 终端异常 今天执行了如下命令调用 vi 来打开 find 搜索到的文件 xff1a longyu 64 longyu pc span clas
  • UNPV2 学习:Posix Message Queues

    文章目录 特点消息队列的释放mq notify 函数mq notify 使用信号通知消息到达直接在信号处理函数中调用 mq notify 与 mq receive 函数来接收数据在信号处理函数中设置标志在程序主逻辑中调用 mq notify
  • VMware ESXI虚拟机磁盘在线扩容后fdisk -l 找不到问题解决

    VMware ESXI虚拟机磁盘在线扩容后fdisk l 找不到问题解决 在VMware ESXI终端页面为虚拟机新增磁盘后 xff0c 进入虚拟机执行fdisk l 找不到新增的盘 重启系统肯定是可以解决的 xff0c 但是机器有在跑测试

随机推荐

  • go调用python

    安装 安装python和go的环境 xff0c 在debian和ubuntu系统上 xff0c 还要sudo apt install python all dev安装sudo apt get install pkg config安装go g
  • C++ 20 Concept 语法

    requires expression 一种表达式 xff0c 它很像一个lambda表达式 xff0c 一个未命名元函数 例如 xff1a requires int a int b a 43 b 其中 xff1a xff08 xff09
  • 带你一步步破解Android微信聊天记录解决方案

    哪个小可爱在偷偷的看我 前言 最近公司需要做个内部应用 xff0c 需求有通话并录音上传服务器 xff0c 微信聊天记录上传服务器 xff0c 我擦 xff0c 竟然要做严重窃取隐私的功能 xff0c 一万个草泥马奔腾而来 xff0c 于是
  • 51单片机定时器初值的计算

    什么是时钟周期 xff1f 什么是机器周期 xff1f 什么是指令周期 xff1f 时钟周期 时钟周期也称为振荡周期 xff0c 定义为时钟脉冲的倒数 xff08 可以这样来理解 xff0c 时钟周期就是单片机外接晶振的倒数 xff0c 例
  • 计算机操作系统之系统调用

    目录 x1f4a8 什么是系统调用 xff0c 有何作用 xff1f x1f4a8 系统调用与库函数的区别 x1f4a8 系统调用背后的过程 x1f4a8 总结 我们将带着以下问题去学习什么是系统调用 什么是系统调用 xff0c 有何作用
  • Python简易逻辑运算

    1 逻辑运算符 逻辑运算在编程中是十分重要的组成部分 xff0c 除了布尔值外 xff0c 还有其他用于逻辑运算的运算符 and 与 or 或 not 非 and连接的条件判断必须前后全部成立结果才能成立 xff08 所有条件True才输出
  • RCE漏洞之绕过

    文章目录 花括号斜杠空格过滤一些命令分隔符黑名单绕过拼接绕过编码绕过单引号和双引号绕过利用Shell 特殊变量绕过linux中直接查看文件内容的工具文件构造 花括号 在Linux bash中还可以使用 OS COMMAND ARGUMENT
  • 调用windows系统动态库实现wifi连接及问题

    有个项目是c 做的 xff0c 有个需求是程序启动自动连接指定wifi xff0c 想到windows有个系统库支持 xff0c 就用c 43 43 调的系统库 xff0c 然后c 再调c 43 43 封装好的接口 xff0c 比较简单 x
  • ffmpeg编译时cmp: command not found的问题

    执行安装 pacman S diffutils 参考 xff1a https stackoverflow com questions 18152168 using cygwin for ffmpeg build error cmp comm
  • 关于vs2013弹出“正在初始化模板“的问题

    此处有标题 昨天想在vs2013里配置python的编译环境 xff0c 于是在网上找了资源来下载 xff0c 但是由于中途出了一点意外 xff0c 配置过程中断了 xff0c 再等我回来想要新建项目的时候 xff0c 就弹出来这个框框 x
  • C++异常和C++11标准

    异常 异常概念 xff1a 程序中可预料但无法避免的错误 异常处理概念 xff1a 从发生异常的地方开始终止 xff0c 不再进行正常的流程 xff0c 去转而执行特定的异常处理流程 关键字 xff1a try try块 xff0c 受监控
  • linux下安装sl

    在root用户下哦 yum install sl 这里会提示 No package sl available 我们要安装一个wget yum install wget 中间一路yes 提示出现Complete即为安装成功 下一步用wget安
  • C++ 20 Range

    简单理解为 xff1a 封装了begin xff0c end 这一对迭代器的对象 range的抽象级别更高 xff0c 具有更多好处 1 xff09 避免繁琐 std for each begin v end v 迭代器 xff0c 书写繁
  • P3367 【模板】并查集

    题目描述 如题 xff0c 现在有一个并查集 xff0c 你需要完成合并和查询操作 输入格式 第一行包含两个整数N M 表示共有 N 个元素和 M 个操作 接下来 M 行 xff0c 每行包含三个整数 Zi Xi Yi 当 Zi 61 1
  • Notepad++ 下载安装和使用

    Notepad 43 43 下载安装和使用 介绍下载1 官网下载2 网盘下载 介绍 Notepad 43 43 是 Windows操作系统下的一套文本编辑器 xff1b Notepad 43 43 是免费软件 xff0c 可以免费使用 xf
  • 如何解决c++中循环包含头文件的问题

    今天在编译别的人写的代码时 xff0c 出现 missing type specifier int assumed Note C 43 43 does not support default int的错误 在网上搜了一下 xff0c 发现是
  • Qt开发之Go篇(五)

    QPushButton 基本用法就像前边Hello World示例中的那样 xff0c 现在我们看看不基本的用法 状态保持 QPushButton有一个属性是checkable xff0c 当设置为true之后按钮就会点一下是按下 xff0
  • note: please ensure that VS 2013,VS 2015, VS 2017,VS 2019 or VS 2022 was instal1ed with the Visua1 C

    编译rust代码报错 报错信息 error 1inker link exe 96 not found 61 note program not found note the msvc targets depend on the msvc li
  • 线性表习题

    本章的代码大多数都是伪代码 xff0c 是不能直接运行的 删除递增单链表中 xff0c data值为mink maxk之间的值 思想 xff1a 先找到第一个大于等于mink的结点q xff0c 并记录其前驱结点pre xff0c 再找到第
  • c语言指针和多重指针

    数据结构是一种思想 xff0c 不限制于某一种语言 xff0c 但再各种语言实现中却有许多小细节不可忽视 xff0c 比如c语言中的指针 xff0c 是个让人十分头疼的问题 先以链表为例 xff0c 这里定义了链表的结点表示 xff0c d