Haohao Notes

DREAM OF TECHNICAL ACHIEVEMENT

0%

程序和进程

  • 程序,是指编译好的二进制文件,在磁盘上,不占用系统资源(cpu、内存、打开的文件、设备、锁….)

  • 进程,是一个抽象的概念,与操作系统原理联系紧密。进程是活跃的程序,占用系统资源。在内存中执行。(程序运行起来,产生一个进程)

程序 → 剧本(纸)

进程 → 戏(舞台、演员、灯光、道具…)

同一个剧本可以在多个舞台同时上演。同样,同一个程序也可以加载为不同的进程(彼此之间互不影响)

如:同时开两个终端。各自都有一个bash但彼此ID不同。

并发

并发,在操作系统中,一个时间段中有多个进程都处于已启动运行到运行完毕之间的状态。但,任一个时刻点上仍只有一个进程在运行。

例如,当下,我们使用计算机时可以边听音乐边聊天边上网。 若笼统的将他们均看做一个进程的话,为什么可以同时运行呢,因为并发。

分时复用cpu

阅读全文 »

map/multimap的简介

  • map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对。它提供基于key的快速检索能力。
  • map中key值是唯一的。集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
  • map的具体实现采用红黑树变体的平衡二叉树的数据结构。在插入操作和删除操作上比vector快。
  • map可以直接存取key所对应的value,支持[]操作符,如map[key]=value。
  • multimap与map的区别:map支持唯一键值,每个键只能出现一次;而multimap中相同键可以出现多次。multimap不支持[]操作符。

头文件 #include <map>

map and multimaps

map/multimap采用模板类实现,对象的默认构造形式:

  • map<T1,T2> mapTT;
  • multimap<T1,T2> multimapTT;

如:

  • map<int, char> mapA;
  • map<string,float> mapB;

其中T1,T2还可以用各种指针类型或自定义类型

map的插入与迭代器

阅读全文 »

set/multiset的简介

  • set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
    set采用红黑树变体的数据结构实现,红黑树属于平衡二叉树。在插入操作和删除操作上比vector快。
  • set不可以直接存取元素。(不可以使用at.(pos)与[]操作符)。
  • multiset与set的区别:set支持唯一键值,每个元素值只能出现一次;而multiset中同一值可以出现多次。
  • 不可以直接修改set或multiset容器中的元素值,因为该类容器是自动排序的。如果希望修改一个元素值,必须先删除原有的元素,再插入新的元素。

头文件 #include <set>

图解

set/multiset对象的默认构造

  • set<int> setInt; //一个存放int的set容器。
  • set<float> setFloat; //一个存放float的set容器。
  • set<string> setString; //一个存放string的set容器。
  • multiset<int> mulsetInt; //一个存放int的multi set容器。
  • multi set<float> multisetFloat; //一个存放float的multi set容器。
  • multi set<string> multisetString; //一个存放string的multi set容器。

set的插入与迭代器

  • set.insert(elem); //在容器中插入元素。
  • set.begin(); //返回容器中第一个数据的迭代器。
  • set.end(); //返回容器中最后一个数据之后的迭代器。
  • set.rbegin(); //返回容器中倒数第一个元素的迭代器。
  • set.rend(); //返回容器中倒数最后一个元素的后面的迭代器。
1
2
3
4
5
6
7
8
set<int> setInt;
setInt.insert(3); setInt.insert(1);setInt.insert(5);setInt.insert(2);
for(set<int>::iterator it=setInt.begin(); it!=setInt.end(); ++it)
{
int iItem = *it;
cout << iItem; //或直接使用cout << *it
}
//这样子便顺序输出 1 2 3 5。

set.rbegin()set.rend()略。

阅读全文 »

List简介

  • list是一个双向链表容器,可高效地进行插入删除元素。
  • list不可以随机存取元素,所以不支持at.(pos)函数与[]操作符。It++(ok) it+5(err)

头文件 #include <list>

list对象的默认构造

list采用采用模板类实现,对象的默认构造形式:list<T> lstT;
如:

  • list<int> lstInt; //定义一个存放int的list容器。
  • list<float> lstFloat; //定义一个存放float的list容器。
  • list<string> lstString; //定义一个存放string的list容器。
  • list<xxxx> lstXxxx; //定义一个存放xxxx的list容器。

尖括号内还可以设置指针类型或自定义类型。

list头尾的添加移除操作

  • list.push_back(elem); //在容器尾部加入一个元素
  • list.pop_back(); //删除容器中最后一个元素
  • list.push_front(elem); //在容器开头插入一个元素
  • list.pop_front(); //从容器开头移除第一个元素
1
2
3
4
5
6
7
8
9
10
11
12
13
list<int> lstInt;
lstInt.push_back(1);
lstInt.push_back(3);
lstInt.push_back(5);
lstInt.push_back(7);
lstInt.push_back(9);
lstInt.pop_front();
lstInt.pop_front();
lstInt.push_front(11);
lstInt.push_front(13);
lstInt.pop_back();
lstInt.pop_back();
// lstInt {13,11,5}
阅读全文 »

Queue简介

queue是队列容器,是一种“先进先出”的容器。

头文件 #include <queue>

queue对象的默认构造

queue采用模板类实现,queue对象的默认构造形式:queue<T> queT;
如:

  • queue<int> queInt; //一个存放int的queue容器。
  • queue<float> queFloat; //一个存放float的queue容器。
  • queue<string> queString; //一个存放string的queue容器。
  • queue<xxxx> queXxxx; //一个存放xxxx的queue容器。

尖括号内还可以设置指针类型或自定义类型。

queue的push()与pop()方法

  • queue.push(elem); //往队尾添加元素
  • queue.pop(); //从队头移除第一个元素
1
2
3
4
5
queue<int> queInt;
queInt.push(1);queInt.push(3);
queInt.push(5);queInt.push(7);
queInt.push(9);queInt.pop();
queInt.pop();
阅读全文 »

Stack简介

  • stack是堆栈容器,是一种“先进后出”的容器。
  • stack是简单地装饰deque容器而成为另外的一种容器。

头文件 #include <stack>

stack对象的默认构造

stack采用模板类实现, stack对象的默认构造形式: stack <T> stkT;

  • stack <int> stkInt; //一个存放int的stack容器。
  • stack <float> stkFloat; //一个存放float的stack容器。
  • stack <string> stkString; //一个存放string的stack容器。
  • stack <xxx> xxx; //尖括号内还可以设置指针类型或自定义类型。

stack的push()与pop()方法

  • stack.push(elem); //往栈头添加元素
  • stack.pop(); //从栈头移除第一个元素
1
2
3
4
5
stack<int> stkInt;  	
stkInt.push(1);stkInt.push(3);stkInt.pop();
stkInt.push(5);stkInt.push(7);
stkInt.push(9);stkInt.pop();
stkInt.pop();

此时stkInt存放的元素是1,5

阅读全文 »

Deque简介

  • deque是“double-ended queue”的缩写,和vector一样都是STL的容器,deque是双端数组,而vector是单端的。
  • deque在接口上和vector非常相似,在许多操作的地方可以直接替换。
  • deque可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法,这个等下会详讲)。
  • deque头部和尾部添加或移除元素都非常快速。但是在中部安插元素或移除元素比较费时。

头文件#include <deque>

deque对象的默认构造

deque采用模板类实现,deque对象的默认构造形式:deque<T> deqT;

1
2
3
4
deque <int> deqInt;            //一个存放int的deque容器。
deque <float> deq Float; //一个存放float的deque容器。
deque <string> deq String; //一个存放string的deque容器。
deque <xxx> deq xxx; //尖括号内还可以设置指针类型或自定义类型。

deque末尾的添加移除操作

理论知识:

  • deque.push_back(elem); //在容器尾部添加一个数据
  • deque.push_front(elem); //在容器头部插入一个数据
  • deque.pop_back(); //删除容器最后一个数据
  • deque.pop_front(); //删除容器第一个数据
1
2
3
4
5
6
7
8
9
10
11
12
13
deque<int> deqInt;
deqInt.push_back(1);
deqInt.push_back(3);
deqInt.push_back(5);
deqInt.push_back(7);
deqInt.push_back(9);
deqInt.pop_front();
deqInt.pop_front();
deqInt.push_front(11);
deqInt.push_front(13);
deqInt.pop_back();
deqInt.pop_back();
//deqInt { 13,11,5}
阅读全文 »

Vector容器

Vector容器简介

  • vector是将元素置于一个动态数组中加以管理的容器。
  • vector可以随机存取元素(支持索引值直接存取, 用[]操作符或at()方法)。
  • vector尾部添加或移除元素非常快速。但是在中部或头部插入元素或移除元素比较费时

vector对象的默认构造

vector采用模板类实现,vector对象的默认构造形式

  • vector<T> vecT;
  • vector<int> vecInt; //一个存放int的vector容器。
  • vector<float> vecFloat; //一个存放float的vector容器。
  • vector<string> vecString; //一个存放string的vector容器。
  • vector<xxx> vecXxx; //尖括号内还可以设置指针类型或自定义类型。
1
2
3
Class CA{};
vector<CA*> vecpCA; //用于存放CA对象的指针的vector容器。
vector<CA> vecCA; //用于存放CA对象的vector容器。由于容器元素的存放是按值复制的方式进行的,所以此时CA必须提供CA的拷贝构造函数,以保证CA对象间拷贝正常。

vector对象的带参数构造

理论知识

  • vector(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。注意该区间是左闭右开的区间。
  • vector(n,elem); //构造函数将n个elem拷贝给本身。
  • vector(const vector &vec); //拷贝构造函数
阅读全文 »

String概念

string是STL的字符串类型,通常用来表示字符串。而在使用string之前,字符串通常是用char表示的。string与char都可以用来表示字符串,那么二者有什么区别呢。

string和char*的比较

  • string是一个类, char*是一个指向字符的指针。
  • string封装了char,管理这个字符串,是一个char型的容器。
  • string不用考虑内存释放和越界。
  • string管理char*所分配的内存。每一次string的复制,取值都由string类负责维护,不用担心复制越界和取值越界等。
  • string提供了一系列的字符串操作函数.查找find,拷贝copy,删除erase,替换replace,插入insert

string的构造函数

默认构造函数:

  • string(); //构造一个空的字符串string s1。

拷贝构造函数:

  • string(const string &str); //构造一个与str一样的string。如string s1(s2)。

带参数的构造函数

阅读全文 »

STL(标准模板库)理论基础

基本概念

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

STL的从广义上讲分为三类:algorithm(算法)、container(容器)和iterator(迭代器),容器和算法通过迭代器可以进行无缝地连接。几乎所有的代码都采 用了模板类和模板函数的方式,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。在C++标准中,STL被组织为下面的13个头文 件:<algorithm>、<deque>、<functional>、<iterator>、<vector>、<list>、<map>、<memory>、<numeric>、<queue>、<set>、<stack><utility>

STL.png

STL详细的说六大组件

  • 容器(Container)
  • 算法(Algorithm)
  • 迭代器(Iterator)
  • 仿函数(Function object)
  • 适配器(Adaptor)
  • 空间配制器(allocator)

使用STL的好处

  1. STL是C++的一部分,因此不用额外安装什么,它被内建在你的编译器之内。
  2. STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但是这种分离确实使得STL变得非常通用。
    例如,在STL的vector容器中,可以放入元素、基础数据类型变量、元素的地址;
    STL的sort()函数可以用来操作vector,list等容器。

  3. 程序员可以不用思考STL具体的实现过程,只要能够熟练使用STL就OK了。这样他们就可以把精力放在程序开发的别的方面。

  4. STL具有高可重用性,高性能,高移植性,跨平台的优点。

  • 高可重用性:STL中几乎所有的代码都采用了模板类和模版函数的方式实现,这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。关于模板的知识,已经给大家介绍了。
  • 高性能:如map可以高效地从十万条记录里面查找出指定的记录,因为map是采用红黑树的变体实现的。(红黑树是平横二叉树的一种)
  • 高移植性:如在项目A上用STL编写的模块,可以直接移植到项目B上。
  • 跨平台:如用windows的Visual Studio编写的代码可以在Mac OS的XCode上直接编译。
阅读全文 »