c++ - c++11(1)

文章目录

  • 前言
    • 一、统一的列表初始化
      • 1、使用{ }初始化
      • 2、 std::initializer_list
    • 二、声明
      • 1、auto
      • 2、decltype
      • 3、nullptr
    • 三、范围for循环
    • 四、右值引用
      • 1、左值引用和右值引用
      • 2、左值引用和右值引用的比较
      • 3、左值引用的使用场景
      • 4、右值引用的使用场景
      • 5、完美转发


前言


一、统一的列表初始化

1、使用{ }初始化

(1)概念

C++11扩大了用大括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义的类型,使用初始化列表时,可添加等号(=),也可不添加。

(2)演示:

//日期类
class Date
{
public:Date(int year = 1,int month = 1,int day = 1):_year(year),_month(month),_day(day){}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};//统一的列表初始化
void test01()
{//对一个数组int arr[] = { 1,2,3,4,5 };//也可以将等号舍去 int arr[]{ 1,2,3,4,5 };cout << "arr: ";for (auto& e : arr)cout << e << " ";cout << endl;//对一个对组pair<int, int> p = { 1,1 };//p{1,1}cout << "p: ";cout << p.first << " " << p.second << endl;//对一个变量int a = { 1 };//a{1}cout << "a: ";cout << a << endl;//自定义类型Date d = { 1,2,3 };//Date d{1,2,3}cout << "d: ";d.Print();
}

在这里插入图片描述

2、 std::initializer_list

(1)介绍
在这里插入图片描述

(1)此类型用于访问 C++ 初始化列表中的值,该列表是 const T 类型的元素列表。
(2)这种类型的对象是由编译器根据初始化列表声明自动构造的,该定义列表声明是用大括号括起来的逗号分隔的元素列表:auto il = { 10, 20, 30 }; //IL 的类型是initializer_list
(3)具体了解: std::initializer_list

(2)使用场景

std::initializer_list一般是作为构造函数的参数,C++11对STL中的不少容器就增加std::initializer_list作为参数的构造函数,这样初始化容器对象就更方便了。
在这里插入图片描述
也可以作为operator=的参数,这样就可以用大括号赋值。
在这里插入图片描述
(3)演示:

//std::initializer_list
void test02()
{//直接使用initializer_list<int> ls = { 1,2,3,4,5};cout << "ls: ";for (auto e : ls)cout << e << " ";cout << endl;//作为参数使用//隐式类型转化为initializer_list类型再使用构造函数构造vector<int> arr = { 1,2,3,4,5 };	cout << "arr: ";for (auto e : arr)cout << e << " ";cout << endl;
}

(4)注意
在这里插入图片描述

二、声明

1、auto

(1)介绍

在C++98中auto是一个存储类型的说明符,表明变量是局部自动存储类型,但是局部域中定义局部的变量默认就是自动存储类型,所以auto就没什么价值了。C++11中废弃auto原来的用法,将 其用于实现自动类型腿断。这样要求必须进行显示初始化,让编译器将定义对象的类型设置为初 始化值的类型。
注意:在C++中,auto 关键字不能直接用作函数参数的类型声明。auto 的设计初衷是用于自动类型推导,但仅限于在编译时能够根据初始化表达式确定类型的上下文中,如局部变量声明、for 循环的初始化表达式等。函数参数的类型必须在编译时就已经明确,因为函数声明和定义必须清晰地指明其接受哪些类型的参数,以便编译器进行类型检查和函数重载解析。

(2)演示:

//作为函数返回值
auto func()
{//推导为intreturn 1;
}void test03()
{//自动推导内置类型auto a = 10;cout << "a:" << a << endl;//自动推导自定义类型auto b = Date(1, 1, 1);cout << "b:";b.Print();//推导复杂的类型vector<int> arr = {1,2,3};//vector<int>::iterator = arr.begin();auto c = arr.begin();cout << "c:" << *c << endl;//作为返回值auto d = func();cout << typeid(d).name() << endl;
}

2、decltype

(1)介绍

关键字decltype将变量的类型声明为表达式指定的类型。

(2)演示

//通过模板类型推导类型
template<class T1, class T2>
void func02(T1 t1, T2 t2)
{//通过t1*t2的结果类型来声明decltype(t1 * t2) p3;cout << "p3:" << typeid(p3).name() << endl;
}void test04()
{//通过a*b的表达式的类型来声明ret的类型int a = 10;int b = 10;double c = 1.1;//通过a*b的结果类型来声明decltype(a * b) p1;//通过a*c的结果类型来声明decltype(a * c) p2;cout << "p1:" << typeid(p1).name() << endl;cout << "p2:" << typeid(p2).name() << endl;func02(1, 1);
}

3、nullptr

(1)介绍

由于C++中NULL被定义成字面量0,这样就可能回带来一些问题,因为0既能指针常量,又能表示
整形常量。所以出于清晰和安全的角度考虑,C++11中新增了nullptr,用于表示空指针。

(2)演示

//整形类型
void func03(int a)
{cout << "void func03(int a)" << endl;
}//重载
//指针类型
void func03(void* a)
{cout << "void func03(void* a)" << endl;
}void test05()
{func03(0);func03(NULL);func03(nullptr);
}

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/48e3cbb09ddc44ec84b85101a432de80.png

上述出现了NULL也调用整形重载函数,出现了误用的情况,而使用nullptr就不会出现误用的情况,所以使用空指针时建议使用nullptr

三、范围for循环

1、介绍

C++11 引入了范围 for 循环(Range-based for loop),也被称为基于范围的 for 循环,它提供了一种更加简洁和直观的方式来遍历容器(如数组、向量 std::vector、列表 std::list、字符串等)中的元素。这种循环方式不仅减少了代码量,还提高了代码的可读性和可维护性。

2、语法

for (declaration : expression)  statement

declaration:定义了一个变量,用于在每次迭代中存储容器中的当前元素。这个变量的类型会自动根据容器的元素类型推导出来(需要C++11 的自动类型推导功能auto)。
expression:表示一个容器(如数组、向量、字符串等),或者是一个可以返回迭代器对的表达式(如begin() 和 end() 成员函数)。
statement:在每次迭代中执行的代码块。

3、演示

//范围for
void test06()
{//遍历数组int arr[] = { 1,2,3,4.5 };cout << "arr: ";for (auto e : arr)//auto &e 取引用{cout << e << " ";}cout << endl;//遍历vector容器vector<int> v = { 1,2,3,4,5 };cout << "v: ";for(auto &e:v){cout << e << " ";}cout << endl;
}

在这里插入图片描述

四、右值引用

1、左值引用和右值引用

传统的C++语法中就有引用的语法,而C++11中新增了的右值引用语法特性,之前学习的引用就叫做左值引用。无论左值引用还是右值引用,都是给对象取别名。

(1)什么是左值、什么是左值引用

左值是一个表示数据的表达式(如变量名或解引用的指针),我们可以获取它的地址+可以对它赋值,左值可以出现赋值符号的左边,右值不能出现在赋值符号左边。定义时const修饰符后的左值,不能给他赋值,但是可以取它的地址。左值引就是给左值的引用,给左值取别名。

//左值
void test07()
{int a = 10;int* b = new int(10);const int c = 10;//以上abc都是左值//下面对左值取引用int& la = a;int*& lb = b;const int& lc = c;
}

(2)什么是右值、什么是右值引用

右值也是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值(这个不能是左值引用返回)等等,右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,右值不能取地址。右值引用(&&)就是对右值的引用,给右值取别名。

//右值
int func04()
{return 1;
}void test08()
{int x = 10, y = 10;//下面是右值1;x + y;func04();//对右值取引用int&& a = 10;int&& b = x + y;int&& c = func04();
}

2、左值引用和右值引用的比较

(1)左值引用不能引用右值,但是加const修饰的左值引用能引用右值。
(2)右值引用不能引用左值,但是通过move(将左值强制转化为右值)左值,就能被右值引用了。

void test09()
{	//err//int& a = 10;	左值引用不能引用右值const int& a = 10;	//加const修饰后就可引用右值了//errint b = 10;//int&& c = b;	//右值引用不能引用左值int&& c = move(b);//通过move后就可以引用左值了
}

3、左值引用的使用场景

一般作为参数和作为返回值,这样减少拷贝来提高效率。

//返回值:值返回
//参数:值传递
string func05(string s)
{return s;
}
//返回值:引用返回
//参数:引用传递
string& func06(string& s)
{return s;
}void test10()
{string s = "abc";string s1 = func05(s);	//调用值传递版本string s2 = func06(s);	//调用引用传递版本
}

在这里插入图片描述

4、右值引用的使用场景

(1)右值引用的作用:

移动语义:允许对象以更高效的方式传递其资源(如动态分配的内存、文件句柄等),而不是复制它们。当一个对象通过右值引用传递给函数时,该函数可以“窃取”对象的资源,避免不必要的复制,然后将其状态设置为安全可析构的状态(如空指针、零大小等)。

(1)实现移动拷贝构造和移动赋值重载
对下面链表增加移动拷贝构造和移动赋值重载

list.h

namespace xu
{// List的结点类template<class T>struct ListNode{ListNode<T>* _pPre; //后继指针ListNode<T>* _pNext; //前驱指针T _val; //数据//构造结点ListNode(const T& val = T()) :_val(val), _pPre(nullptr), _pNext(nullptr){}};//List的正向迭代器类//Ref为T& Ptr为T*template<class T, class Ref, class Ptr>class ListIterator{typedef ListNode<T>* PNode;typedef ListIterator<T, Ref, Ptr> Self;public://构造函数 ,获取一个结点指针ListIterator(const PNode & pNode = nullptr, const PNode& const P = nullptr) :_pNode(pNode),_P(P){}Ref operator*(){assert(_P != _pNode);return _pNode->_val;}Ptr operator->(){return &(operator*());}Self& operator++(){_pNode = _pNode->_pNext;return *this;}Self operator++(int){Self tmp(_pNode);_pNode = _pNode->_pNext;return tmp;}Self& operator--(){_pNode = _pNode->_pPre;return *this;}Self& operator--(int){Self tmp(_pNode);_pNode = _pNode->_pPre;return tmp;}bool operator!=(const Self& l){return l._pNode != _pNode;}bool operator==(const Self& l){return l._pNode == _pNode;}PNode get(){return _pNode;}private:PNode _pNode;PNode _P;};//List的反向迭代器类template<class T, class Ref, class Ptr>class Reverse_ListIterator{typedef ListNode<T>* PNode;typedef Reverse_ListIterator<T, Ref, Ptr> Self;public:Reverse_ListIterator(const PNode& pNode = nullptr, const PNode& const P = nullptr) :_pNode(pNode), _P(P){}Ref operator*(){assert(_P != _pNode ->_pPre);return _pNode->_pPre->_val;}Ptr operator->(){return &(operator*());}Self& operator++(){_pNode = _pNode->_pPre;return *this;}Self operator++(int){Self tmp(_pNode);_pNode = _pNode->_pPre;return tmp;}Self& operator--(){_pNode = _pNode->_pNext;}Self& operator--(int){Self tmp(_pNode);_pNode = _pNode->_pNext;return tmp;}bool operator!=(const Self& l){return l._pNode != _pNode;}bool operator==(const Self& l){return l._pNode == _pNode;}PNode get(){return _pNode;}private:PNode _pNode;PNode _P;};//list类template<class T>class list{typedef ListNode<T> Node;typedef Node* PNode;public:typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&, const T*> const_iterator;typedef Reverse_ListIterator<T, T&, T*> reverse_iterator;typedef Reverse_ListIterator<T, const T&, const T*> reverse_const_iterator;public://默认构造list() {   //构造一个哨兵位结点CreateHead(); }list(int n, const T& value = T()){//构造一个哨兵位结点CreateHead();//将元素尾插入while (n != 0){push_back(value);--n;}}template <class Iterator>list(Iterator first, Iterator last){//构造一个哨兵位结点CreateHead();//将元素尾插入while (first != last){push_back(*first);++first;}}//拷贝构造list(const list<T>& l){//构造一个哨兵位结点CreateHead();//遍历+将元素尾插入PNode tmp = l._pHead->_pNext;while (tmp != l._pHead){//尾插push_back(tmp->_val);tmp = tmp->_pNext;}cout << " list(const list<T>& l)" << endl;}list<T>& operator=(const list<T>& l){//清空原链表clear();//遍历+将元素尾插入PNode tmp = l._pHead->_pNext;while (tmp != l._pHead){push_back(tmp->_val);tmp = tmp->_pNext;}return *this;}~list(){//清空链表clear();//删除哨兵位结点delete _pHead;_pHead = nullptr;}///// List Iteratoriterator begin(){return iterator(_pHead->_pNext, _pHead);}iterator end(){return iterator(_pHead, _pHead);}const_iterator begin() const{return const_iterator(_pHead->_pNext, _pHead);}const_iterator end()const{return const_iterator(_pHead, _pHead);}reverse_iterator rbegin(){return reverse_iterator(_pHead, _pHead);}reverse_iterator rend(){return reverse_iterator(_pHead ->_pNext, _pHead);}reverse_const_iterator rbegin() const{return reverse_const_iterator(_pHead, _pHead);}reverse_const_iterator rend()const{return reverse_const_iterator(_pHead->_pNext, _pHead);}size_t size()const{PNode tmp = _pHead->_pNext;size_t count = 0;while (tmp != _pHead){tmp = tmp->_pNext;++count;}return count;}bool empty()const{return _pHead == _pHead->_pNext;}// List AccessT& front(){assert(!empty());return _pHead->_pNext->_val;}const T& front()const{assert(!empty());return _pHead->_pNext->_val;}T& back(){assert(!empty());return _pHead->_pPre->_val;}const T& back()const{assert(!empty());return _pHead->_pPre->_val;}// List Modifyvoid push_back(const T & val) { insert(end(), val); }void pop_back() { erase(--end()); }void push_front(const T & val) { insert(begin(), val); }void pop_front() { erase(begin()); }// 在pos位置前插入值为val的节点iterator insert(iterator pos, const T & val){//创造一个结点PNode tmp = new Node(val);//获取迭代器中的指针PNode _pos = pos.get();//进行插入PNode prv = _pos->_pPre;prv->_pNext = tmp;tmp->_pPre = prv;tmp->_pNext = _pos;_pos->_pPre = tmp;//返回新迭代器return iterator(tmp);}// 删除pos位置的节点,返回该节点的下一个位置iterator erase(iterator pos){//判断是否为哨兵位结点iterator it = end();assert(pos != it);//获取迭代器结点指针PNode tmp = pos.get();//进行删除PNode next = tmp->_pNext;PNode prv = tmp->_pPre;prv->_pNext = next;next->_pPre = prv;delete tmp;tmp = nullptr;//返回被删除结点的下一个位置的结点迭代器return iterator(next);}void clear(){//保存有效结点位置PNode tmp = _pHead->_pNext;//遍历删除while (tmp != _pHead){PNode p = tmp->_pNext;delete tmp;tmp = p;}//重新指向_pHead->_pNext = _pHead;_pHead->_pPre = _pHead;}void swap(list<T>& l){std::swap(_pHead, l._pHead);}private://让哨兵位结点指向自己void CreateHead(){_pHead = new  Node;_pHead->_pNext = _pHead;_pHead->_pPre = _pHead;}PNode _pHead;   //哨兵位结点};};

实现移动拷贝构造

//移动拷贝
list(list<T>&& l):_pHead(nullptr)
{//构造一个哨兵位结点CreateHead();//交换链表头节点std::swap(_pHead, l._pHead);cout << " list(list<T>&& l):_pHead(nullptr)" << endl;
}

移动拷贝构造和普通拷贝构造比较
在传右值时是调用移动拷贝构造,在传左值时是调用普通拷贝构造。
场景1:
用右值传参时,分别普通拷贝构造和移动拷贝构造的效率比较。
在这里插入图片描述
场景2:
用左值传参,分别调用移动拷贝构造(通过move来转化)、普通拷贝构造。
在这里插入图片描述

实现移动赋值重载

list<T>& operator=(list<T>&& l)
{//清空原链表clear();std::swap(_pHead, l._pHead);return *this;
}

移动赋值重载构造和赋值重载比较:与移动拷贝构造和普通拷贝构造类似。

(2)当需要返回局部变量引用时,通过左值引用返回的话,可能会造成访问已经销毁的空间。此时只能使用传值返回了,传值返回的临时变量是右值,如果存在移动拷贝构造,则会调用移动拷贝构造,这样就会提高效率。

//返回左值引用可能造成访问冲突
//err
string & func07()
{string ret = "abc";return ret;
}
//传值返回
string  func07()
{string ret = "abc";return ret;
}
//
void   func08()
{string ret = func07();
}

在这里插入图片描述

5、完美转发

(1)万能引用

(1)、在模板中&& 不是作为右值引用,而是作为万能引用,即可以引用右值也能够引用左值。
(2)、模板的万能引用只是提供了能够接收同时接收左值引用和右值引用的能力,但是引用类型的唯一作用就是限制了接收的类型,后续使用中都退化成了左值,我们希望能够在传递过程中保持它的左值或者右值的属性, 就需要用我们下面学习的完美转发

template<typename T>
void func08(T && t)	//万能引用
{
}

(2)完美转化
std::forward 完美转发在传参的过程中保留对象原生类型属性。

//左值引用
void func09(const int &a)
{cout << "void func09(const int &a)" << endl;
}//右值引用
void func09(int &&a)
{cout << " void func10(int &&a)" << endl;
}template<typename T>
void func08(T && t)
{func09(std::forward<T>(t));
}void test12()
{int a = 10;//左值func08(a);//右值func08(10);
}

在这里插入图片描述
(3)运用完美转发实现链表尾插右值引用版本

void push_back(T&& val)
{ insert(end(), std::forward<T>(val));
}// 在pos位置前插入值为val的节点
iterator insert(iterator pos, T&& val)
{//创造一个结点PNode tmp = new Node(val);//获取迭代器中的指针PNode _pos = pos.get();//进行插入PNode prv = _pos->_pPre;prv->_pNext = tmp;tmp->_pPre = prv;tmp->_pNext = _pos;_pos->_pPre = tmp;//返回新迭代器return iterator(tmp);
}

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

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

相关文章

Python爬虫入门实战(详细步骤)

1. 技术选型 爬虫这个功能&#xff0c;我个人理解是什么语言都能写的&#xff0c;只要能正常发送 HTTP 请求&#xff0c;将响应回来的静态页面模版 HTML 上把我们所需要的数据提取出来就可以了&#xff0c;原理很简单&#xff0c;这个东西当然可以手动去统计收集&#xff0c;但…

【C语言】预处理详解(上)

文章目录 前言1. 预定义符号2. #define 定义常量3. #define定义宏4. 带有副作用的宏参数5. 宏替换的规则 前言 在讲解编译和链接的知识点中&#xff0c;我提到过翻译环境中主要由编译和链接两大部分所组成。 其中&#xff0c;编译又包括了预处理、编译和汇编。当时&#xff0c…

【准则化的思想】变异测试的真正价值

下面我们来讨论变异充分准则。这个准则&#xff0c;同样是一种基于缺陷的充分准则&#xff0c;但是跟我们前面讨论过的准则相比&#xff0c;思路又完全不同。我们来具体看一看。 首先&#xff0c;它为什么叫“变异”充分准则呢&#xff1f;我们通常说的变异&#xff0c;指的是…

【0304】psql 执行“VACUUM FULL”命令的背后实现过程

1. 概述 在前面讲解Postgres内核中解析器相关(【0297】Postgres内核之 INSERT INTO 原始解析树 转 Query 树 (1))内容时,曾提到过,Postgres内核大致将用户下发的SQL语句分为三大类,这里的VACUUM FULL属于CMD_UTILITY; 因此直接调用utility.c(实用程序)中的对应函数。…

SQL Server Management Studio的使用

之前在 https://blog.csdn.net/fengbingchun/article/details/140961550 介绍了在Windows10上安装SQL Server 2022 Express和SSMS&#xff0c;这里整理下SSMS的简单使用&#xff1a; SQL Server Management Studio(SSMS)是一种集成环境&#xff0c;提供用于配置、监视和管理SQL…

微信小程序【五】摇骰子

摇骰子 一、dice.js二、dice.json三、dice.wxml四、dice.wxss 效果简述&#xff1a;点击设置“骰子个数”&#xff0c;喝一杯前&#xff0c;先摇一摇。 骰子图片命名示例&#xff1a; 1.png、2.png 一、dice.js Page({data: {numDice: 1, // 初始化骰子数diceImages: [],dic…

Redis进阶(四):哨兵

为了解决主节点故障&#xff0c;需要人工操作切换主从的情况&#xff1b;因此需要一种方法可以自动化的切换&#xff1a;哨兵的引入大大改变这种情况。 哨兵的基本概念 自动切换主从节点 哨兵架构 1、当一个哨兵节点发现主节点挂了的时候&#xff0c;还需要其他节点也去检测一…

新华三H3CNE网络工程师认证—进制转换

了解进制转换&#xff0c;先要了解一下IP地址与子网划分&#xff0c;在我们通信当中&#xff0c;每一层都有它的标识&#xff0c;网络层的标识一共有两类协议&#xff0c;一个是IP协议&#xff0c;一个是IPv6协议。IP地址和MAC地址&#xff0c;他们之间是有一些区别。IP地址在网…

07.FreeRTOS列表与列表项

文章目录 07. FreeRTOS列表与列表项1. 列表和列表项的简介2. 列表相关API函数3. 代码验证 07. FreeRTOS列表与列表项 1. 列表和列表项的简介 列表的定义&#xff1a; typedef struct xLIST {listFIRST_LIST_INTEGRITY_CHECK_VALUE /* 校验值 */volatile UBaseType_t uxN…

在百度飞浆中搭建pytorch环境

文章目录 1 先检查创建的环境2 创建虚拟环境3 最终结果 1 先检查创建的环境 选择GPU版本 检查python版本 2 创建虚拟环境 虚拟环境的创建 python3 -m venv env_name # (python3 -m 路径 环境名)激活虚拟环境 source env_name/bin/activate这里注意&#xff0c;同名文件…

sqli靶场复现(1-8关)

目录 1.sqli-labs第二关 1.判断是否存在sql注入 1.1你输入数字值的ID作为参数&#xff0c;我们输入?id1 1.2在数据库可以查看到users下的对应内容 2.联合注入 2.1首先知道表格有几列&#xff0c;如果报错就是超过列数&#xff0c;如果显示正常就是没有超出列数。 2.2得…

PHP全方位多功能投票小程序系统源码

&#x1f31f;【全民参与&#xff0c;决策更精彩】全方位多功能投票小程序大揭秘&#xff01;&#x1f389; &#x1f680; 开篇引入&#xff1a;投票新风尚&#xff0c;尽在指尖 Hey小伙伴们&#xff0c;你是否厌倦了传统的投票方式&#xff0c;觉得它们既繁琐又不够灵活&am…

IO进程----标准IO

目录 IO进程 标准IO 1. 概念&#xff1a; 2. 特点&#xff1a; 3. 缓存区 3.1. 行缓存&#xff1a;和终端操作相关 刷新缓存的条件&#xff1a; 1) 程序正常退出 2) \n刷新 3) 缓存区满刷新 4) 强制刷新 fflush 3.2. 全缓存&#xff1a;和文件操作相关 3.…

sqli-labs闯关1-4

第一关&#xff1a; 这里的输入了 &#xff1f;id1 意思是以GET方式传入id1的参数 就等于SELECT * FROM users WHERE id1 LIMIT 0,1 注意&#xff1a;-- 与-- 空格的区别 在url中输入了--以后&#xff0c;后端数据会变成--空格。在 url中输入 -- 空格 变成 -- 在mysql中&…

使用Go语言实现基于泛型的Jaccard相似度算法

基本原理 跳表&#xff1a; jaccard相似度&#xff1a; jaccard相似度的代码实现&#xff1a; 时间复杂度分析&#xff1a; 快速jaccard算法&#xff1a; 代码实现&#xff0c;这个要求两个集合都是有序的&#xff1a; Jaccard相似度算法的基本实现 算法&#xf…

LeetCode Hot100 排序链表

给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4]示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出&#xff1a;[-1,0,3,4,5]示例 3&#xff1a; 输…

工程技术人员职称专业一览表,赶紧收藏!有助评职称、落户

现在很多地区为了引进人才&#xff0c;都会对各类获得中级或高级职称的人才提供一系列优惠政策&#xff0c;比如人才补贴、职称入户等等。 下面小编就来为大家介绍一下中级职称专业一览表&#xff0c;告诉你能以考代评的几个考试&#xff0c;需要评职称、落户的快看过来&#…

【秋招突围】2024届秋招-京东笔试题-第二套

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 编程一对一辅导 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍭 本次给大家…

PXE:Kickstart自动化安装Linux系统

PXE&#xff1a;工作在 Client/Server模式&#xff0c;允许客户机通过网络从远程服务器下载引导镜像&#xff0c;并加载安装文件或者整个操作系统。 运行 PXE协议需要设置&#xff1a;DHCP服务器和TFTP服务器。DHCP服务器用来给 PXE client&#xff08;将要安装系统的主机&…

【C++二分查找 决策包容性】1300. 转变数组后最接近目标值的数组和

本文涉及的基础知识点 C二分查找 决策包容性 LeetCode1300. 转变数组后最接近目标值的数组和 给你一个整数数组 arr 和一个目标值 target &#xff0c;请你返回一个整数 value &#xff0c;使得将数组中所有大于 value 的值变成 value 后&#xff0c;数组的和最接近 target …