当前位置: 首页 > news >正文

链表(2)——带头双向循环链表

🍁一、链表的分类

🌕1.单向或者双向

🌕2.带头或者不带头(有无哨兵)

🌕3.循环或者不循环

🌕4.无头单向非循环链表(常用)

🌕5.带头双向循环链表(常用)

🌕注意:

1. 无头单向非循环链表: 结构简单 ,一般不会单独用来存数据。实际中更多是作为 其他数据结 构的子结构 ,如哈希桶、图的邻接表等等。另外这种结构在 笔试面试 中出现很多。
2. 带头双向循环链表: 结构最复杂 ,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了,后面我们代码实现了就知道了。

🍁二、双向链表的定义:

我们知道单链表的结点有一个数据域用于存放数据,一个指针域用于指向下一个结点。而 双向链表即是在此基础上每个结点多了一个指针域用于指向前一个结点;

🍁三、带头双向循环链表的定义

带头双向循环链表:即在双向链表的基础上,尾结点的next域指向头结点,使之体现出一个循环的结构。


🍁四、带头双向循环链表操作实现(多文件)

🌕1.定义:

只需在单链表定义的基础上多一个指针域prve,用于指向前驱;

typedef int SLDataType;typedef struct ListNode
{struct ListNode* prev;//指向前驱struct ListNode* next;//指向后继SLDataType data;//数据域
}ListNode;

🌕2.获得新结点

因为后续经常用到此函数,所以首先介绍。

操作很简单,用malloc函数生成即可

//获得新结点
ListNode* BuyLTNode(SLDataType x)
{//用malloc函数动态生成即可ListNode* node = (ListNode*)malloc(sizeof(ListNode));if (node == NULL){//检查malloc错误原因perror("malloc");exit(-1);}//处理新结点的成员node->data = x;node->next = NULL;node->prev = NULL;return node;
}

🌕3.初始化

①:原本初始化需要改变头结点phead,所以需要结构体二级指针,但其他操作都不需要二级指针,所以为了排面,我们可以用返回值来代替使用二级指针;

②:初始化只需要获得一个新结点作为一个头结点,然后头结点的两个指针域互相指向代表此时为空表;

//初始化
ListNode* Init()
{//获得头结点,头结点数据域可以存点有意义的数据,也可以随便存,因为用不着ListNode* phead = BuyLTNode(0);//初始化头结点的两个指针域指向头结点本身表示为空表phead->next = phead;phead->prev = phead;return phead;
}

🌕4.尾插法

该种类链表虽然结构复杂,但操作却非常简单,比如尾插法就有几点优势于单链表;

2.1:优势

①:单链表尾插需要考虑元素是否为空,当链表中没有元素时会改变头指针(头结点),所以需要使用结构体二级指针;但带头双向循环链表因为带有头,所以不管有无元素,在尾插时只需改变结构体指针域,即改变结构体,所以都只需要使用结构体指针;

②:单链表尾插时需要找到尾结点,但带头双向循环链表不需要,因为多了一个prev指针域,头结点的prev域就是尾结点;可以参考上述图片;

2.2:尾插法大致分为“四步骤”:

首先创建一个临时指针tail指向头结点的prev域,即指向尾结点便于操作

①:将tail的next域指向新结点;

②:将新结点的prev域指向tail结点(尾结点);

③:将新结点的next域指向头结点;

④:将头结点的prev域指向新结点。

2.3:源代码
//尾插
//因为带有头,所以操作只需要改变结构体,所以只需要结构体指针
//具体操作看注释
void LTPushBack(ListNode* phead, SLDataType x)
{//因为是带头的,所以phead至少是个头指针,所以phead不可能为空,所以需要用assert检查一下assert(phead);//找到尾结点tailListNode* tail = phead->prev;//获取新结点newnodeListNode* newnode = BuyLTNode(x);//四步骤tail->next = newnode;newnode->prev = tail;phead->prev = newnode;newnode->next = phead;
}

🌕5.打印数据

此链表打印数据与单链表有一个区别,就是结束条件不同;因为带头双向循环链表的尾结点的next域不指向NULL,而是指向头结点,所以结束条件为“tail==head”;

//打印
void LTprint(ListNode* phead)
{//创建一个临时指针便于遍历操作ListNode* node = phead->next;//为了体现此链表结构而打印printf("phead<->");//打印数据,当临时指针node等于头结点时结束while (node != phead){printf("%d<->", node->data);node = node->next;}//为了体现此链表结构而打印printf("phead\n");
}

🌕6.尾删法

6.1:相对于单链表,该链表也有几个优点:

①:尾删不用找尾结点以及倒数第二个结点,用prev域就可以找到;

②:当表中只有一个元素时,单链表需要改变结构体指针,所以需要单独分类;而此链表因为有带头结点和prev域,所以用正常尾删方法即可;

6.2:尾删步骤:

①:判断单链表是否为空(条件:phead->next=phead时即为空);

②:创建一个临时指针tail1用于保存尾结点,方便后续释放尾结点;

③:创建一个临时指针tail2用于保存尾结点的prev域(尾结点的前一个结点),方便进行尾删操作;

④:tail2的next域指向头结点:tail2->next=phead;

⑤:头结点的prev域指向tail2结点:phead->prev=tail2;

⑥:释放尾结点tail1。

6.3:源代码:

//尾删
void LTPopBack(ListNode* phead)
{assert(phead);//检查是否为空if (phead->next == phead){printf("此链表为空,尾删失败!\n");return;}//临时指针保存结点ListNode* tail1 = phead->prev;ListNode* tail2 = phead->prev->prev;//断开与尾结点的链接tail2->next = phead;phead->prev = tail2;//释放尾结点free(tail1);
}

🌕7.头插法

同上,因为prev的存在,所以不用考虑初始表是否为空表的情况;

7.1:四步骤:

①:新结点的next域指向head的next域(即指向插入前的首结点);

②:head的next域的prev域指向新结点(即插入前的首结点的prev域指向新结点);

③:新结点的prev域指向头结点head;

④:头结点head的next域指向新结点。

7.2:源代码
//头插
void LTPushFront(ListNode* phead, SLDataType x)
{assert(phead);//新结点ListNode* newnode = BuyLTNode(x);//四步骤newnode->next = phead->next;phead->next->prev = newnode;newnode->prev = phead;phead->next = newnode;
}

🌕8.头删法

头删法也很简单,只需考虑个个指针的链接即可;

8.1:步骤

①:创建临时指针first指向首结点,便于后续释放首结点;

②:创建临时指针second指向第二个结点,便于进行删除操作;

③:改变指针链接:

second->prev = phead;

phead->next = second;

④:释放首结点;

8.2:源代码
//头删
void LTPopFront(ListNode* phead)
{assert(phead);if (phead->next == phead){printf("链表为空,头删失败!\n");return;}//临时指针first指向首结点,便于后续释放首结点//临时指针second指向第二个结点,便于进行删除操作ListNode* first = phead->next;ListNode* second = first->next;//删除second->prev = phead;phead->next = second;//释放首结点free(first);
}

🌕9.在pos位置之前插入结点

其实很简单,只需要搞得指针域的链接顺序,防止指针丢失即可

9.1:源代码如下:
 
//在pos位置之前插入结点
ListNode* LTInsrt(ListNode* pos, SLDataType x)
{assert(pos);//新结点ListNode* newnode = BuyLTNode(x);//插入pos->prev->next = newnode;newnode->prev = pos->prev;newnode->next = pos;pos->prev = newnode;
}
9.2:有了这个算法后我们可以改进头插与尾插:

①:当pos==phead->next时,即为头插算法:
 

//头插
void LTPushFront(ListNode* phead, SLDataType x)
{assert(phead);//改进LTInsrt(phead->next, x);
}

②:当pos等于phead时,即为尾插算法:

//尾插
void LTPushBack(ListNode* phead, SLDataType x)
{//因为是带头的,所以phead至少是个头指针,所以phead不可能为空,所以需要用assert检查一下assert(phead);//改进LTInsrt(phead, x);
}

🌕10.删除pos位置的结点

10.1:步骤:

①:创建临时指针first保存pos前一个结点;

②:创建临时指针second保存pos后一个结点;

③:改变指针链接,删除pos结点:

first->next = second; 

second->prev = first;

④:释放pos结点。

10.2:源代码
//删除pos位置的结点
void LTErase(ListNode* pos)
{assert(pos);//临时指针ListNode* first = pos->prev;ListNode* second = pos->next;//删除first->next = second;second->prev = first;//释放posfree(pos);
}
10.3:有了这个算法,我们可以改进头删与尾删

①:当pos==phead->next时,即为头删算法:

//头删
void LTPopFront(ListNode* phead)
{assert(phead);//改进LTErase(phead->next);
}

②:当pos==phead->prev时,即为尾删算法:

//尾删
void LTPopBack(ListNode* phead)
{assert(phead);//改进LTErase(phead->prev);
}

🍁五、测试源代码

main.c

#include"List.h"void STTest1()
{ListNode* plist = NULL;plist = Init();//初始化//尾插LTPushBack(plist, 1);LTPushBack(plist, 2);LTPushBack(plist, 3);LTPushBack(plist, 4);LTPushBack(plist, 5);//打印LTprint(plist);
}void STTest2()
{ListNode* plist = NULL;plist = Init();//初始化//尾插LTPushBack(plist, 1);//打印LTprint(plist);//尾删LTPopBack(plist);//打印LTprint(plist);
}void STTest3()
{ListNode* plist = NULL;plist = Init();//初始化//头插LTPushFront(plist, 1);LTPushFront(plist, 2);//打印LTprint(plist);//头删LTPopFront(plist);//打印LTprint(plist);//头删LTPopFront(plist);//打印LTprint(plist);
}int main()
{//STTest1();//STTest2();STTest3();return 0;
}

List.c

#include"List.h"//获得新结点
ListNode* BuyLTNode(SLDataType x)
{//用malloc函数动态生成即可ListNode* node = (ListNode*)malloc(sizeof(ListNode));if (node == NULL){//检查malloc错误原因perror("malloc");exit(-1);}//处理新结点的成员node->data = x;node->next = NULL;node->prev = NULL;return node;
}//初始化
ListNode* Init()
{//获得头结点,头结点数据域可以存点有意义的数据,也可以随便存,因为用不着ListNode* phead = BuyLTNode(0);//初始化头结点的两个指针域指向头结点本身表示为空表phead->next = phead;phead->prev = phead;return phead;
}//打印
void LTprint(ListNode* phead)
{assert(phead);//创建一个临时指针便于遍历操作ListNode* node = phead->next;//为了体现此链表结构而打印printf("phead<->");//打印数据,当临时指针node等于头结点时结束while (node != phead){printf("%d<->", node->data);node = node->next;}//为了体现此链表结构而打印printf("phead\n");
}//尾插
//因为带有头,所以操作只需要改变结构体,所以只需要结构体指针
//具体操作看注释
void LTPushBack(ListNode* phead, SLDataType x)
{//因为是带头的,所以phead至少是个头指针,所以phead不可能为空,所以需要用assert检查一下assert(phead);找到尾结点tail//ListNode* tail = phead->prev;获取新结点newnode//ListNode* newnode = BuyLTNode(x);四步骤//tail->next = newnode;//newnode->prev = tail;//phead->prev = newnode;//newnode->next = phead;//改进LTInsrt(phead, x);
}//尾删
void LTPopBack(ListNode* phead)
{assert(phead);检查是否为空//if (phead->next == phead)//{//	printf("此链表为空,尾删失败!\n");//	return;//}临时指针保存结点//ListNode* tail1 = phead->prev;//ListNode* tail2 = phead->prev->prev;断开与尾结点的链接//tail2->next = phead;//phead->prev = tail2;释放尾结点//free(tail1);//改进LTErase(phead->prev);
}//头插
void LTPushFront(ListNode* phead, SLDataType x)
{assert(phead);//新结点//ListNode* newnode = BuyLTNode(x);四步骤//newnode->next = phead->next;//phead->next->prev = newnode;//newnode->prev = phead;//phead->next = newnode;//改进LTInsrt(phead->next, x);
}//头删
void LTPopFront(ListNode* phead)
{assert(phead);/*if (phead->next == phead){printf("链表为空,头删失败!\n");return;}*/临时指针first指向首结点,便于后续释放首结点临时指针second指向第二个结点,便于进行删除操作//ListNode* first = phead->next;//ListNode* second = first->next;删除//second->prev = phead;//phead->next = second;释放首结点//free(first);//改进LTErase(phead->next);
}//在pos位置之前插入结点
void LTInsrt(ListNode* pos, SLDataType x)
{assert(pos);//新结点ListNode* newnode = BuyLTNode(x);//插入pos->prev->next = newnode;newnode->prev = pos->prev;newnode->next = pos;pos->prev = newnode;
}//删除pos位置的结点
void LTErase(ListNode* pos)
{assert(pos);//临时指针ListNode* first = pos->prev;ListNode* second = pos->next;//删除first->next = second;second->prev = first;//释放posfree(pos);
}

List.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>typedef int SLDataType;typedef struct ListNode
{struct ListNode* prev;//指向前驱struct ListNode* next;//指向后继SLDataType data;//数据域
}ListNode;//获得一个新结点
ListNode* BuyLTNode(SLDataType x);//初始化
ListNode* Init();//打印
void LTprint(ListNode* phead);//尾插
void LTPushBack(ListNode* phead,SLDataType x);//尾删
void LTPopBack(ListNode* phead);//头插
void LTPushFront(ListNode* phead, SLDataType x);//头删
void LTPopFront(ListNode* phead);//在pos位置之前插入结点
void LTInsrt(ListNode* pos, SLDataType x);//删除pos位置的结点
void LTErase(ListNode* pos);

本次知识到此结束,希望对你有所帮助!

相关文章:

链表(2)——带头双向循环链表

&#x1f341;一、链表的分类 &#x1f315;1.单向或者双向 &#x1f315;2.带头或者不带头&#xff08;有无哨兵&#xff09; &#x1f315;3.循环或者不循环 &#x1f315;4.无头单向非循环链表&#xff08;常用&#xff09; &#x1f315;5.带头双向循环链表&#xff08;常用…...

C语言 函数指针

函数指针是C语言中的一种特殊类型&#xff0c;它允许你像操作变量一样操作函数。函数指针的主要用途是存储并后续调用一组函数。 在C语言中&#xff0c;函数指针的定义通常如下所示&#xff1a; 返回类型 (*指针变量名)(参数类型) 例如&#xff0c;如果你有一个返回整数并接受…...

F. Vasilije Loves Number Theory

Problem - F - Codeforces 思路&#xff1a;分析一下题意&#xff0c;对于第一种操作来说&#xff0c;每次乘以x&#xff0c;那么nn*x&#xff0c;然后问是否存在一个a使得gcd(n,a)1并且n*a的约数个数等于n&#xff0c;有最大公约数等于1我们能够知道其实这两个数是互质的&…...

electron打包后主进程下载文件崩溃

electronvue3写了一个小项目&#xff0c;实现了一个文件下载功能 存在的问题 打包后&#xff0c;应用下载文件崩溃代码 // 渲染进程window.electron.ipcRenderer.invoke(save-file, {path: r.filePath,fileurl: previewUrl,}).then(response > {console.log(response ----…...

Spring实例化源码解析之Custom Events下集(九)

上集从官网的角度讲解了基本的使用和源码的内容&#xff0c;没有深入的进行分析&#xff0c;本章将从源码的角度分析ApplicationEvent、ApplicationListener、ApplicationEventMulticaster这三者之间的关系。 initApplicationEventMulticaster 上一章后续部分给出了源码的含义…...

python numpy库关键函数说明

python numpy库函数说明 np.argwhere()np.dtype()np.shape()np.zeros() np.argwhere() 输入参数是一个基本的逻辑表达式&#xff0c;输出检索结果的索引值。 >>> x np.arange(6).reshape(2,3) >>> x array([[0, 1, 2],[3, 4, 5]]) >>> np.argwhe…...

【Linux C】Linux如何执行一个程序(程序存储空间、系统调用、内核调用)

文章目录 一、程序存储空间1.1 C语言程序存储空间1.2 用户空间和内核空间1.3 用户模式和内核模式 二、内核调用-系统调用-C语言库函数2.1 系统调用和内核调用2.2 C语言库函数 三、Linux如何执行一个程序 一、程序存储空间 本节说的空间主要是指内存空间&#xff0c;即程序如何分…...

IP协议总结

一、定义。 IP全称为Internet Protocol&#xff0c;是TCP/IP协议族中的一员&#xff0c;负责实现数据在网络上的传输。它是一种无连接、不可靠的数据报协议。 IP协议常用于Internet网络和局域网中&#xff0c;它通过将数据包进行分组并进行逐跳转发来实现数据在网络中的传输。…...

微信支付v2

文档&#xff1a; https://pay.weixin.qq.com/wiki/doc/api/index.html 微信小程序&#xff1a;https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter11_1 需要一个微信认证后的小程序&#xff0c;&#xff0c;还需要一个&#xff0c;在微信商户平台&#xff0c;&…...

tcpdump(二)命令行参数讲解(一)

一 tcpdump实战详解 1、我们做抓包,一般都需要指定条件,保证对系统的CPU、内存、磁盘资源不会产生过大的响应备注&#xff1a; 遇到过tcpdump持续抓包导致系统挂了2、条件&#xff1a;1) tcpdump的 基础命令选项参数2) 真正的 过滤条件 抓包工具tcpdump用法说明 ① 参数学…...

10_8C++

X-Mind #include <iostream>using namespace std; class Rect { private:int width;int heigjt; public:void init(int w,int h){width w;heigjt h;}void set_w(int w){width w;}void set_h(int h){heigjt h;}void show(){cout << "矩形的周长" <…...

JVM篇---第七篇

系列文章目录 文章目录 系列文章目录一、Minor GC与Full GC分别在什么时候发生?二、你知道哪些JVM性能调优参数?(简单版回答)三、对象一定分配在堆中吗?有没有了解逃逸分析技术?一、Minor GC与Full GC分别在什么时候发生? 新生代内存不够用时候发生MGC也叫YGC,JVM内存…...

更新Xcode 版本后运行项目出现错误 Unable to boot the Simulator 解决方法

错误截图 出现 Unable to boot the Simulator 错误原因很多&#xff0c;以下方法不一定都适用&#xff0c;我是通过以下方法解决的 打开命令终端输入以下命令&#xff0c;可能需要你输入开机密码 sudo rm -rf ~/Library/Developer/CoreSimulator/Caches...

winform窗体控件太多显示不过来,怎么实现滚动条

winform窗体控件太多显示不过来&#xff0c;怎么实现滚动条 Winform Panel实现滚动条 一、创建panel 在界面上拖拽一个父级Panel1&#xff0c;然后在Panel1里面拖拽一个子级Panel2 设置父级Panel1的AutoScroll属性为True 属性设置好后&#xff0c;当子级高度或者宽度大于父…...

WebSocket连接异常 Error parsing HTTP request header Connection reset by peer

问题描述 在使用spring的方式集成websocket时&#xff0c;在配置WebSocketConfigurer后 Configuration EnableWebSocket public class WebSocketConfiguration implements WebSocketConfigurer {ResourceServletWebSocketServerHandler servletWebSocketServerHandler;Overri…...

Spring中shutdown hook作用

在Spring框架中&#xff0c;Shutdown Hook&#xff08;关闭钩子&#xff09;是一种机制&#xff0c;用于在应用程序关闭时执行一些清理操作Spring会向JVM注册一个shutdown hook&#xff0c;在接收到关闭通知的时候&#xff0c;进行bean的销毁&#xff0c;容器的销毁处理等操作在…...

关于IvorySQL和OpenGauss包SPEC处理的一些思考

包的SPEC区可以定义下面三种类型&#xff08;本篇只讨论SPEC区的情况&#xff09; 变量类型&#xff08;nested table等&#xff09;&#xff08;注意这是包内定义的类型&#xff0c;与SQL创建的不通&#xff09;游标 这三种类型在PG原生中&#xff0c;是找不到相似的功能的&…...

我用PYQT5做的第一个实用的上位机项目(六)

将之前的画面和代码用复制粘贴的方法复制四份&#xff0c;就完成了整个主画面和主程序的基本构建。 下面的工作是关于PLC和通信。 上位机项目&#xff0c;其与PLC通信的模式很多都是这样的&#xff1a;在没有操作和设置的平常显示界面&#xff0c;按照预定周期从PLC读取当前页…...

【高级语言程序设计】python函数式编程(一)

基础知识 Python函数式编程的主要内容包括以下几个方面&#xff1a; (1)函数作为一等公民&#xff1a;在函数式编程中&#xff0c;函数被视为一等公民&#xff0c;可以像其他数据类型一样被传递、赋值以及作为返回值。 (2)不可变数据&#xff1a;函数式编程鼓励使用不可变数据…...

使用python查找指定文件夹下所有xml文件中带有指定字符的xml文件

文件夹目录如下&#xff08;需要递归删除文件夹下的.DS_Store文件&#xff09;&#xff1a; labels文件夹下面是xml文件&#xff1a; import os import os.pathpath "name/labels" files os.listdir(path) # 得到文件夹下所有文件名称 s []for xmlFile in files:…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...