嵌入式C++(十一)

简介: 嵌入式C++(十一)

一 forward_list


1.基本概念


forward_list 始于c++11,是一个single linked list管理元素
头文件 #include <forward_list>
namespace std{
  template<typename T,typename Allocator = allocator>
     class forward_list;
};
元素类型:可以为任意类型的T,默认的内存类型是allocator


2.forward_list的能力


forward_list是一个行为受限制的list,不能走回头路,凡是list没有的功能,forward_list都不提供
优点:内存用量少,行动略迅速
设计目标:和自己写的c-style linked list比较,没有任何空间和时间上的额外开销
      如果任何方法和这两个要求相违背,就应该放弃该方法(API)


3.for_ward的约束


1.只提供前向迭代器,而不是双向迭代器,不支持反向迭代器
2.不提供成员函数size()--->不允许空间时间的浪费
  因为size()被调用,要么直接计算其大小,要么需要提供一个额外的数据栏记录其大小
  只要某个有能力改变其大小的函数被调用,这个数据栏都要去更新检查
  -->解决方案:1.自行追踪 2.使用list
3.forward_list没有指向最末元素的anchor(锚点),所以不提供给处理最末元素的成员函数
    比如:push_back(),pop_back()都不提供
    -->解决方案:1.提供特殊版本(xx_after),(before_xx)

4.注意事项


1.forward_list不支持随机访问,如果想要访问第n个元素,必须遵循link所形成的串链“航行”前n个元素,因此速度相当满。
2.在任意位置安插和移除,因为没有任何元素需要搬移,只有若干个pointer需要被涂改
3.在这个里面提供特殊成员函数,是一般算法的快速版本。
#include <iostream>
#include <forward_list>
#include <string>
using namespace std;
int main(void)
{
  forward_list<int> f1 = { 1,2,3,4,5,6 };
  f1.emplace_front(7);
  f1.emplace_after(f1.before_begin(), 88);  //第一个参数传入要插入的前一个位置,支持插入一个元素
  for (auto &l : f1)
  {
  cout << l << " ";
  }
  cout << endl;
  /*for (auto it = f1.begin(); it != f1.end(); it++)
  {
  cout << *it << " ";
  }
  cout << endl;*/
  f1.insert_after(f1.before_begin(), {11,22,33});  //允许插入一个区间,一个元素,或者n个相同的元素
  for (auto &l : f1)
  {
  cout << l << " ";
  }
  cout << endl;
  //f1.insert_after(f1.end(), { 44,55,66 });  //如果想要在最后一个位置插入,必须要传入最后一个元素的位置
  forward_list<int> l1 = { 1,2,3,4,5 };
  forward_list<int> l2 = { 97,98,99 };
//接合函数
  //l2.splice_after()
  //void splice_after(const_iterator pos, forward_list& other,const_iterator it);
//将l1内部第一个数值为3的元素搬移到l2内第一个数值为99元素的前方:
  auto pos1 = l1.cbefore_begin();
  for (auto t1 = l1.begin(); t1 != l1.end(); ++t1,++pos1)
  {
  if (*t1 == 3)
  {
    break;  
  }
  }
  //在l2中找99
  auto pos2 = l2.cbefore_begin();
  for (auto t2 = l2.begin(); t2 != l2.end(); ++t2, ++pos2)
  {
  if (*t2 == 99)
  {
    break;
  }
  }
  l2.splice_after(pos2,l1,pos1);
  for (auto &l : l2)
  {
  cout << l << " ";
  }
  cout << endl;
  for (auto &l : l1)
  {
  cout << l << " ";
  }
  cout << endl;
  return 0;
}


练习 for_ward_list运用实例


//创建两个forward_list list1 list2
forward_list<int> list1 = {1,2,3,4};
forward_list<int> list2 = {77,88,99};
//在list2开始的位置插入6个新元素
//1.在77的前面插入99这个元素
//2.使用头插法插入元素10
//3.在第一个元素的前面插入一个区间【10,11,12,13】
//在list1的开头插入list2中所有的元素
//删除list2中第二个元素和99后面的所有元素(提示:使用find查找算法,可以找到99元素的位置)
                                              //find(beign,end,val);
//给list1排序,并且将其赋值给list2,并且移除所有相邻重复的元素
//合并list1和list2到list1中
//上述所有结果封装成函数进行遍历


#include <iostream>
#include <forward_list>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
void printList(const string &s, const forward_list<int> &l1, const forward_list<int> &l2)
{
  cout << s << endl;
  cout << "list1:" << endl;
  copy(l1.begin(),l1.end(), ostream_iterator<int>(cout, " "));  //关联cout,设置分隔符(输出迭代器)
                  //元素拷贝到ostream_iterator所指向的对象cout
  cout << endl;
  cout << "list2:" << endl;
  copy(l2.begin(), l2.end(), ostream_iterator<int>(cout, " "));  //关联cout,设置分隔符(输出迭代器)
                  //元素拷贝到ostream_iterator所指向的对象cout
  cout << endl;
}
int main(void)
{
  //创建两个forward_list list1 list2
  forward_list<int> list1 = { 1,2,3,4 };
  forward_list<int> list2 = { 77,88,99 };
  printList("init list1 list2:",list1,list2);
  //在list2开始的位置插入6个新元素
  //1.在77的前面插入99这个元素
  list2.emplace_after(list2.cbefore_begin(), 99);
  //2.使用头插法插入元素10
  list2.emplace_front(10);
  //3.在第一个元素的前面插入一个区间【10,11,12,13】
  list2.insert_after(list2.before_begin(), {10,11,12,13});
  printList("插入六个元素:", list1, list2);
  //在list1的开头插入list2中所有的元素
  list1.insert_after(list1.before_begin(),list2.begin(),list2.end());
  printList("在list1的开头插入list2中所有的元素:", list1, list2);
  //删除list2中第二个元素和99后面的所有元素(提示:使用find查找算法,可以找到99元素的位置)
              //find(beign,end,val);
  list2.erase_after(list2.begin());
  list2.erase_after(find(list2.begin(), list2.end(), 99), list2.end());
  printList("删除list2中第二个元素和99后面的所有元素:", list1, list2);
  //给list1排序,并且将其赋值给list2,并且移除所有相邻重复的元素
  list1.sort();
  list2 = list1;
  printList("给list1排序,并且将其赋值给list2:", list1, list2);
  list1.unique();
  printList("移除所有相邻重复的元素:", list1, list2);  
  //合并list1和list2到list1中
  list1.merge(list2);
  printList("合并list1和list2到list1中:", list1, list2);
  //上述所有结果封装成函数进行遍历
  return 0;
}


二 关联式容器


2.1 pair对组


#include <iostream>
#include <forward_list>
#include <string>
#include <algorithm>
#include <iterator>
#include <vector>
using namespace std;
template <typename T1,typename T2>
class MyPair
{
public:
  T1 first;
  T2 second;
};
int main(void)
{
  pair<int, string> p1;
  p1.first = 1;
  p1.second = "hello world";
  MyPair<int, string> p2;
  p2.first = 2;
  p2.second = "nihao nanjing";
  pair<int, string> p3(1,"hello");
  pair<int, string> p4 = make_pair(1, "hello world"); //c++11
  cout << p4.first << endl;
  cout << p4.second << endl;
//编写程序,将每个string和int存入一个pair中,pair保存在一个vector中,遍历输出每个string和int
  string s[10];
  int v[10];
  for (int i = 0; i < 10; i++)
  {
  s[i] = "hello";
  v[i] = i + 1;
  }
  vector<pair<string, int>> data;
  for (int i = 0; i < 10; i++)
  {
  //data.emplace_back(pair<string, int>(s[i], v[i]));
  //data.emplace_back(make_pair(s[i], v[i]));
  data.push_back({s[i],v[i]});
  }
  for (auto &d : data)
  {
  cout << d.first << " " << d.second << endl;
  }
  return 0;
}


2.2 tuple(元组)


一个tuple中可以有任意数量的成员


tuple<int, string, int> t1(1,"zhangsan",12);
  cout << std::tuple_size<decltype(t1)>::value << endl;
  cout << t1 << endl;
  cout << "id = " << std::get<0>(t1) << endl;
  cout << "name = " << std::get<1>(t1) << endl;
  cout << "age = " << std::get<2>(t1) << endl;
  //tie解包
  int id;
  string name;
  int age;
  std::tie(id, name, age) = t1;
  cout << "id = " << id << endl;
  cout << "name = " << name << endl;
  cout << "age = " << age << endl;


2.3 set的使用


#include <iostream>
#include <forward_list>
#include <string>
#include <algorithm>
#include <set>
using namespace std;
class Student
{
  friend ostream& operator<<(ostream &out, const Student &t);
public:
  Student(int i,string n)
  {
  cout << "student" << endl;
  id = i;
  name = n;
  }
  ~Student()
  {
  cout << "~student" << endl;
  }
  bool operator<(const Student &s) const
  {
  return this->id < s.id;
  }
  bool operator>(const Student &s) const
  {
  return this->id > s.id;
  }
private:
  int id;
  string name;
};
ostream& operator<<(ostream &out, const Student &t)
{
  out << "id = " << t.id << " name = " << t.name << endl;
  return out;
}
template <typename T,typename U = std::less<T>>
void printSet(const set<T,U> &s)
{
  for (auto &s1 : s)
  {
  cout << s1 << " ";
  }
  cout << endl;
}
int main(void)
{
  Student s1(3, "aa");
  Student s2(4, "bb");
  Student s3(8, "cc");
  Student s4(9, "dd");
  Student s5(1, "ee");
  Student s6(6, "ff");
  Student s7(7, "gg");
  //set<Student> s;
  set<Student, greater<Student>> s;
  s.insert(s1);
  s.insert(s2);
  s.insert(s3);
  s.insert(s4);
  s.insert(s5);
  s.insert(s6);
  s.emplace(s7);
  s.emplace(10, "hh");
  s.emplace(Student(11,"oo"));
  printSet<Student>(s);
  cout << "集合大小:" << s.size() << endl;
  s.erase(s.begin());
  printSet(s);
  cout << "set区间删除" << endl;
  s.erase(--s.end(), s.end());
  printSet(s);
  cout << "删除具体的元素" << endl;
  s.erase(s1); //按照id查找并删除
  printSet(s);
  cout << "set的查找" << endl;
  auto it = s.find(s2);
  if (it == s.end())
  {
  cout << "对象不存在" << endl;
  }
  else
  {
  cout << *it << endl;
  }
  cout << "set的统计" << endl;
  cout << s.count(s6) << endl;
  Student ss(0, "bb");
//如果lower_bound和upper_bound返回的是相等的迭代器,说明元素不存在
  cout << "lower_bound" << endl;
  it = s.lower_bound(ss);  //返回元素ss的第一个可安插的位置,也就是元素值>=ss的第一个元素的位置
  if (it == s.end())
  {
  cout << "不存在" << endl;
  }
  else
  {
  cout << *it << endl;
  }
  cout << "upper_bound" << endl;
  it = s.upper_bound(ss);  //返回元素ss的最后一个可安插的位置,也就是元素值>=ss的第一个元素的位置
  if (it == s.end())
  {
  cout << "不存在" << endl;
  }
  else
  {
  cout << *it << endl;
  }
  /************************************************************************/
  /* equal_range:接受一个关键词,返回一个pair对组
  若关键词存在,第一个迭代器指向第一个与关键词匹配的元素,第二个指向最后一个匹配元素之后的位置
  若未找到匹配,则两个迭代器相等,都指向关键词可插入的位置。
  */
  /************************************************************************/
  cout << "equal_range" << endl;
  pair<set<Student>::iterator, set<Student>::iterator> p;
  p = s.equal_range(ss);
  /*cout << *p.first << endl;
  cout << *p.second << endl;*/
  return 0;
}


2.4 map


每个元素都是key/value的pair,其中key是排序的准则,每个key只能出现一次,不许重复,map也被称为

关联式数组,,也就是“索引可以为任意类型”的数组。


#include <iostream>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
template<typename T1,typename T2>
void printMap(const map<T1, T2> &m)
{
  for (auto &m1 : m)
    {
      cout << "key: " << m1.first << " value: " << m1.second << endl;
    }
}
int main(void)
{
    map<int, string> m; //key是int型,value是string类型
    m.insert(pair<int,string>(3,"aa"));
    m.insert(pair<int, string>(4, "bb"));
    m.insert(make_pair(5,"cc"));
    m.insert(make_pair(6, "dd")); //make_pair组合一组数据插入
    m.insert(map<int, string>::value_type(7,"ee"));
    m.insert(map<int, string>::value_type(8, "ff")); //通过map内部的静态成员函数插
    m[9] = "ww"; //map重载了【】运算符
    m[10] = "qq";
    m.emplace(11,"tt");
    m.emplace_hint(m.begin(), 19, "aa");
    printMap(m);
    pair<map<int,string>::iterator,bool> p = m.insert(make_pair(5, "ll")); //返回一个pair
    if (p.second == false)
    {
        cout << "插入失败" << endl;
        cout << "key: " <<p.first->first<< " value: " << p.first->second <<
        endl;
    }
    else
    {
     cout << "插入成功" << endl;
    }
    m[3] = "ww";
    printMap(m);
    //map删除指定位置
    //map删除具体元素(根据KEY值删除)
    cout << "map删除具体元素(根据KEY值删除)" << endl;
    m.erase(4);
    printMap(m);
    return 0;
}
相关文章
|
6月前
|
开发框架 Linux C语言
C、C++、boost、Qt在嵌入式系统开发中的使用
C、C++、boost、Qt在嵌入式系统开发中的使用
211 1
|
6月前
|
算法 Linux 程序员
嵌入式工程师以及C++程序员到公司就业需要掌握那些技术?
嵌入式工程师以及C++程序员到公司就业需要掌握那些技术?
|
6月前
|
数据处理 C++ UED
如何作为一个嵌入式软件工程师博主获得铁粉:C/C++ 技术分享之道
如何作为一个嵌入式软件工程师博主获得铁粉:C/C++ 技术分享之道
115 0
|
6月前
|
C语言 数据安全/隐私保护 C++
嵌入式中如何把C++代码改写成C语言代码
嵌入式中如何把C++代码改写成C语言代码
75 0
|
6月前
|
存储 缓存 Java
嵌入式系统中C++内存管理基本方法
嵌入式系统中C++内存管理基本方法
136 0
|
6月前
|
存储 编译器 程序员
嵌入式系统中C++基础知识精髓
嵌入式系统中C++基础知识精髓
110 0
|
6月前
|
关系型数据库 数据库 C++
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)
嵌入式数据库sqlite3【基础篇】基本命令操作,小白一看就懂(C/C++)
|
6月前
|
存储 编译器 C++
嵌入式中C++ 编程习惯与编程要点分析
嵌入式中C++ 编程习惯与编程要点分析
53 1
|
6月前
|
架构师 数据挖掘 程序员
嵌入式系统中C++ 类的设计和实现分析
嵌入式系统中C++ 类的设计和实现分析
72 1
|
6月前
|
算法 小程序 编译器
嵌入式中C++开发的基本操作方法
嵌入式中C++开发的基本操作方法
59 0