首页 > 编程语言 >C++模板与容器

C++模板与容器

时间:2024-10-09 19:48:10浏览次数:3  
标签:容器 cout int iter C++ lis include 模板

目录

一、  模板

1 .函数模板

2 .类模板

二、容器

1 .标准模板库STL

2. 概念

3 顺序容器

3.1 array数组

2.3.2 vector 向量

3.3 list列表 

3.4 deque队列

4 关联容器

5 迭代器遍历


一、  模板

        模板可以让类或者函数支持一种通用类型,这种通用数据类型在实际运行的过程中可以使用任何数据类型。因此程序员可以写出一些与类型无关的代码,这种编程方式也被称为泛型编程。

通常有两种实现形式:

● 函数模板
● 类模板

1 .函数模板

        使一个函数支持模板编程,可以使函数支持通用数据类型。
 

#include <iostream>
using namespace std;


template<typename T>     // typename 也可以是class
T add(T a,T b)
{
    return a+b;
}

int main()
{
    string a = "hello";
    string b = "world";
    cout << add(a,b);
    return 0;
}

2 .类模板

使一个类支持模板编程,可以使一个类支持通用数据类型。

#include <iostream>
using namespace std;

template<typename T>     // typename 也可以是class
int add(int a,int b)
{
    return a+b;
}


// 类模板
template<class T>
class Test
{
private:
    T val;
public:
    Test(T v);
    T get_val();
    void set_val(const T &val);
};

template<class T>
Test<T>::Test(T v):val(v)
{

}

template<class T>
T Test<T>::get_val()
{
    return val;
}

template<class T>
void Test<T>::set_val(const T &val)
{
    this->val = val;
}


int main()
{
    Test<int> t1(20);
    cout << t1.get_val() << endl;

    Test<double> t2(3.14);
    cout << t2.get_val() << endl;


    Test<string> t3("hello");
    cout << t3.get_val() << endl;

    return 0;
}

二、容器

1 .标准模板库STL

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

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

2. 概念

容器是用来存储数据的集合,数据的元素可以是任何类型(因为是使用模板实现)。

容器类的使用,都需要引入对应的头文件。

3 顺序容器

顺序容器中每个元素均有固定的位置并程线行排布。除非使用删除或者插入的操作改变元素的位置。否则元素位置不变。

3.1 array数组

array数组是C++11新增的容器类型,与传统数组相比更加安全、更加易于使用。array数组是定长的,没办法方便进行伸缩。

#include <iostream>
#include <array>
using namespace std;

int main()
{
    // 创建一个长度为5的int数组
    array<int,5> arr = {1,2,3}; // 后面两位补零
    cout << arr[0] << endl; // 1
    cout << arr[4] << endl; // 0

    cout << arr.at(2) << endl;  // 3

    arr[3] = 200;

    // for循环
    for(int i = 0;i < arr.size();++i)
    {
        cout << arr[i] << endl;
    }

    // for each
    for(int i : arr)
    {
        cout << i << endl;
    }

    // 迭代器遍历,后面说
    return 0;
}

2.3.2 vector 向量

vector内部是由数组实现的,比较适合进行随机存取操作,而不擅长插入和删除操作。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    //    vector<int> v = {1,2,3};
    //    cout << v.size() << endl;
    //    for(int i:v)
    //    {
    //        cout << i << endl;
    //    }

    // 创建一个长度为5的int向量
    vector<int> vec(5);
    cout << vec.size() << endl; // 5

    // 增
    vec.push_back(222);
    cout << vec.size() << endl; // 6

    // +2是在第三个位置上插入333
    vec.insert(vec.begin()+2,333); // begin()可以返回指向第一个元素的迭代器指针

    // 改
    vec.at(0) = 1;
    vec[1] = 2;
    vec[3] = 4;
    vec[4] = 5;

    // 删除
    // 删除最后一个元素
    vec.pop_back();

//    // 删除第二个元素
    vec.erase(vec.begin()+1);
    vec.erase(vec.end()-2); // 删除倒数第二个元素

    // 查
    // 取出单个元素
    cout << vec[0] << endl;
    cout << vec.at(2) << endl;

    // 遍历
    for(int i = 0; i < vec.size() ;++i)
    {
        cout << vec[i] << " ";
    }
    cout << endl;


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

    // 迭代器遍历,先省略

    // 判断是否空,0非空,1空
    cout << vec.empty() << endl;

    // 清空
    vec.clear();
    cout << vec.empty() << endl;    // 1
    return 0;
}

3.3 list列表 

list内部是由双向循环链表实现,内存空间不连续,不支持下标访问。优点:可以高效的删除和插入操作。但是不适合随机存取操作。

#include <iostream>
#include <list>
using namespace std;

int main()
{
    // 创建一个默认无数值的list
//    list<string>lis1;

//    // 创建一个长度为2的列表,第一个元素是hello第二个元素是world
//    list<string>lis2{"hello","world"};
//    for(string s :lis2)
//    {
//        cout << s << endl;
//    }

    // 创建一个长度为5的列表,每个元素都是"hello"
    list<string>lis(5,"hello");

    // 增
    lis.push_back("world"); // 向后追加单元素
    lis.push_front("hahaha");   // 向前追加单元素

    lis.insert(++lis.begin(),"222");    // 在第二个位置上插入“222”

    // 删
//    lis.pop_back(); // 删除最后一个元素
    lis.pop_front();    // 删除第一个元素

    // 保存迭代器指针
    list<string>::iterator iter = lis.begin();
    advance(iter,1);    // 移动迭代器指针
    lis.insert(iter,"333");

    // 删除 最后一个元素
//    iter = lis.end();
//    iter--;
//    lis.erase(iter);

    iter = lis.begin();
    advance(iter,1);
    lis.erase(iter);

    // 返回第一个元素的引用
//    cout << lis.front() << endl;
    // 最后一个元素的引用
//    cout << lis.back() << endl;


    // 改
    iter = lis.end();
    advance(iter,2);
    *iter = "200";

    // 查
    cout << *iter << endl;
    // 遍历 for each
    for(string s :lis)
    {
        cout << s << endl;
    }

    // 迭代器遍历,后面说

    // 清空
    lis.clear();
    cout << lis.size() << endl;
    return 0;
}

3.4 deque队列

队列几乎支持所有vector的API,性能位于vector与list两者之间。是最擅长两端存取的顺序容器。

#include <iostream>
#include <deque>
using namespace std;

int main()
{
    //    deque<int> v = {1,2,3};
    //    cout << v.size() << endl;
    //    for(int i:v)
    //    {
    //        cout << i << endl;
    //    }

    // 创建一个长度为5的int向量
    deque<int> deq(5);
    cout << deq.size() << endl; // 5

    // 增
    deq.push_back(222);
    cout << deq.size() << endl; // 6

    // +2是在第三个位置上插入333
    deq.insert(deq.begin()+2,333); // begin()可以返回指向第一个元素的迭代器指针

    // 改
    deq.at(0) = 1;
    deq[1] = 2;
    deq[3] = 4;
    deq[4] = 5;

    // 删除
    // 删除最后一个元素
    deq.pop_back();

//    // 删除第二个元素
    deq.erase(deq.begin()+1);
    deq.erase(deq.end()-2); // 删除倒数第二个元素

    // 查
    // 取出单个元素
    cout << deq[0] << endl;
    cout << deq.at(2) << endl;

    // 遍历
    for(int i = 0; i < deq.size() ;++i)
    {
        cout << deq[i] << " ";
    }
    cout << endl;


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

    // 迭代器遍历,先省略

    // 判断是否空,0非空,1空
    cout << deq.empty() << endl;

    // 清空
    deq.clear();
    cout << deq.empty() << endl;    // 1
    return 0;
}

4 关联容器

关联容器的各个元素之间没有严格顺序,虽然内部具有排序的特点,但是在使用时没有任何顺序相关的接口。

最常见的关联容器map-键值对映射。

对于map而言,键具有唯一性,键通常使用字符串类型,值可能是任何类型。通过键可以找到对应的值。

#include <iostream>
#include <map>
using namespace std;

int main()
{
    map<string,int>ma1 = {{"身高",190},{"体重",250}};   // 有两个元素
    cout << ma1.size() << endl; // 2

    // 创建一个元素数据为0的键值对对象
    map<string,int>ma;
    cout << ma.size() << endl;  // 0

    // 增
    ma["身高"] = 180;
    ma.insert(pair<string,int>("体重",150));  // 插入元素


    // 改
    ma["身高"] = 110; // 修改元素

    cout << ma.size() << endl;
    // 查
    cout << ma["身高"] << endl;
    cout << ma["体重"] << endl;


    if(ma.find("身高") == ma.end())   // find从头开始查找,如果没找到返回end
    {
        cout << "没有找到身高元素" << endl;
    }
    else
    {
        cout << ma["身高"] << endl;
    }

    // 删
    int re = ma.erase("身高");    // 返回值1表示删除成功,0失败
    cout << "身高删除:" << re << endl;

    cout << ma.size() << endl;  // 1

    re = ma.erase("月薪");
    cout << "删除:" << re << endl;

    ma.clear();
    cout << ma.size() << endl;  // 0

    return 0;
}

5 迭代器遍历

迭代器是一个特殊的指针,主要用于容器元素的读写以及遍历。

如果迭代器不进行修改,建议使用只读迭代器:const_iterator,反之则使用iterator。

#include <iostream>
#include <map>
#include <array>
#include <vector>
#include <list>
#include <deque>
using namespace std;

int main()
{

    string s = "abcdefg";
    // 迭代器遍历string
    for(string::const_iterator iter = s.begin(); iter != s.end(); iter++)
    {
        cout << *iter << " ";
    }

    cout << endl;
    cout << "--------------------" << endl;


    // 迭代器遍历array
    array<int,5> arr = {5,3,6,333,7};
    for(array<int,5>::const_iterator iter = arr.begin(); iter != arr.end();iter++)
    {
        cout << *iter << " ";
    }

    cout << endl;
    cout << "--------------------" << endl;

    // 迭代器遍历vector
    vector<string> vec(6,"hello");
    for(vector<string>::const_iterator iter = vec.begin(); iter != vec.end(); iter++)
    {
        cout << *iter << " ";
    }
    cout << endl;
    cout << "--------------------" << endl;


    // 迭代器遍历list
    list<string>lis(6,"world");
    for(list<string>::const_iterator iter = lis.begin(); iter != lis.end();++iter)
    {
        cout << *iter << " ";
    }
    cout << endl;
    cout << "--------------------" << endl;


    // 迭代器遍历队列
    deque<string> deq(6,"haha");
    for(deque<string>::iterator iter = deq.begin(); iter != deq.end();++iter)
    {
        *iter = "heiheihei";
        cout << *iter << " ";
    }
    cout << endl;
    cout << "--------------------" << endl;


    // 迭代器遍历map
    map<string,int>ma;
    ma["年龄"] = 24;
    ma["身高"] = 180;
    ma["体重"] = 140;

    for(map<string,int>::const_iterator iter = ma.begin();iter != ma.end();iter++)
    {
        // first 是键 second 是值
        cout << iter->first << " " << iter->second << endl;
    }

    return 0;
}

标签:容器,cout,int,iter,C++,lis,include,模板
From: https://blog.csdn.net/qq_64136247/article/details/142794607

相关文章

  • 关于C++中的异常概念理解
    1.基本概念异常,即exception,是C++中的基本概念之一,在某段程序发生无法继续正常执行的情况时,C++允许程序进行所谓抛出异常(有时也被称为吐出异常)的行为,这些被抛出的异常,会自动地从触发点开始向外传播,直到被捕获(有时也被称为吞下异常)或者程序终止。2.语法2.1抛出异常下面用一......
  • C++名字空间
    基本概念名字空间本质上是自定义作用域,由于C++设计的初衷是开发大规模软件,大量的软件库必然会加剧全局符号(变量、函数)的冲突,因此名字空间最基本的作用就是给不同的库和模块拥有自己的独特的作用域,处于不同名字空间中的重名符号相安无事,互不冲突,以此来大大提高编程的便利性。1.1......
  • C++:自治我的世界2D.V0.0.4.5
    更新内容:增加挖掘进度,挖掘需要时间了,但还有BUG操作说明:A,D移动;W跳跃;上,下,右+上,右+下,左+上,左+下撸方块;M开关大地图#include<bits/stdc++.h>#include<windows.h>#defineKEY_DOWN(VK_NONAME)((GetAsyncKeyState(VK_NONAME)&0x8000)?1:0)usingnamespacestd;void......
  • C++消灭星星游戏编程【目录】
    欢迎来到zhooyu的专栏。主页:【zhooyu】专栏:【C++消灭星星游戏编程】特色:【保姆级教程,含每一课程源码】致力于用最简洁的语言,最简单的方式,最易懂的知识,带大家享受编程的快乐。消灭星星游戏编程演示效果消灭星星游戏编程演示效果本专栏内容:消灭星星的小游戏保姆......
  • 洛谷题单指南-字符串-P3375 【模板】KMP
    原题链接:https://www.luogu.com.cn/problem/P3375题意解读:给定两个字符串:原串s,模式串p,求p在s中出现的所有位置,并输出p的长度为1~p.size()的子串的最长相同真前、后缀的长度。解题思路:KMP模版题,分两问,第一问通过KMP核心算法实现,第二问输出模式串的Next数组内容,接下来一一解读。......
  • 实验一 C++
    实验任务1:task1.cpp:1#include<iostream>2#include<string>3#include<vector>4#include<algorithm>56usingnamespacestd;78//声明9//模板函数声明10template<typenameT>11voidoutput(constT&c);1213......
  • 实验1 现代C++编程初体验
    任务一#include<iostream>#include<string>#include<vector>#include<algorithm>usingnamespacestd;template<typenameT>voidoutput(constT&c);voidtest1();voidtest2();voidtest3();intmain(){cout<<&qu......
  • C++编译并运行后出现Process finished with exit code 139 (interrupted by signal 11
    问题描述:        代码运行意外终止,报错信息为Processfinishedwithexitcode139(interruptedbysignal11:SIGSEGV)CMakeList文件如下:cmake_minimum_required(VERSION3.26)project(SLAM)set(CMAKE_CXX_STANDARD17)set(CMAKE_CXX_STANDARD_REQUIRED......
  • 调用sdapi/v1/txt2img接口,报错“Couldn‘t load custom C++ ops”
    后端启动stable_diffusion的api接口nohuppythonlaunch.py --use-cpuall--skip-torch-cuda-test   --api--api-log  --listen--server-name192.168.1.204>/home/third_party_app/llm/stable-diffusion-webui/logs/all.log2>&1 &服务接口http://192.168......
  • (2024最新毕设合集)基于SpringBoot的乡村书屋小程序-31881|可做计算机毕业设计JAVA、PHP
    摘要随着信息技术的快速发展和互联网的广泛普及,数字化服务的需求不断增长,乡村书屋作为传统的文化服务机构也需要适应这一变革。本研究将使用Java开发技术,通过springboot作为框架,结合微信小程序,和MySQL作为数据存储的技术,开发一套功能齐备可移动的乡村书屋小程序,旨在提升乡......