嵌入式学习-C嘎嘎-Day04

嵌入式学习-C嘎嘎-Day04

[1. 模(mú)板](#1. 模(mú)板)

[1.1 函数模板](#1.1 函数模板)

[1.2 类模板](#1.2 类模板)

[2. 容器](#2. 容器)

[2.1 相关概念](#2.1 相关概念)

[2.2 容器分类](#2.2 容器分类)

[2.2.1 顺序容器](#2.2.1 顺序容器)

[2.2.1.1 array 数组](#2.2.1.1 array 数组)

[2.2.1.2 vector 向量](#2.2.1.2 vector 向量)

[2.2.1.3 list 列表](#2.2.1.3 list 列表)

[2.2.1.4 deque 队列](#2.2.1.4 deque 队列)

[2.2.2 关联容器](#2.2.2 关联容器)

[2.3 迭代器 iterator](#2.3 迭代器 iterator)

1. 模 (mú)

模板可以让程序员编写与类型无关的代码,模板可以让类或函数声明一种通用类型,在使用的过程中一些变量、参数或返回值可以是任意类型。

模板通常有两种实现方式:

  • 函数模板
  • 类模板

模板是一种参数化多态的工具。

1.1 函数模板

编写函数模板时,需要确定函数算法的适用性。

复制代码
#include <iostream>`

`using` `namespace std;`

`// 模板声明`
`template` `<class` `T>`
`T add(T a,T b)`
`{`
    `return a+b;`
`}`

`class` `Dog`
`{`

`};`


`int` `main()` `{`

`    cout <<` `add(2,3)` `<< endl;` `// 5`
`    cout <<` `add(2.2,3.3)` `<< endl;` `// 5.5`
`    cout <<` `add('A','A')` `<< endl;` `// ?`
`    string a =` `"abc";`
`    string b =` `"123";`
`    cout <<` `add(a,b)` `<< endl;`
`    Dog d1;`
`    Dog d2;`
`//    add(d1,d2); 参数可以正常传入`

    `return` `0;`
`}`
`

1.2 类模板

复制代码
#include <iostream>`

`using namespace std;`

`template <typename T>`
`class Test`
`{`
`private:`
`    T value;`

`public:`
`    Test(T v):value(v){}`

`    T get_value() const`
`    {`
`        return value;`
`    }`

`    void set_value(T value)`
`    {`
`        this->value = value;`
`    }`
`};`

`int main()`
`{`
`    Test<int> t1(1);`
`    cout << t1.get_value() << endl;`

`    Test<double> t2(1.1);`
`    cout << t2.get_value() << endl;`

`    return 0;`
`}

把上面的写法改为类内声明,类外定义的方式

复制代码
#include <iostream>`

`using namespace std;`

`template <typename T>`
`class Test`
`{`
`private:`
`    T value;`

`public:`
`    Test(T v);`
`    T get_value() const;`
`    void set_value(T value);`
`};`

`template<class T>`
`Test<T>::Test(T v):value(v){} // 构造函数`

`template<class T>`
`T Test<T>::get_value() const // getter`
`{`
`    return value;`
`}`

`template<class T>`
`void Test<T>::set_value(T value) // setter`
`{`
`    this->value = value;`
`}`

`int main()`
`{`
`    Test<int> t1(1);`
`    cout << t1.get_value() << endl;`

`    Test<double> t2(1.1);`
`    cout << t2.get_value() << endl;`

`    return 0;`
`}`
`

2. 容器

2.1 相关概念

泛型编程(Generic Programming)最初提出时的动机很简单直接:发明一种语言机制,能够帮助实现一个通用的标准容器库。所谓通用的标准容器库,就是要能够做到,比如用一个List类存放所有可能类型的对象这样的事;泛型编程让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。

标准模板库(Standard Template Library,STL)是惠普实验室开发的一系列软件的统称。虽说它主要表出现到C++中,但在被引入C++之前该技术就已经存在了很长时间。

STL的代码从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),几乎所有的代码都采用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。

2.2 容器分类

容器类型在使用时均需要引入对应的头文件,并且容器对象本身只能在栈内存。

思维导图插件

2.2.1 顺序容器

顺序容器是一种线性结构的可续群集,各个元素之间按照先后顺序排列,可以使用删除或插入操作改变顺序(array例外)。

2.2.1.1 array 数组

array是C++11中新增的数据类型,相比于传统的内置数组更加安全且更容易使用。

复制代码
#include <iostream>`
`#include <array> // 数组`

`using namespace std;`

`int main()`
`{`
`    // 创建一个长度为3的int数组`
`    array<int,3> arr;`
`    cout << arr.size() << endl; // 3`

`    // 赋值`
`    arr[1] = 2;`

`    // 取出元素`
`    cout << arr[0] << endl; // 输出结果不定`
`    cout << arr.at(1) << endl; // 更安全`

`    // 填充`
`    arr.fill(10086);`

`    // for循环遍历`
`    for(int i = 0;i<arr.size();i++)`
`    {`
`        cout << arr.at(i) << " ";`
`    }`
`    cout << endl;`

`    // for-each遍历`
`    for(int i:arr)`
`        cout << i << " ";`
`    cout << endl;`

`    // 迭代器遍历:(略)`

`    return 0;`
`}
2.2.1.2 vector 向量

vector内部由数组实现,元素的内存地址是连续的,因此可以高效地进行随机存取,但是不擅长插入删除。

复制代码
#include <iostream>`
`#include <vector> // 向量`

`using namespace std;`

`int main()`
`{`
`    vector<int> vec1; // 创建一个长度为0的int向量`
`    cout << vec1.empty() << endl; // 判断是否为空`
`    vector<int> vec2(vec1); // 拷贝构造函数`
`    cout << vec2.size() << endl; // 0`
`    vector<int> vec3(5); // 5个0`

`    // for循环遍历`
`    for(int i=0;i<vec3.size();i++)`
`    {`
`        cout << vec3.at(i) << " ";`
`    }`
`    cout << endl;`

`    vector<int> vec4(5,2); // 5个2`
`    vec4.push_back(23); // 尾插23`
`    // 参数1:插入的位置,begin返回值一个迭代器指针,指向第一个元素`
`    // +2表示向后移动两位`
`    // 参数2:新插入的元素`
`    vec4.insert(vec4.begin()+2,4);`

`    // 修改元素`
`    vec4[0] = 1;`
`    vec4[vec4.size()-3] = -222;`
`    vec4.pop_back(); // 删除最后一个元素`
`//    // 删除倒数第2个元素`
`    // 参数:删除的位置,end函数返回的迭代器指针指向最后一个元素的后面`
`    vec4.erase(vec4.end()-2);`

`    // 在倒数第二个位置插入元素888`
`    vec4.insert(vec4.end()-1,888);`

`    cout << "第一个元素:" << vec4.front() << endl;`
`    cout << "最后一个元素:" << vec4.back() << endl;`

`    // 清空`
`//    vec4.clear();`

`    // for-each`
`    for(int i:vec4)`
`        cout << i << " ";`
`    cout << endl;`

`    // 迭代器遍历:(略)`

`    return 0;`
`}
2.2.1.3 list 列表

list由双向链表实现,元素的内存空间是不连续的,因此更高效地进行插入删除操作,但是不擅长随机存取。

复制代码
#include <iostream>`
`#include <list> // 列表`

`using` `namespace std;`

`int` `main()`
`{`
`    list<int> lis1;` `// 创建一个长度为0的int向量`
`    cout << lis1.empty()` `<< endl;` `// 判断是否为空`
`    list<int>` `lis2(lis1);` `// 拷贝构造函数`
`    cout << lis2.size()` `<< endl;` `// 0`
`    list<int>` `lis3(5);` `// 5个0`

`    list<int>` `lis4(5,2);` `// 5个2`

`    lis4.push_back(9);` `// 尾插`
`    lis4.push_front(-1);` `// 头插`
    `// 在第2个位置插入元素`
`    lis4.insert(++lis4.begin(),3);`
    `// 获取指向第一个元素的迭代器指针`
`    list<int>::iterator iter = lis4.begin();`
    `// 移动指针到第4个位置`
    `advance(iter,3);`
    `// 在第4个位置插入元素4`
`    lis4.insert(iter,4);`
    `// 在倒数第三个位置插入元素-33`
`    iter = lis4.end();`
    `advance(iter,-2);`
`    lis4.insert(iter,-33);`

    `// for-each`
    `for(int i:lis4)`
    `{`
`        cout << i <<` `" ";`
    `}`
`    cout << endl;`

`    lis4.pop_back();` `// 删除最后一个元素`
`    lis4.pop_front();` `// 删除第一个元素`
`    iter = lis4.begin();`
    `advance(iter,4);`
`    lis4.erase(iter);` `// 删除第五个元素`

    `// 修改倒数第一个元素`
`    iter =` `--lis4.end();`
    `*iter =` `679;`

    `// 排序`
`    lis4.sort();`
`    lis4.clear();` `// 清空`

    `for(int i:lis4)`
    `{`
`        cout << i <<` `" ";`
    `}`
`    cout << endl;`

    `return` `0;`
`}
2.2.1.4 deque 队列

deque是一种均衡的顺序容器,几乎兼容所有的vector和list的接口,性能介于二者之间(两端存取性能较强)。

代码略。

2.2.2 关联容器

关联容器对外没有顺序,内部仍然有排序特点。内部数据以键值对(key-value pair)的方式存储。

map是一种单重键值对映射,键需要具有唯一性,而值可以重复,通常使用键寻找值。

复制代码
#include <iostream>`
`#include <map> // 单重键值对映射`

`using` `namespace std;`

`int` `main()`
`{`
`    map<string,int> m;` `// 创建一个map对象`
    `// 添加键值对`
`    m["height"]` `=` `177;`
`    m.insert(pair<string,int>("age",22));`
`    m["height"]` `=` `178;` `// 已经存在则修改`
`    m.insert(pair<string,int>("age",23));` `// 已经存在则无效`

`    cout << m.size()` `<< endl;` `// 2`
    `// 通过键取出值`
`    cout << m["height"]` `<<` `" "` `<< m["age"]` `<< endl;`

    `// 取出的键值对不存在,则创建一个`
`    cout << m["weight"]` `<< endl;` `// 0`
`    cout << m.size()` `<< endl;` `// 3`

`//    cout << m.at("income") << endl; 终止`

    `// 获取某个键的迭代器指针`
`    map<string,int>::iterator iter = m.find("income");`
    `if(iter == m.end())`
    `{`
`        cout <<` `"没有此键"` `<< endl;`
    `}else`
    `{`
`        cout <<` `"有此键,值="` `<< iter->second << endl;`
    `}`

`    m.clear();` `// 清空`

    `// 遍历只支持迭代器(略)`

    `return` `0;`
`}

2.3 迭代器 iterator

迭代器可以遍历所有的容器,在创建迭代器时,可以使用容器的begin和end函数,分别拿到一个指向第一个元素和最后一个元素之后的迭代器。

迭代器分为只读迭代器(const_interator)和读写迭代器(iterator)。

复制代码
#include <iostream>`
`#include <string>`
`#include <array>`
`#include <vector>`
`#include <list>`
`#include <deque>`
`#include <map>`

`using` `namespace std;`

`int` `main()`
`{`
`    string s =` `"fgjksdhj";`
    `for(string::const_iterator iter = s.begin();iter!=s.end();iter++)`
    `{`
`        cout <<` `*iter << endl;`
    `}`

`    array<double,5> arr;`
    `for(int i=0;i<arr.size();i++)`
`        arr.at(i)` `= i+1;`
    `for(array<double,5>::iterator iter = arr.begin();iter!=arr.end();iter++)`
    `{`
        `*iter =` `*iter+1;`
`        cout <<` `*iter << endl;`
    `}`

`    vector<string>` `v(4,"AAA");`
    `for(vector<string>::const_iterator iter = v.begin();iter!=v.end();iter++)`
`        cout <<` `*iter << endl;`

`    list<string>` `l(4,"AAA");`
    `for(list<string>::const_iterator iter = l.begin();iter!=l.end();iter++)`
`        cout <<` `*iter << endl;`

`    deque<int>` `d(4,666);`
    `for(deque<int>::const_iterator iter = d.begin();iter!=d.end();iter++)`
`        cout <<` `*iter << endl;`

`    map<string,string> m;`
`    m["name"]` `=` `"David";`
`    m["city"]` `=` `"Jinan";`
`    m["aaa"]` `=` `"bbbb";`
    `for(map<string,string>::const_iterator iter = m.begin();iter!=m.end();`
`        iter++)`
    `{`
`        cout << iter->first <<` `" "` `<< iter->second << endl;`
    `}`

    `return` `0;`
`}
相关推荐
数据小爬虫@5 分钟前
如何高效利用Python爬虫按关键字搜索苏宁商品
开发语言·爬虫·python
ZJ_.6 分钟前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
Narutolxy12 分钟前
深入探讨 Go 中的高级表单验证与翻译:Gin 与 Validator 的实践之道20241223
开发语言·golang·gin
Hello.Reader19 分钟前
全面解析 Golang Gin 框架
开发语言·golang·gin
禁默30 分钟前
深入浅出:AWT的基本组件及其应用
java·开发语言·界面编程
yuyanjingtao32 分钟前
CCF-GESP 等级考试 2023年9月认证C++四级真题解析
c++·青少年编程·gesp·csp-j/s·编程等级考试
Code哈哈笑39 分钟前
【Java 学习】深度剖析Java多态:从向上转型到向下转型,解锁动态绑定的奥秘,让代码更优雅灵活
java·开发语言·学习
程序猿进阶43 分钟前
深入解析 Spring WebFlux:原理与应用
java·开发语言·后端·spring·面试·架构·springboot
qq_433618441 小时前
shell 编程(二)
开发语言·bash·shell
闻缺陷则喜何志丹1 小时前
【C++动态规划 图论】3243. 新增道路查询后的最短距离 I|1567
c++·算法·动态规划·力扣·图论·最短路·路径