C++学习笔记(8)

embedded/2024/9/20 1:24:54/ 标签: c++, 学习, 笔记

184、基于范围的 for 循环
对于一个有范围的集合来说,在程序代码中指定循环的范围有时候是多余的,还可能犯错误。
C++11 中引入了基于范围的 for 循环。
语法:
for (迭代的变量 : 迭代的范围)
{
// 循环体。
}
注意:
1)迭代的范围可以是数组名、容器名、初始化列表或者可迭代的对象(支持 begin()、end()、++、
==)。
2)数组名传入函数后,已退化成指针,不能作为容器名。
3)如果容器中的元素是结构体和类,迭代器变量应该申明为引用,加 const 约束表示只读。
4)注意迭代器失效的问题。
示例:
#include <iostream>
#include <vector>
using namespace std;
class AA
{
public:
string m_name;
AA() { cout << "默认构造函数 AA()。\n"; }
AA(const string& name) : m_name(name) { cout << "构造函数,name=" << m_name <<
"。\n"; }
AA(const AA& a) : m_name(a.m_name) { cout << "拷贝构造函数,name=" << m_name <<
"。\n"; }
AA& operator=(const AA& a) { m_name = a.m_name; cout << "赋值函数,name=" <<
m_name << "。\n"; return *this; } ~AA() { cout << "析构函数,name=" << m_name<<"。\n"; }
};
int main()
{
vector<int> vv = { 1,2,3,4,5,6,7,8,9,10 };
//for (auto it = vv.begin(); it != vv.end(); it++) // 用迭代器遍历容器 vv。
//{
// cout << *it << " ";
//}
//cout << endl;
for (auto val : vv) // 用基于范围的 for 循环遍历数组 vv。
{
cout << val << " ";
vv.push_back(10);
}
cout << endl;
/*vector<AA> v;
cout << "1111,v.capacity()=" << v.capacity() << "\n";
v.emplace_back("西施");
cout << "2222,v.capacity()=" << v.capacity() << "\n";
v.emplace_back("冰冰");
cout << "3333,v.capacity()=" << v.capacity() << "\n";
v.emplace_back("幂幂");
cout << "4444,v.capacity()=" << v.capacity() << "\n";
for (const auto &a : v)
cout << a.m_name << " ";
cout << endl;*/
}
185、list 容器
list 容器封装了双链表。
包含头文件: #include<list>
list 类模板的声明:
template<class T, class Alloc = allocator<T>>
class list{
private:
iterator head;
iterator tail; ……
} 一、构造函数
1)list(); // 创建一个空的 list 容器。
2)list(initializer_list<T> il); // 使用统一初始化列表。
3)list(const list<T>& l); // 拷贝构造函数。
4)list(Iterator first, Iterator last); // 用迭代器创建 list 容器。
5)list(list<T>&& l); // 移动构造函数(C++11 标准)。
6)explicit list(const size_t n); // 创建 list 容器,元素个数为 n。
7)list(const size_t n, const T& value); // 创建 list 容器,元素个数为 n,值均为 value。
析构函数~list()释放内存空间。
示例:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main()
{
// 1)list(); // 创建一个空的 list 容器。
list<int> l1;
// cout << "li.capacity()=" << l1.capacity() << endl; // 链表没有容量说法。
cout << "li.size()=" << l1.size() << endl;
// 2)list(initializer_list<T> il); // 使用统一初始化列表。
list<int> l2({ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });
// list<int> l2={ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// list<int> l2 { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
for (int value : l2) // 用基于范围的 for 循环遍历容器。
cout << value << " ";
cout << endl;
// 3)list(const list<T>& l); // 拷贝构造函数。
list<int> l3(l2);
// list<int> l3=l2;
for (int value : l3)
cout << value << " ";
cout << endl;
// 4)list(Iterator first, Iterator last); // 用迭代器创建 list 容器。
list<int> l4(l3.begin(), l3.end()); // 用 list 容器的迭代器。
for (int value : l4)
cout << value << " ";
cout << endl;
vector<int> v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 创建 vector 容器。
list<int> l5(v1.begin() + 2, v1.end() - 3); // 用 vector 容器的迭代器创建 list 容器。
for (int value : l5)
cout << value << " ";
cout << endl;
int a1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 创建数组。
list<int> l6(a1 + 2, a1 + 10 - 3); // 用数组的指针作为迭代器创建 list 容器。
for (int value : l6)
cout << value << " ";
cout << endl;
char str[] = "hello world"; // 定义 C 风格字符串。
string s1(str + 1, str + 7); // 用 C 风格字符串创建 string 容器。
for (auto value : s1) // 遍历 string 容器。
cout << value << " ";
cout << endl;
cout << s1 << endl; // 以字符串的方式显示 string 容器。
vector<int> v2(l3.begin(), l3.end()); // 用 list 迭代器创建 vector 容器。
for (auto value : v2) // 遍历 vector 容器。
cout << value << " ";
cout << endl;
}
二、特性操作
size_t max_size() const; // 返回容器的最大长度,此函数意义不大。
size_t size() const; // 返回容器的实际大小(已使用的空间)。
bool empty() const; // 判断容器是否为空。
void clear(); // 清空容器。
void resize(size_t size); // 把容器的实际大小置为 size。
void resize(size_t size,const T &value); // 把容器的实际大小置为 size,如果 size<实际大小,
会截断多出的部分;如果 size>实际大小,就用 value 填充。 三、元素操作
T &front(); // 第一个元素。
const T &front(); // 第一个元素,只读。
const T &back(); // 最后一个元素,只读。
T &back(); // 最后一个元素。 四、赋值操作
给已存在的容器赋值,将覆盖容器中原有的内容。
1)list &operator=(const list<T> &l); // 把容器 l 赋值给当前容器。
2)list &operator=(initializer_list<T> il); // 用统一初始化列表给当前容器赋值。
3)list assign(initializer_list<T> il); // 使用统一初始化列表赋值。
4)list assign(Iterator first, Iterator last); // 用迭代器赋值。
5)void assign(const size_t n, const T& value); // 把 n 个 value 给容器赋值。 五、交换、反转、排序、归并
void swap(list<T> &l); // 把当前容器与 l 交换,交换的是链表结点的地址。
void reverse(); // 反转链表。
void sort(); // 对容器中的元素进行升序排序。
void sort(_Pr2 _Pred); // 对容器中的元素进行排序,排序的方法由_Pred 决定(二元函数)。
void merge(list<T> &l); // 采用归并法合并两个已排序的 list 容器,合并后的 list 容器仍是有序
的。
示例:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main()
{
list<int> la = { 8,2,6,4,5 };
for (auto &val : la)
cout << val << " ";
cout << endl;
la.reverse(); // 反转链表。
for (auto& val : la)
cout << val << " ";
cout << endl;
la.sort(); // 链表排序。
for (auto& val : la)
cout << val << " ";
cout << endl;
list<int> lb = { 3,7,9,10,1 };
lb.sort(); // 链表排序。
la.merge(lb); // 归并链表。
for (auto& val : la)
cout << val << " ";
cout << endl;
}
六、比较操作
bool operator == (const vector<T> & l) const;
bool operator != (const vector<T> & l) const;
七、插入和删除
1)void push_back(const T& value); // 在链表的尾部追加一个元素。
2)void emplace_back(…); // 在链表的尾部追加一个元素,…用于构造元素。C++11
3)iterator insert(iterator pos, const T& value); // 在指定位置插入一个元素,返回指向插入元
素的迭代器。
4)iterator emplace (iterator pos, …); // 在指定位置插入一个元素,…用于构造元素,返回指向
插入元素的迭代器。C++11
5)iterator insert(iterator pos, iterator first, iterator last); // 在指定位置插入一个区间的元素,
返回指向第一个插入元素的迭代器。
6)void pop_back(); // 从链表尾部删除一个元素。
7)iterator erase(iterator pos); // 删除指定位置的元素,返回下一个有效的迭代器。
8)iterator erase(iterator first, iterator last); // 删除指定区间的元素,返回下一个有效的迭代器。
9)push_front(const T& value); // 在链表的头部插入一个元素。
10)emplace_front(…); // 在链表的头部插入一个元素,…用于构造元素。C++11
11)splice(iterator pos, const vector<T> & l); // 把另一个链表连接到当前链表。
12)splice(iterator pos, const vector<T> & l, iterator first, iterator last); // 把另一个链表指
定的区间连接到当前链表。
13)splice(iterator pos, const vector<T> & l, iterator first); // 把另一个链表从first开始的结
点连接到当前链表。
14)void remove(const T& value); // 删除链表中所有值等于 value 的元素。
15)void remove_if(_Pr1 _Pred); // 删除链表中满足条件的元素,参数_Pred 是一元函数。
16)void unique(); // 删除链表中相邻的重复元素,只保留一个。
17)void pop_front(); // 从链表头部删除一个元素。
示例:
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main()
{
list<int> la = { 8,2,6,4,5 };
for (auto& val : la) cout << val << " ";
cout << endl;
list<int> lb = { 3,7,9,10,1 };
for (auto& val : lb) cout << val << " ";
cout << endl;
auto first = lb.begin();
first++;
auto last = lb.end();
last--;
la.splice(la.begin(), lb, first, last);
for (auto& val : la) cout << val << " ";
cout << endl;
cout << "lb.size()=" << lb.size() << endl;
for (auto& val : lb) cout << val << " ";
cout << endl;
}
八、list 容器的简单实现
以下 demo 程序简单的实现了 list 容器。
示例:
#include<iostream>
using namespace std;
namespace
{
template<class _Ty> class List;
template<class _Ty> class ListIterator;
// 节点类。
template<class _Ty>
class ListNode
{
friend class List<_Ty>;
friend class ListIterator<_Ty>;
public:
ListNode() :_Value(_Ty()), _Next(nullptr), _Prev(nullptr) {}
ListNode(_Ty V, ListNode* next = nullptr, ListNode* prev = nullptr) :_Value(V), _Next(next), _Prev(prev) {}
private: _Ty _Value;
ListNode* _Next;
ListNode* _Prev;
};
// 迭代器。
template<class _Ty>
class ListIterator
{
typedef ListIterator<_Ty> _It;
public:
ListIterator() :_Ptr(nullptr) {}
ListIterator(ListNode<_Ty>* _P) :_Ptr(_P) {}
public: _It& operator++()
{ _Ptr = _Ptr->_Next;
return *this;
}_It& operator--()
{ _Ptr = _Ptr->Prev;
return *this;
}_Ty& operator*()
{
return (_Ptr->_Value);
}
bool operator!=(const _It& it)
{
return _Ptr != it._Ptr;
}
bool operator==(const _It& it)
{
return _Ptr == it._Ptr;
}
ListNode<_Ty>* _Mynode()
{
return _Ptr;
}
private:
ListNode<_Ty>* _Ptr;
};
// 链表类。
template<class _Ty>
class List
{
public:
typedef ListNode<_Ty>* _Nodeptr;
typedef ListIterator<_Ty> iterator;
public:
List() :_Size(0)
{
CreateHead();
}
List(size_t n, const _Ty& x = _Ty()) :_Size(0)
{
CreateHead(), insert(begin(), n, x);
}
List(const _Ty* first, const _Ty* last) :_Size(0)
{
CreateHead();
while (first != last)
push_back(*first++);
}
List(iterator first, iterator last)
{
CreateHead();
while (first != last)
{
push_back(*first);
++first;
}
}
List(List<_Ty>& lt) :_Size(0)
{
CreateHead();
List<_Ty>tmp(lt.begin(), lt.end());
this->swap(tmp);
}~List()
{
clear();
delete _Head; _Size = 0;
}
public:
void push_back(const _Ty& x)
{
insert(end(), x);
}
void pop_back()
{
erase(--end());
}
void push_front(const _Ty& x)
{
insert(begin(), x);
}
void pop_front()
{
erase(begin());
}_Ty& front()
{
return *begin();
}
const _Ty& front()const
{
return *begin();
}_Ty& back()
{
return *--end();
}
const _Ty& back()const
{
return *--end();
}
public:
size_t size()const
{
return _Size;
}
bool empty()const
{
return (size() == 0);
}
public:
iterator begin()
{
return iterator(_Head->_Next);
}
iterator end()
{
return iterator(_Head);
}
void clear()
{
erase(begin(), end());
}
public:
//在_P 位置前插入值为 x 的节点
iterator insert(iterator _P, const _Ty& x)
{ _Nodeptr cur = _P._Mynode(); _Nodeptr _S = new ListNode<_Ty>(x); _S->_Next = cur; _S->_Prev = cur->_Prev; _S->_Prev->_Next = _S; _S->_Next->_Prev = _S; _Size++;
return iterator(_S);
}
void insert(iterator _P, size_t n, const _Ty& x = _Ty())
{
while (n--)
insert(_P, x);
}
//删除_P 位置的节点,返回该节点的下一个节点位置
iterator erase(iterator _P)
{ _Nodeptr cur = _P._Mynode(); _Nodeptr next_node = cur->_Next;
cur->_Prev->_Next = cur->_Next;
cur->_Next->_Prev = cur->_Prev;
delete cur; _Size--;
return iterator(next_node);
}
iterator erase(iterator first, iterator last)
{
while (first != last)
{
first = erase(first);
}
return first;
}
void swap(List<_Ty>& lt)
{
std::swap(_Head, lt._Head);
std::swap(_Size, lt._Size);
}
protected:
void CreateHead()
{ _Head = new ListNode<_Ty>; _Head->_Prev = _Head->_Next = _Head;
}
private: _Nodeptr _Head;
size_t _Size;
};
};
int main()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
List<int>la(arr+2, arr + 10);
List<int>lb(la);
for (auto elem:la)
cout << elem << " ";
cout << endl;
for (auto elem : lb)
cout << elem << " ";
cout << endl;
}
 


http://www.ppmy.cn/embedded/108344.html

相关文章

实践reflex:项目架构解析

reflex 是一个使用纯Python构建全栈web应用的库&#xff0c;但是需要使用node&#xff0c;所以你懂的。 reflex安装&#xff1a;实践reflex&#xff1a;一个使用纯Python构建全栈web应用的库-CSDN博客 创建hello项目 (base) skyub:~$ mkdir hello (base) skyub:~$ cd hello/…

【Azure Redis】Redis-CLI连接Redis 6380端口始终遇见 I/O Error

问题描述 使用Redis-cli连接Redis服务&#xff0c;因为工具无法直接支持TLS 6380端口连接&#xff0c;所以需要使用 stunnel 配置TLS/SSL服务。根据文章(Linux VM使用6380端口(SSL方式)连接Azure Redis (redis-cli & stunnel) &#xff1a; https://www.cnblogs.com/luligh…

模型训练套路(二)

接模型训练套路&#xff08;一&#xff09;http://t.csdnimg.cn/gZ4Fm 得到预测的值&#xff1a;preds[1][1]&#xff0c; 输出目标&#xff1a;inputs target [0][1]&#xff1b; 查看两者的正确率&#xff0c;就看&#xff1a;predsinputs target 输出的结果&#xff1a…

前端WebSocket客户端实现

// 创建WebSocket连接 var socket new WebSocket(ws://your-spring-boot-server-url/websocket-endpoint);// 连接打开时触发 socket.addEventListener(open, function (event) {socket.send(JSON.stringify({type: JOIN, room: general})); });// 监听从服务器来的消息 socke…

K8S日志收集

本章主要讲解在 Kubernetes 集群中如何通过不同的技术栈收集容器的日志&#xff0c;包括程序直接输出到控制台日志、自定义文件日志等。 一、有哪些日志需要收集 为了更加方便的处理异常&#xff0c;日志的收集与分析极为重要&#xff0c;在学习日志收集之前&#xff0c;需要知…

QT基础 QPropertyAnimation简单学习

目录 1.简单介绍 2.使用步骤 3.部分代码示例 4.多项说明 5.信号反馈 6.自定义属性 1. 定义自定义属性 2. 使用 QPropertyAnimation 动画化自定义属性 3. 连接信号和槽 4.注意事项 7.更多高级示例 1.简单介绍 QPropertyAnimation是Qt中的一个类&#xff0c;用于实现属性…

idea安装并使用maven依赖分析插件:Maven Helper

在 IntelliJ IDEA 中安装并使用 Maven Helper 插件可以帮助你更方便地管理 Maven 项目的依赖&#xff0c;比如查看依赖树、排除冲突依赖等。以下是安装和使用 Maven Helper 插件的步骤&#xff1a; 安装 Maven Helper 插件 打开 IntelliJ IDEA 并进入你的项目。 在 IDE 的右下…

百度飞浆OCR半自动标注软件OCRLabel配置【详细

今天帮标注人员写了一份完整的百度飞浆OCR标注软件的安装配置说明书、以供标注人员使用 包括各种环境安装包一起分享出来【conda\python\label项目包、清华源配置文件、pycharm社区版安装包】 提取码&#xff1a;umys 1、解压并安装tools文件下的miniconda,建议安装在D盘下的…

Win32绕过UAC弹窗获取管理员权限

在早些年写一些桌面软件时&#xff0c;需要管理员权限&#xff0c;但是又不想UAC弹窗&#xff0c;所以一般是直接将UAC的级别拉到最低&#xff0c;或者直接禁用UAC的相关功能。 什么是UAC(User Account Control) 用户帐户控制 (UAC) 是一项 Windows 安全功能&#xff0c;旨在保…

Flink SQL 中常见的数据类型

Flink SQL 中常见的数据类型 目标 通过了解Flink SQL 中常见的数据类型,掌握正确编写Flink SQL 语句背景 Apache Flink 支持多种数据类型,这些数据类型被用于 Flink SQL 表达式、Table API 以及 DataStream API 中。以下是 Flink SQL 中常见的数据类型: 基本数据类型 Boo…

<Rust>egui学习之部件(十一):如何在窗口中添加单选框radiobutton部件?

前言 本专栏是关于Rust的GUI库egui的部件讲解及应用实例分析&#xff0c;主要讲解egui的源代码、部件属性、如何应用。 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;egui、eframe 概述 本文是本专栏的第十一篇…

算法练习题17——leetcode54螺旋矩阵

题目描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 代码 import java.util.*;class Solution {public List<Integer> spiralOrder(int[][] matrix) {// 用于存储螺旋顺序遍历的结果List<Integer>…

学习整理使用jquery实现获取相同name被选中的多选框值的方法

学习整理使用jquery实现获取相同name被选中的多选框值的方法 <html><head><meta charset"gbk"><!-- 引入JQuery --><script src"https://www.qipa250.com/jquery/dist/jquery.min.js" type"text/javascript"><…

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题

flutter开发实战-flutter build web微信无法识别二维码及小程序码问题 GitHub Pages是一个直接从GitHub存储库托管的静态站点服务&#xff0c;‌它允许用户通过简单的配置&#xff0c;‌将个人的代码项目转化为一个可以在线访问的网站。‌这里使用flutter build web来构建web发…

现代计算机中数字的表示与浮点数、定点数

现代计算机中数字的表示与浮点数、定点数 导读&#xff1a;浮点数运算是一个非常有技术含量的话题&#xff0c;不太容易掌握。许多程序员都不清楚使用操作符比较float/double类型的话到底出现什么问题。这篇文章讲述了浮点数的来龙去脉&#xff0c;所有的软件开发人员都应该读…

【网络安全】服务基础第二阶段——第三节:Linux系统管理基础----Linux用户与组管理

目录 一、用户与组管理命令 1.1 用户分类与UID范围 1.2 用户管理命令 1.2.1 useradd 1.2.2 groupadd 1.2.3 usermod 1.2.4 userdel 1.3 组管理命令 1.3.1 groupdel 1.3.2 查看密码文件 /etc/shadow 1.3.4 passwd 1.4 Linux密码暴力破解 二、权限管理 2.1 文件与目…

封装触底加载组件

&#xff08;1&#xff09;首先创建一个文件名为&#xff1a;InfiniteScroll.vue <template><div ref"scrollContainer" class"infinite-scroll-container"><slot></slot><div v-if"loading" class"loading-sp…

nginx 新建一个 PC web 站点

注意&#xff1a;进行实例之前必须完成nginx的源码编译。&#xff08;阅读往期文章完成步骤&#xff09; 1.编辑nginx的配置文件&#xff0c;修改内容 [rootlocalhost ~]# vim /usr/local/nginx/conf/nginx.conf 2.创建新目录/usr/local/nginx/conf.d/&#xff0c;编辑新文件…

【激活函数总结】Pytorch中的激活函数详解: ReLU、Leaky ReLU、Sigmoid、Tanh 以及 Softmax

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

问:你知道IO和NIO有哪些区别不?

一、先表示一下_ Java IOJava NIO主要特点面向流&#xff08;Stream&#xff09;的I/O操作面向缓冲区&#xff08;Buffer&#xff09;和通道&#xff08;Channel&#xff09;的I/O操作&#xff0c;支持非阻塞I/O和选择器&#xff08;Selector&#xff09;常用方法InputStream、…