【C++】list讲解及模拟

目录

list的基本介绍

list模拟实现

一.创建节点

二.迭代器

1.模版参数

2.迭代器的实现:

a. !=

b. ==

c. ++ --

d. *指针

e.&引用

整体iterator (与const复用):

三.功能实现

1.模版参数

2.具体功能实现:

2.1 构造函数

2.2 begin() && end()

2.3插入

insert任意位置插入

push_back 尾插&& push_front前插

2.4 删除

erase任意位置删除

pop_back 头删 && pop_front尾删

2.5 拷贝构造 && 赋值操作符

2.6 clear() && 析构函数

代码示例

Test.cpp

list.h


list的基本介绍

list本质上是一个带头双向循环链表,列表是一种用于存储一组元素的数据结构,元素按照插入的顺序排列。它允许动态地添加和删除元素,可以重复存储相同的值。列表提供了对元素的插入、删除、访问和遍历等常用操作。

列表是序列容器,允许在序列内的任何位置插入和擦除操作,并在两个方向上进行迭代。

列表容器被实现为双链接列表;双链接列表可以将它们所包含的每个元素存储在不同的和不相关的存储位置中。顺序通过与前面元素的链接和后面元素的链接的关联在内部保持。

与其他序列容器相比,列表和前向列表的主要缺点是它们无法通过位置直接访问元素; 例如,要访问列表中的第六个元素,必须从已知位置(如开始或结束)迭代到该位置,该位置之间的距离需要线性时间。它们还会消耗一些额外的内存来保持与每个元素相关联的链接信息(这可能是大量小元素列表的一个重要因素)。

若要查看双向循环链表相关知识→:数据结构:线性表之-循环双向链表(万字详解)_数据结构循环双链表概念-CSDN博客

list模拟实现

一.创建节点

template <class T>//模版
struct list_node
{list_node<T> *_prev;//前一节点list_node<T> *_next;//后一节点T _data;
​// 构造函数,创建链表list_node(const T &x = T()) // 用匿名对象做缺省值(调用默认构造),以存储其他类型的元素: _next(nullptr), _prev(nullptr), _data(x){}
};

二.迭代器

1.模版参数

template <class T, class Ref, class Ptr>
  1. class T:表示元素类型,为了应对要接收不同类型的数据

  2. class Ref:引用类型参数模版,Ref用于提供对迭代器所指向元素的引用

  3. class Ptr:指针类型参数模版,Ptr用于提供对迭代器所指向元素的指针。

后面会提到Ref,Ptr作用,请仔细阅读哦

2.迭代器的实现:

基本模版:

template <class T, class Ref, class Ptr>
struct __list_iterator
{//重新命名typedef list_node<T> node; typedef __list_iterator<T, Ref, Ptr> self;node *_node;//指向列表节点的指针,用于追踪迭代器的当前位置。
​//构造函数,接受一个指向列表节点的指针,并将其作为初始位置给 _node。__list_iterator(node *n): _node(n){}
};

这个结构体的作用是提供列表的迭代功能,它可以被用于遍历列表中的元素,并对元素进行访问和操作。

"const T&"表示迭代器所指向元素的引用类型,而"const T*"表示迭代器所指向元素的指针类型。 这样定义迭代器的目的是为了在const成员函数中使用该迭代器,并保证在遍历列表时不会修改列表中的元素"

参考:

list<int>::iterator it = lt.begin();
//__list_itreator后续被重命名为iterator
a. !=
bool operator!=(const self &s)
{return _node != s._node;
}
b. ==
bool operator==(const self &s)
{return _node == s._node;
}
c. ++ --
self &operator++()
{_node = _node->_next;return *this;
}
self &operator++(int)// 后置++
{self tmp = *this;_node = _node->_next;return tmp;
}
​
self &operator--()
{_node = _node->_prev;return *this;
}
self &operator--(int) // 后置--
{self tmp = *this;_node = _node->_prev;return tmp;
}
d. *指针

重载了解引用运算符(*),返回 _node->_data 的引用,即迭代器所指向的元素

Ref &operator*()//加const不能修改数据
{return _node->_data;
}
e.&引用

重载了箭头运算符(->),返回 _node->_data 的指针,即迭代器所指向元素的指针

Ptr operator->()
{return &(_node->_data); // 取地址
}

Ref与Ptr的定义在class list中进行定义

整体iterator (与const复用):
template <class T, class Ref, class Ptr>
struct __list_iterator
{typedef list_node<T> node;typedef __list_iterator<T, Ref, Ptr> self;node *_node;__list_iterator(node *n): _node(n){}Ref &operator*(){return _node->_data;}Ptr operator->(){return &(_node->_data); // 取地址}self &operator++(){_node = _node->_next;return *this;}self &operator++(int){self tmp = *this;_node = _node->_next;return tmp;}self &operator--(){_node = _node->_prev;return *this;}self &operator--(int) // 后置--{self tmp = *this;_node = _node->_prev;return tmp;}bool operator!=(const self &s){return _node != s._node;}bool operator==(const self &s){return _node == s._node;}
};

三.功能实现

1.模版参数

    
template <class T>
class list
{typedef list_node<T> node;public://iterator和const_iterator都是公用接口typedef __list_iterator<T, T &, T *> iterator;typedef __list_iterator<T, const T &, const T *> const_iterator;private://头节点node *_head; // ListNode<T>是类型 , ListNode是类名
};

2.具体功能实现:

2.1 构造函数

为了后续操作的方便,将初始化链表代码写在另一个函数里

void empty_init()
{_head = new node;_head->_next = _head;_head->_prev = _head;
}
list()
{empty_init();
}
2.2 begin() && end()
iterator begin()
{return iterator(_head->_next);
}
​
iterator end()
{return iterator(_head);
}
​
const_iterator begin() const
{return const_iterator(_head->_next);
}
​
const_iterator end() const
{return const_iterator(_head);
}

test:通过迭代器依次打印出元素

list<int>::iterator it = lt.begin();
while (it != lt.end())
{cout << *it << " ";++it;
}
cout << endl;

我们将迭代器遍历封装到一个函数内:

void print_list(const list<T> &lt)
{cout << "---list---" << endl;// list<int>::const_iterator it = lt.begin();list<int>::const_iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl<< "---list---" << endl;
}
2.3插入
insert任意位置插入
void insert(iterator pos, const T &x)
{node *cur = pos._node;   // .访问pos内的成员变量_nodenode *prev = cur->_prev; // ->访问指针所指向的节点的成员
​node *new_node = new node(x);
​prev->_next = new_node;new_node->_prev = prev;new_node->_next = cur;cur->_prev = new_node;
}
push_back 尾插&& push_front前插
void push_back(const T &x)
{insert(end(), x);
}
void push_front(const T &x)
{insert(begin(), x);
}

test:

void test_list3()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);
​list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;
​it = lt.begin();list<int>::iterator pos = lt.begin();++pos;lt.insert(pos, 20);
​lt.print_list(lt);
​cout << endl;
}
2.4 删除
erase任意位置删除
iterator erase(iterator pos)
{assert(pos != end());
​node *prev = pos._node->_prev;node *next = pos._node->_next;
​prev->_next = next;next->_prev = prev;delete pos._node;
​return iterator(next);
}
pop_back 头删 && pop_front尾删
void pop_back()
{erase(--end());
}
void pop_front()
{erase(begin());
}

test:

void test_list4()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.print_list(lt);cout << endl;lt.push_back(100);lt.push_front(99);lt.print_list(lt);cout << endl;
​lt.pop_back();lt.pop_front();lt.print_list(lt);cout << endl;
}

2.5 拷贝构造 && 赋值操作符

swap交换函数:

void swap(list<T> &temp)
{std::swap(_head, temp._head);
}

当调用swap函数时[例子:lt2拷贝lt1调用swap时],调用拷贝构造将lt1进行拷贝再交换到lt2

list:

list(const list<T> &lt)
{empty_init();//创建头节点list<T> temp(lt.begin(), lt.end());swap(temp);
}

赋值操作数:

// lt3=lt2
// 不能使用&,而是传值调用拷贝构造,拷贝lt2,赋值给lt3
list<T> &operator=(const list<T> lt)//const list<T>& lt
{swap(lt);return *this;
}

test:

void test_list6()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.print_list(lt);cout << endl;
​// list<int> lt2(lt);// lt2.print_list(lt2);// cout << endl;list<int> lt2 = lt;lt2.print_list(lt2);lt.print_list(lt);
}

2.6 clear() && 析构函数

clear:清除头节点以外的数据

void clear()
{iterator it = begin();while (it != end())it = erase(it); // erase(it++);//后置++返回的是前一个的拷贝,不会失效
}

test:

void test_list5()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.print_list(lt);cout << endl;
​lt.clear();lt.push_back(20);
​lt.print_list(lt);
}

析构:

~list()
{clear();delete _head;_head = nullptr;
}

代码示例

Test.cpp

#include "list.h"int main()
{wzf::test_list6();return 0;
}

list.h

#pragma once
#include <iostream>
#include <assert.h>
using namespace std;namespace wzf
{// 节点template <class T>struct list_node{list_node<T> *_prev;list_node<T> *_next;T _data;// 构造函数,创建链表list_node(const T &x = T()) // 用匿名对象做缺省值(调用默认构造),以存储收其他类型的元素: _next(nullptr), _prev(nullptr), _data(x){}};// 迭代器// // 1.iterator// template <class T>// struct __list_iterator// {//     typedef list_node<T> node;//     typedef __list_iterator<T> self;//     node *_node;//     __list_iterator(node *n)//         : _node(n)//     {//     }//     T &operator*()//     {//         return _node->_data;//     }//     self &operator++()//     {//         _node = _node->_next;//         return *this;//     }//     self &operator++(int) // 后置++//     {//         self tmp = *this;//         _node = _node->_next;//         return tmp;//     }//     self &operator--()//     {//         _node = _node->_prev;//         return *this;//     }//     self &operator--(int)//     {//         self tmp = *this;//         _node = _node->_prev;//         return tmp;//     }//     bool operator!=(const self &s)//     {//         return _node != s._node;//     }//     bool operator==(const self &s)//     {//         return _node == s._node;//     }// };// // 2.const_iterator// template <class T>// struct __list_const_iterator// {//     typedef list_node<T> node;//     typedef __list_const_iterator<T> self;//     node *_node;//     __list_const_iterator(node *n)//         : _node(n)//     {//     }//     const T &operator*() // 与1区别的地方,加const不能修改数据//     {//         return _node->_data;//     }//     self &operator++()//     {//         _node = _node->_next;//         return *this;//     }//     self &operator++(int) // 后置++//     {//         self tmp = *this;//         _node = _node->_next;//         return tmp;//     }//     self &operator--()//     {//         _node = _node->_prev;//         return *this;//     }//     self &operator--(int)//     {//         self tmp = *this;//         _node = _node->_prev;//         return tmp;//     }//     bool operator!=(const self &s)//     {//         return _node != s._node;//     }//     bool operator==(const self &s)//     {//         return _node == s._node;//     }// };// template <class T,class Ref>// struct __list_iterator// {//     typedef list_node<T> node;//     typedef __list_iterator<T,Ref> self;//     node *_node;//     __list_iterator(node *n)//         : _node(n)//     {//     }//     Ref &operator*()//     {//         return _node->_data;//     }//     self &operator++()//     {//         _node = _node->_next;//         return *this;//     }//     self &operator++(int)//     {//         self tmp = *this;//         _node = _node->_next;//         return tmp;//     }//     self &operator--()//     {//         _node = _node->_prev;//         return *this;//     }//     self &operator--(int) // 后置++//     {//         self tmp = *this;//         _node = _node->_prev;//         return tmp;//     }//     bool operator!=(const self &s)//     {//         return _node != s._node;//     }//     bool operator==(const self &s)//     {//         return _node == s._node;//     }// };// 迭代器template <class T, class Ref, class Ptr>struct __list_iterator{typedef list_node<T> node;typedef __list_iterator<T, Ref, Ptr> self;node *_node;__list_iterator(node *n): _node(n){}Ref &operator*(){return _node->_data;}Ptr operator->(){return &(_node->_data); // 取地址}self &operator++(){_node = _node->_next;return *this;}self &operator++(int){self tmp = *this;_node = _node->_next;return tmp;}self &operator--(){_node = _node->_prev;return *this;}self &operator--(int) // 后置--{self tmp = *this;_node = _node->_prev;return tmp;}bool operator!=(const self &s){return _node != s._node;}bool operator==(const self &s){return _node == s._node;}/*"const T&"表示迭代器所指向元素的引用类型,而"const T*"表示迭代器所指向元素的指针类型。这样定义迭代器的目的是为了在const成员函数中使用该迭代器,并保证在遍历列表时不会修改列表中的元素*/};template <class T>class list{typedef list_node<T> node;public:typedef __list_iterator<T, T &, T *> iterator;typedef __list_iterator<T, const T &, const T *> const_iterator;// typedef __list_const_iterator<T> const_iterator;iterator begin(){return iterator(_head->_next);}iterator end(){return iterator(_head);}const_iterator begin() const{return const_iterator(_head->_next);}const_iterator end() const{return const_iterator(_head);}void empty_init(){_head = new node;_head->_next = _head;_head->_prev = _head;}list(){empty_init();}// 构造函数, 迭代器区间template <class Iterator>list(const Iterator first, const Iterator last){empty_init(); // 创建头节点for (Iterator it = first; it != last; ++it)push_back(*it);}void swap(list<T> &temp){std::swap(_head, temp._head);}// 拷贝构造// lt2(lt1)// list(const list<T> &lt)// {//     empty_init();//     const_iterator it = lt.begin();//     while (it != lt.end())//     {//         push_back(*it);//         ++it;//     }// }list(const list<T> &lt){empty_init();list<T> temp(lt.begin(), lt.end());swap(temp);}// 赋值操作符// lt3=lt2// 不能使用&,而是传值调用拷贝构造,拷贝lt2,赋值给lt3list<T> &operator=(const list<T> lt){swap(lt);return *this;}~list(){clear();delete _head;_head = nullptr;}// 清除头节点以外的数据void clear(){iterator it = begin();while (it != end())it = erase(it); // erase(it++);//后置++返回的是前一个的拷贝,不会失效}// void push_back(const T &x)// {//     node *tail = _head->_prev;//     node *new_node = new node(x);//     tail->_next = new_node;//     new_node->_prev = tail;//     new_node->_next = _head;//     _head->_prev = new_node;// }void push_back(const T &x){insert(end(), x);}void push_front(const T &x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}void print_list(const list<T> &lt){cout << "---list---" << endl;// list<int>::const_iterator it = lt.begin();list<int>::const_iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl<< "---list---" << endl;}void insert(iterator pos, const T &x){node *cur = pos._node;   // .访问pos内的成员变量_nodenode *prev = cur->_prev; // ->访问指针所指向的节点的成员node *new_node = new node(x);prev->_next = new_node;new_node->_prev = prev;new_node->_next = cur;cur->_prev = new_node;}iterator erase(iterator pos){assert(pos != end());node *prev = pos._node->_prev;node *next = pos._node->_next;prev->_next = next;next->_prev = prev;delete pos._node;return iterator(next);}/*在该函数的最后一行,返回了一个迭代器对象 `iterator(next)`。这是因为在 C++ STL 中,通常情况下,删除一个元素后,我们希望返回删除元素的下一个位置作为新的迭代器。直接返回 `next` 的话,可能会暴露内部实现细节,使得用户可以直接操作指针 `next`,可能导致潜在的问题。为了隐藏底层指针的细节,通常会将其封装在迭代器对象中返回。因此,返回 `iterator(next)` 的方式可以提供更好的封装性和安全性,使用户能够使用迭代器对象来操作返回的下一个位置,而不需要直接访问底层的指针。这也符合 C++ STL 设计的一般原则,即通过迭代器提供统一的接口,隐藏底层的具体实现细节。*/private:node *_head; // ListNode<T>是类型 , ListNode是类名};void test_list1(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;lt.print_list(lt);}struct AA{int _a1;int _a2;AA(int a1 = 0, int a2 = 0): _a1(a1), _a2(a2){}};void test_list2(){list<AA> lt;lt.push_back(AA(1, 2));lt.push_back(AA(3, 4));lt.push_back(AA(5, 6));list<AA>::iterator it = lt.begin();while (it != lt.end()){cout << it->_a1 << " " << it._node->_data._a2 << endl;cout << it.operator->()->_a1 << " " << it.operator->()->_a2 << endl;cout << it.operator->() << endl<< endl; // 地址值++it;}}void test_list3(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;it = lt.begin();list<int>::iterator pos = lt.begin();++pos;lt.insert(pos, 20);lt.print_list(lt);cout << endl;}void test_list4(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.print_list(lt);cout << endl;lt.push_back(100);lt.push_front(99);lt.print_list(lt);cout << endl;lt.pop_back();lt.pop_front();lt.print_list(lt);cout << endl;}void test_list5(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.print_list(lt);cout << endl;lt.clear();lt.push_back(20);lt.print_list(lt);}void test_list6(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.print_list(lt);cout << endl;// list<int> lt2(lt);// lt2.print_list(lt2);// cout << endl;list<int> lt2 = lt;lt2.print_list(lt2);lt.print_list(lt);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/246227.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大型语言模型基础知识的可视化指南

直观分解复杂人工智能概念的工具和文章汇总 如今&#xff0c;LLM&#xff08;大型语言模型的缩写&#xff09;在全世界都很流行。没有一天不在宣布新的语言模型&#xff0c;这加剧了人们对错过人工智能领域的恐惧。然而&#xff0c;许多人仍在为 LLM 的基本概念而苦苦挣扎&…

python爬虫基础

python爬虫基础 前言 Python爬虫是一种通过编程自动化地获取互联网上的信息的技术。其原理可以分为以下几个步骤&#xff1a; 发送HTTP请求&#xff1a; 爬虫首先会通过HTTP或HTTPS协议向目标网站发送请求。这个请求包含了爬虫想要获取的信息&#xff0c;可以是网页的HTML内…

关于C#中的HashSet<T>与List<T>

HashSet<T> 表示值的集合。这个集合的元素是无须列表&#xff0c;同时元素不能重复。由于这个集合基于散列值&#xff0c;不能通过数组下标访问。 List<T> 表示可通过索引访问的对象的强类型列表。内部是用数组保存数据&#xff0c;不是链表。元素可重复&#xf…

如何利用streamlit 將 gemini pro vision 進行圖片內容介紹

如何利用streamlit 將 gemini pro vision 進行圖片內容介紹 1.安裝pip install google-generativeai 2.至 gemini pro 取 api key 3.撰寫如下文章:(方法一) import json import requests import base64 import streamlit as st 讀取圖片檔案&#xff0c;並轉換成 Base64 編…

mysql 存储过程学习

存储过程介绍 1.1 SQL指令执行过程 从SQL执行的流程中我们分析存在的问题: 1.如果我们需要重复多次执行相同的SQL&#xff0c;SQL执行都需要通过连接传递到MySQL&#xff0c;并且需要经过编译和执行的步骤; 2.如果我们需要执行多个SQL指令&#xff0c;并且第二个SQL指令需要…

145基于matlab的求解悬臂梁前3阶固有频率和振型

基于matlab的求解悬臂梁前3阶固有频率和振型,采用的方法分别是&#xff08;假设模态法&#xff0c;解析法&#xff0c;瑞利里兹法&#xff09;。程序已调通&#xff0c;可直接运行。 145 matlab 悬臂梁 固有频率 振型 (xiaohongshu.com)

Linux 驱动开发基础知识—— LED 驱动程序框架(四)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

[嵌入式软件][启蒙篇][仿真平台] STM32F103实现IIC控制OLED屏幕

上一篇&#xff1a;[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键 [嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集 [嵌入式软件][启蒙篇][仿真平台]STM32F103实现定时器 [嵌入式软件][启蒙篇][仿真平台] STM32F103实现IIC控制OLED屏幕 文章目…

DS:单链表的实现(超详细!!)

创作不易&#xff0c;友友们点个三连吧&#xff01; 在博主的上一篇文章中&#xff0c;很详细地介绍了顺序表实现的过程以及如何去书写代码&#xff0c;如果没看过的友友们建议先去看看哦&#xff01; DS&#xff1a;顺序表的实现&#xff08;超详细&#xff01;&#xff01;&…

上位机图像处理和嵌入式模块部署(python opencv)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们谈到了qt&#xff0c;谈到了opencv&#xff0c;也谈到了嵌入式&#xff0c;但是没有说明python在这个过程当中应该扮演什么样的角色。open…

风口抓猪-借助亚马逊云科技EC2服务器即刻构建PalWorld(幻兽帕鲁)私服~~~持续更新中

Pocketpair出品的生存类游戏《幻兽帕鲁》最近非常火&#xff0c;最高在线人数已逼近200万。官方服务器亚历山大&#xff0c;游戏开发商也提供了搭建私人专用服务器的方案&#xff0c;既可以保证稳定的游戏体验&#xff0c;也可以和朋友一起联机游戏&#xff0c;而且还能自定义经…

Websocket协议详解

前言 本文主要介绍Websocket是什么以及其协议内容。 WebSocket 协议实现在受控环境中运行不受信任代码的一个客户端到一个从该代码已经选择加入通信的远程主机之间的全双工通信。该协议包括一个打开阶段握手规定以及通信时基本消息帧的定义。其基于TCP之上。此技术的目标是为基…

分布式因果推断在美团履约平台的探索与实践

美团履约平台技术部在因果推断领域持续的探索和实践中&#xff0c;自研了一系列分布式的工具。本文重点介绍了分布式因果树算法的实现&#xff0c;并系统地阐述如何设计实现一种分布式因果树算法&#xff0c;以及因果效应评估方面qini_curve/qini_score的不足与应对技巧。希望能…

基于机器学习的地震预测(Earthquake Prediction with Machine Learning)

基于机器学习的地震预测&#xff08;Earthquake Prediction with Machine Learning&#xff09; 一、地震是什么二、数据组三、使用的工具和库四、预测要求五、机器学习进行地震检测的步骤六、总结 一、地震是什么 地震几乎是每个人都听说过或经历过的事情。地震基本上是一种自…

浪花 - 响应拦截器(强制登录)

1. 配置响应拦截器 import axios from axios;const myAxios axios.create({baseURL: http://localhost:8080/api/, });myAxios.defaults.withCredentials true;// 请求拦截器 myAxios.interceptors.request.use(function (config) {// Do something before request is sentc…

ubuntu设置右键打开terminator、code

前言&#xff1a; 这里介绍一种直接右键打开本地目录下的terminator和vscode的方法。 一&#xff1a;右键打开terminator 1.安装terminator sudo apt install terminator 2.安装nautilus-actions filemanager-actions sudo apt-get install nautilus-actions filemanager…

【小白教程】幻兽帕鲁服务器一键搭建 | 支持更新 | 自定义配置

幻兽帕鲁刚上线就百万在线人数&#xff0c;官方服务器的又经常不稳定&#xff0c;所以这里给大家带来最快捷的搭建教程&#xff0c;废话不多说直接开始。 步骤一&#xff1a;准备服务器 服务器建议 Linux 系统&#xff0c;资源占用低&#xff0c;而且一键脚本只需要一条命令&am…

如何使用宝塔面板配置Nginx反向代理WebSocket(wss)

本章教程&#xff0c;主要介绍一下在宝塔面板中如何配置websocket wss的具体过程。 目录 一、添加站点 二、申请证书 三、配置代理 1、增加配置内容 2、代理配置内容 三、注意事项 一、添加站点 二、申请证书 三、配置代理 1、增加配置内容 map $http_upgrade $connection_…

【TCP】传输控制协议

前言 TCP&#xff08;Transmission Control Protocol&#xff09;即传输控制协议&#xff0c;是一种面向连接的、可靠的、基于字节流的传输层通信协议。它由IETF的RFC 793定义&#xff0c;为互联网中的数据通信提供了稳定的传输机制。TCP在不可靠的IP层之上实现了数据传输的可…

常见电源电路(LDO、非隔离拓扑和隔离拓扑结构)

一、常见电路元件和符号 二、DC-DC转换器 DC-DC转换器&#xff1a;即直流-直流转换器&#xff0c;分为三类&#xff1a;①线性调节器&#xff1b;②电容性开关解调器&#xff1b;③电感性开关调节器&#xff1b; 2.1线性稳压器&#xff08;LDO&#xff09; 2.1.1 NMOS LDO…