嵌入式学习-C嘎嘎-Day04

news/2024/11/16 20:42:06 标签: 学习, c语言, 开发语言, c++

嵌入式学习-C嘎嘎-Day04

1. 模(mú)板

1.1 函数模板

1.2 类模板

2. 容器

2.1 相关概念

2.2 容器分类

2.2.1 顺序容器

2.2.1.1 array 数组

2.2.1.2 vector 向量

2.2.1.3 list 列表

2.2.1.4 deque 队列

2.2.2 关联容器

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;
}

http://www.niftyadmin.cn/n/5754598.html

相关文章

前端怎么获取视口大小

方式一&#xff1a;使用 window.innerWidth 和 window.innerHeight 这两个属性分别返回浏览器窗口的视口宽度和高度&#xff08;单位为像素&#xff09;&#xff0c;包括滚动条占用的空间&#xff08;如果有的话&#xff09;。 例如&#xff1a; const viewportWidth window.…

模态融合技术在多模态大模型中的应用研究

随着人工智能技术的快速发展&#xff0c;多模态大模型成为了研究的热点。模态融合技术作为多模态大模型的核心&#xff0c;它允许模型处理和理解来自不同模态&#xff08;如文本、图像、音频&#xff09;的数据。本文旨在探讨模态融合技术的原理、方法、挑战及其在多模态大模型…

MySQL时间字段TIMESTAMP和DATETIME

SELECT global.time_zone, session.time_zone;查询数据库的全局时区和当前会话的时区信息&#xff0c;一般如果使用navicat进行连接&#xff0c;没有显示指定时区信息&#xff0c;会默认使用system_time_zone。 可以使用 SET time_zone 08:00; SELECT global.time_zone, sess…

Cpolar 内网穿透使用

Cpolar登录地址&#xff1a;cpolar - secure introspectable tunnels to localhost 使用固定公网TCP连接ssh ssh -p端口号 用户名公网地址

Linux---常用shell脚本

目录 一.网络服务 开启network服务 网口IP配置 聚合口配置 前言 秋招拿到了科大讯飞的offer&#xff0c;可是由于某些原因无法完成三方签署&#xff0c;心情还是比较失落的&#xff0c;或许写一篇技术博客&#xff0c;活跃一下大脑思维也是一种不错的放松方式。 一.网络服务 …

面试篇-项目管理

⼀、构建管理 项目为什么选择Maven构建? 选择Maven进行项目构建有以下几个主要原因&#xff1a; 1. 依赖管理&#xff1a;Maven 提供了强大的依赖管理功能&#xff0c;可以自动下载项目所需的第三方库和依赖&#xff0c;并且可以管理这些依赖的版本、范围等信息。这简化了项…

Latex表格中多行合并后将内容居中显示

Latex表格中多行合并后将内容居中显示 目标效果Latex代码ProblemLaTeX Code:**Explanation:**Resulting Output: 目标效果 Latex代码 \begin{table}[h]\centering\caption{Example Table with Merged Cells}\begin{tabular}{|c|c|c|c|}\hline\textbf{Row 1, Col 1} & \mul…

STL之vecor的使用(超详解)

目录 1. C/C中的数组 1.1. C语言中的数组 1.2. C中的数组 2. vector的接口 2.1. vector的迭代器 2.2. vector的初始化与销毁 2.3. vector的容量操作 2.4. vector的访问操作 2.5. vector的修改操作 &#x1f493; 博客主页&#xff1a;C-SDN花园GGbond ⏩ 文章专栏…