十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
iostream
定义了用于读写流的基本类型,用于处理控制台IO,fstream
定义了读写命名文件的类型,sstream
定义了读写内存string对象的类型fstream
和stringstream
都是继承自类iostream
,输入类都继承自istream
,输出类都继承自ostream
,因此在istream
对象上执行的操作,也可在ifstream
和istringstream
对象上执行while(cin >>word)
,while循环检查>>
表达式返回的流的状态,如果输入操作成功,流保持有效状态,则条件为真os<< "hello";
,文本串可能会立即打印,也可能被保存在缓冲区中,导致缓冲刷新(数据真正写到输出设备中)的原因有:① 程序正常结束;② 缓冲区满;③ 使用endl
(添加换行)或flush
(不添加)或ends
(添加空字符)操作符显式刷新缓冲区;④ 使用unitbuf
操作符使流在每次写操作后都进行一次flush
操作;⑤ 一个输出流可能被关联到另一个流,当读写被关联的流时,关联到的流缓冲区会被刷新,默认情况下cin
和cerr
都关联到cout
open()
将它与文件关联起来,如果调用失败则不能使用该对象,此时和cin
一样返回false,对一个已经打开的文件流调用open()
会失败,并导致该对象不能被使用,为了将文件流关联到另一个文件,必须先用成员函数close()
关闭已经关联的文件,当一个fstream
对象离开其作用域时,与之关联的文件会自动关闭(对象销毁时,close()
自动调用)9.1 顺序容器概述
成都创新互联公司专注于景县网站建设服务及定制,我们拥有丰富的企业做网站经验。 热诚为您提供景县营销型网站建设,景县网站制作、景县网页设计、景县网站官网定制、成都微信小程序服务,打造景县网络公司原创品牌,更为您提供景县网站排名全网营销落地服务。
- vector:可变大小数组。支持快速随机访问。在尾部之外的位置插入或删除元素很慢
- deque:双端队列。支持快速随机访问。在头尾位置插入和删除速度很快
- list:双向链表。只支持双向顺序访问。在list中任何位置进行插入和删除操作速度都很快
- forward_list:单向链表。只支持单向顺序访问。在链表中任何位置进行插入和删除操作都很快
- array:固定大小数组。支持快速随机访问。不能添加或删除元素。与内置数组相比,array是一种更安全、更易用的数组类型
- string:与vector类似,但专门用于保存字符
- 类型别名:①
iterator
/const_iterator
:此容器类型的迭代器类型;②size_type
:无符号整数类型,可保存此容器类型大可能大小;③difference_type
:带符号整数类型,可保存两个迭代器之间的距离;④vaule_type
:元素类型;⑤reference
/const_reference
:元素的左值类型- 构造函数:①
C c;
:默认构造函数,构造空容器;②C c1(c2);
:拷贝构造函数;③C c(b,e);
将迭代器b和e范围内的元素拷贝到c(array不支持);④C c{x,y,z};
:列表初始化- 赋值与swap:①
c1=c2;
;②c={x,y,z};
;③c1.swap(c2);
;(swap通常比拷贝快得多)④swap(c1,c2);
(最好统一使用非成员版本的swap,适用于泛型编程)- 大小:①
c.size()
:c中元素数目(不支持forward_list);②c.max_size()
:c中可保存的大元素数目;③c.empty()
- 添加删除元素(array不支持,不同容器中这些操作的接口都不同):①
c.insert(args)
;②c.emplace(inits)
;③c.erase(args)
;④c.clear()
- 关系运算符:①
==
/!=
:所有容器都支持;②<
/<=
/>
/>=
:无序关联容器不支持- 获取迭代器:
c.begin(),c.end()
/c.cbegin(),c.cend()
- 反向容器的额外成员(不支持forward_list):①
reverse_iterator
/const_reverse_iterator
;②c.rbegin(),c.rend()
/c.crbegin(),c.crend()
9.2 顺序容器专有操作
- 初始化(array不可用):①
C seq(n);
:seq包含n个元素,对这些元素进行值初始化,此构造函数是explicit的(string不可用);②C seq(n,t);
:seq包含n个初始化为t的元素- 赋值(array不适用):①
seq.assign(b,e);
:将seq中元素替换为迭代器b和e范围内的元素,b和e不能指向seq本身;②seq.assign(il);
:将seq中的元素替换为初始化列表il中的元素;③seq.assign(n,t);
:将seq中的元素替换为n个值为t的元素- 添加元素(array不可用):①
c.push_back(t)
/c.emplace_back(args)
:在c的尾部创建一个值为t或由args创建的元素,返回void(forward_list不可用);②c.push_front(t)
/c.emplace_front(args)
:在c的头部创建一个元素,返回void(vector和string不可用);③c.insert(p,t)
/c.emplace(p,args)
:在迭代器p指向的元素之前创建一个元素,返回指向新添加的元素的迭代器;④c.insert(p,n,t)
/c.insert(p,b,e)
/c.insert(p,il)
- 访问元素(返回的均为引用):①
c.back()
(forward_list不可用);②c.front()
;③c[n]
/c.at(n)
(只能用于string、vector、deque、array)- 删除元素:①
c.pop_back()
:删除c中尾元素(forward_list不可用);②c.pop_front()
:删除c中首元素(vector和string不可用);③c.erase(p)
:删除迭代器p所指向元素,返回被删元素之后元素的迭代器;④c.erase(b,e)
:删除迭代器b和e范围内的元素,返回最后一个被删元素之后元素的迭代器;⑤c.clear()
:删除c中所有元素,返回void- 改变容器大小:①
c.resize(n)
:调整c的大小为n个元素,添加的新元素进行值初始化,若n小于原长度,则多出的元素被丢弃;②c.resize(n,t)
:添加的新元素初始化为值t
at()
成员函数时如果下标越界,会抛出out_of_range异常insert_after
、emplace_after
、erase_after
的操作,并且定义了首前迭代器before_begin
,该迭代器允许在链表首元素之前添加或删除元素c.capacity()
:不重新分配内存空间的话,c可以保存多少元素;②c.reserve(n)
:分配至少能容纳n个元素的内存空间;③c.shrink_to_fit()
:将能保存的元素空间缩大小减为当前的元素个数9.3 额外的string操作
string s(cp,n)
:s是cp指向数组中前n个字符的拷贝,此数组至少包含n个字符;②string s(s2,pos2)
:s是s2从下标pos2开始的字符的拷贝;③string s(s2,pos2,len2)
:s是s2从下标pos2开始len2个字符的拷贝;④s.substr(pos,n)
:子字符串操作,返回一个string,包含s中从pos开始的n个字符的拷贝s,insert(pos,args)
;②s.erase(pos,len)
;③s.assign(args)
;④s.append(args)
;⑤a.replace(range,args)
。其中args可以是下列形式之一:str
/str,pos,len
/cp,len
/cp
/n,c
/b,e
/初始化列表
string::size_type
值,表示匹配发生位置的下标,如果搜索失败,则返回一个名为string::npos
的static成员,二者均为unsign类型:①s.find(args)
/s.rfind(args)
:查找s中args第一次/最后一次出现的位置;②s.find_first_of(args)
/s.find_last_of(args)
:在s中查找arg中任何一个字符第一次/最后一次出现的位置;③s.find_first_not_of(args)
/s.find_last_not_of(args)
:在s中查找第一个/最后一个不在args中的字符。其中args是以下形式之一:c,pos
/s2,pos
/cp,pos
/cp,pos,n
s.compare(args)
的参数形式有:s2
/pos1,n1,s2
/pos1,n1,s2,pos2,n2
/cp
/pos1,n1,cp
/pos1,n1,cp,n2
to_string(val)
:将数值类型转为string;②stoi(s,p,b)
/stol(s,p,b)
/stoul(s,p,b)
/stoll(s,p,b)
/stoull(s,p,b)
:将s转为整型,b表示转换用的基数,默认为10,p是size_t指针,用来保存s中第一个非数值字符的下标,默认为0,即不保存下标;③stof(s,p)
/stod(s,p)
/stold(s,p)
:将s转为浮点型9.4 容器适配器
stackstk(seq);
,默认情况下stack和queue是基于deque实现的,可以在创建一个适配器时将一个命名的顺序容器作为第二个类型参数,来重载默认容器类型stack>str_stk;
container_type
类型访问底层容器类型s.pop()
;②s.push(item)
/s.emplace(args)
:③s.top()
q.pop()
;②q.front()
;③q.back()
(只能用于queue);④q.top()
(只能用于priority_queue);⑤q.push(item)
/q.emplace(args)
10.1 泛型算法概述
中,还有一组数值泛型算法定义在头文件
中。一般情况下,这些算法并不直接操作容器,而是遍历由两个迭代器指定的一个元素范围来进行操作,如auto result=find(vec.cbegin(),vec.cend(),val);
,如果发现匹配元素,则返回指向该元素的迭代器,否则返回尾后迭代器find()
函数和count()
函数都是只读算法,定义在头文件
中的accumulate()
函数也是只读算法,equal(r1.cbegin(),r1.cend(),r2.cbegin())
函数用于比较两个序列是否保存相同的值,该函数接受三个迭代器,前两个表示第一个序列的范围,第三个表示第二个序列的首元素,这种只接受一个单一迭代器来表示第二个序列的算法,都假定第二个序列至少与第一个序列一样长fill(vec.begin(),vec.end(),10)
向给定序列中写入数据;②fill_n(vec.begin(),n,0)
:必须保证vec至少包含n个元素/fill_n(back_inserter(vec),n,0)
:使用插入迭代器back_inserter会调用push_back来添加元素;③copy(bigin(a1),end(a1),a2)
:把a1的内容拷贝给a2;④replace(ilst.cbegin(),ilst.cend(),0,10)
:将序列中所有0替换为10/replace_copy(ilst.cbegin(),ilst.cend(),back_inserter(ivec),0,10)
:ilst不变,ilst中0替换为10后拷贝到ivec中sort()
:排序;②unique()
:去除相邻重复项;以下步骤消除vector中的重复单词sort(v.begin(),v.end()); //排序
auto end_unique = unique(v.begin(),v.end()); //unique函数实现无重复排列,返回指向不重复区域的尾后迭代器
v.erase(end_unique,v.end()); //删除重复单词
10.2 定制操作
<
或=
运算符来比较。标准库还为这些算法提供了额外的版本,使得能够用自己定义的操作来代替默认运算符sort()
函数用谓词代替<
来比较元素,如sort(words.begin(),words.end(),isShorter)
,若想要保证稳定排序,可使用stable_sort()
函数[capture list] (parameter list) ->return type {function body}
其中,捕获列表是一个lambda所在函数中定义的局部变量的列表,通常为空,参数列表、返回类型、函数体与普通函数一样,但是lambda必须使用尾置返回来指定返回类型。lambda可以忽略参数列表和返回类型,但必须包含捕获列表和函数体:auto f = []{return 10;};
,忽略参数列表即参数列表为空,忽略返回类型则从函数体代码中推断返回类型,若函数体中包含单一return之外的内容且未指定返回类型,则返回void
//将words按长度稳定排序
stable_sort(words.begin(),words.end(),[](const string &a,const string &b){return a.size()return a.size()>=sz;});
//从wc迭代器开始打印单词,每个单词后接一个空格
for_each(wc,words.end(),[](const string &s){cout<
[a]
)或引用捕获[&a]
,采用值捕获的前提是变量可以拷贝,被值捕获的变量是在lambda创建时拷贝,而非调用时,因此随后对其的修改不会影响到lambda内对应的值,当以引用方式捕获一个变量时,必须保证在lambda执行时变量是存在的[&]
或[=]
,&告诉编译器采用引用捕获方式,=采用值捕获方式。当混用隐式捕获和显式捕获时,捕获列表中第一个元素必须是&或=auto f=[v]()mutable{return ++v;};
,一个引用捕获的变量是否可以修改依赖于该引用指向的是一个const类型还是非const类型bind()
函数,该函数定义在头文件
中,可以将bind函数看作一个通用的函数适配器,接受一个可调用对象,生成一个新的可调用对象auto newCallable = bind(callable,arg_list);
,当调用newCallable时,会调用callable,并传给它arg_list中的参数,arg_list是一个逗号分隔的参数列表,其中形如_n
的参数代表占位符,绑定引用参数时要使用ref()
或cref()
函数:bind(print,ref(os),_1,' ')
10.3 再探迭代器
中还定义了额外几种迭代器,包括:插入迭代器、流迭代器、反向迭代器、移动迭代器back_inserter(c)
创建一个使用c.push_back(t)
的迭代器;②front_inserter(c)
创建一个使用c.push_front(c)
的迭代器;③inserter(c,iter)
创建一个使用c.insert(iter,t)
的迭代器。使用插入器时,只需要iter=t;
即可在iter指定的位置处插入值tistream_iterator
读取输入流,ostream_iterator
向一个输出流写数据istream_iteratorin(is); //in从输入流is读取类型为T的值
istream_iteratorend; //读取类型为T的尾后迭代器
ostream_iteratorout(os); //out将类型为T的值写到输出流os中
ostream_iteratorout(os,d); //out将类型为T的值写到输出流os中,且每个值后都输出一个d,d为C风格的字符串
rbegin(),rend(),crbegin(),crend()
成员函数来获得反向迭代器,反向迭代器调用base()
成员函数可以得到正向迭代器,但是指向的元素不同(正向迭代器指向后一个元素)10.4 泛型算法结构
- 输入迭代器:只读,不写,单遍扫描,只能递增;
- 输出迭代器:只写,不读,单遍扫描,只能递增;
- 前向迭代器:可读写,多遍扫描,只能递增;
- 双向迭代器:可读写,多遍扫描,可递增递减;
- 随机访问迭代器:可读写,多遍扫描,支持全部迭代器运算
- 输入迭代器:① 用于比较两个迭代器的相等
==
和不相等运算符!=
;② 迭代器的前置和后置递增运算++
;③ 用于读取元素的解引用运算符*
(只会出现在赋值运算符的右侧);④ 用于解引用迭代器并提取成员的箭头运算符->
- 输出迭代器:与1类似,解引用运算符只能出现在赋值运算符的左侧
- 前向迭代器:1和2会破环迭代器原本结构,只能单遍扫描,前向迭代器可以保存当前状态,多次读写同一个元素
- 双向迭代器:还支持前置和后置的递减运算符
--
- 随机访问迭代器:还支持 ① 用于比较两个迭代器相对位置的关系运算符
<,<=,>,>=
;② 迭代器和一个整数值的加减运算+,+=,-,-=
;③ 用于两个迭代器的减法运算-
;④ 下标运算符iter[n],*iter[n]
(两者等价)
ostream_iterator
alg(beg,end,other args);
alg(beg,end,dest,other args);
alg(beg,end,beg2,other args);
alg(beg,end,beg2,end2,other args);
<
或==
;② 接受一个元素值的算法通常会有一个不同名的后缀加上_if
的版本,该版本接受一个谓词代替元素值,如find
和find_if
;③ 默认情况下,重排元素的算法将重排后的元素写回给定的输入序列中,通常提供额外的拷贝版本,加上后缀_copy
,如reverse
和reverse_copy
sort(),merge(),remove(),reverse(),unique()
算法,通用版本的sort要求随机访问迭代器,因此不能用于链表类型11.1 关联容器概述
map
和set
,标准库提供8个关联容器,其不同体现在3个维度上:① set或map;② 是否允许重复的关键字,允许重复关键字的容器以multi
开头;③ 是否按顺序保存元素,不按关键字顺序存储的容器以unordered_
开头multimap
定义在头文件
中,set和multiset
定义在头文件
中,unordered_multimap
和unordered_multiset
定义在头文件
和
中<
运算符来比较两个关键字
中,定义了名为pair
的标准库类型,一个pair保存两个数据成员,当创建一个pair时,必须提供两个类型名,pair的默认构造函数对数据成员进行值初始化,map中的元素是pair,标准库中的pair操作包括:①pairp
;②pairp(v1,v2)
;③make_pair(v1,v2)
;④p.first
,p.second
11.2 关联容器操作
key_value
:关键字类型;②mapped_type
:map的值类型;③value_type
:对于set为关键字类型,对于map为pair
value_type
的值的引用。对map而言,会返回一个pair类型,其first成员保存const关键字,不能修改,second成员保存值,可以修改;对set而言,会返回const关键字,不能修改。当使用一个迭代器遍历一个有序关联容器时,迭代器按关键字升序遍历元素auto m_it = m.cbegin();
while(m_it != m.cend()){cout<< m_it->first<< ":"<< m_it->second<< endl;
++m_it;
}
insert()
成员向容器中添加一个元素或一个元素范围,由于map和set包含不重复的关键字,因此插入一个已存在的元素对容器没有任何影响:①c.insert(v)
/c.emplace(args)
:v为value_type类型的对象,args用来构造一个元素;②c.insert(b,e)
/c.insert(il)
:b和e是迭代器,il是花括号列表;③c.insert(p,v)
/c.emplace(p,args)
:将迭代器p作为一个提示,指出从哪里开始搜索新元素应该存储的位置。对于不包括重复关键字的容器,添加单一元素的insert和emplace返回一个pair,pair的first成员是一个迭代器,指向具有给定关键字的元素,second成员是一个bool值,指出元素是插入成功还是已存在于容器中c.erase(k)
:从c中删除每个关键字为k的元素,返回删除元素的数量;②c.erase(p)
:从c中删除迭代器p指定的元素,返回一个p之后的迭代器;③c.erase(b.e)
:删除迭代器b和e范围中的元素,返回ec[k]
:返回关键字为k的元素,若k不在c中,添加一个关键字为k的元素,对其进行值初始化;②c.at(k)
:访问关键字为k的元素,若k不在c中,抛出一个out_of_range异常c.find(k)
:返回一个迭代器,指向第一个关键字为k的元素,若k不在容器中,则返回尾后迭代器;②c.count(k)
:返回关键字等于k的元素的数量;③c.lower_bound(k)
:返回一个迭代器,指向第一个关键字不小于k的元素(不适用于无序容器);④c.upper_bound(k)
:返回一个迭代器,指向第一个关键字大于k的元素(可与上一个函数一起给定在multimap或multiset中某个关键字对应的迭代器范围);⑤c.equal_range(k)
:返回一个迭代器pair,表示关键字等于k的元素的范围,若k不存在,pair两个成员均等于c.end()12.1 对象与内存分配关系
12.2 动态内存与智能指针
new
:在动态内存中为对象分配空间并返回一个指向该对象的指针;②delete
:接受一个动态对象的指针,销毁该对象并释放与之关联的内存shared_ptr
:允许多个指针指向同一个对象;②unique_ptr
:独占所指向的对象。标准库还定义了一个名为weak_ptr
的伴随类,它是一种弱引用,指向shared_ptr所管理的对象,这三种类型都定义在
头文件中shared_ptrp1;
,智能指针的使用方法与普通指针类似,解引用一个智能指针返回它指向的对象,如果在一个条件判断中使用智能指针,就是检测它是否为空shared_ptrsp
/unique_ptrup
:空智能指针;②p.get()
:返回p中保存的指针,要小心使用,若智能指针释放了其对象,返回的指针所指向的对象也就消失了;③swap(p,q)
/p.swap(q)
:交换p和q中的指针make_shared(args)
:返回一个指向类型T对象的智能指针,使用args初始化此对象;②sharedp(q)
:p是q的拷贝,此操作会递增q中的计数器,q中的指针必须能转换为T*;③p = q
:p和q所保存的指针必须能相互转换,此操作会递减p的引用计数,递增q的引用计数,若p的引用计数变为0,则将其管理的原内存释放;④p.use_count()
:返回与p共享对象的智能指针对象,该操作很慢,主要用于调试;⑤p.unique()
:若p.use_count()为1,返回true,否则返回falseint *p = new int;
,*p的值未定义,在类型名后跟一对括号即可对动态分配的对象进行值初始化:int *p = new int();
:*p的值为0auto p = new auto(obj);
,p指向一个与obj类型相同的对象,该对象用obj进行初始化,当且仅当括号中有单一初始化器时才可使用autoconst int *p = new const int(10);
,new返回的指针是一个指向const的指针int* p = new (nothrow) int;
的方式阻止抛出异常,这种形式的new称为定位new12.3 智能指针的使用
shared_ptrp(new int(10));
,接受指针参数的智能指针构造函数是explicit的,因此不能将一个内置指针隐式转换为一个智能指针,必须使用直接初始化的形式shared_ptrp(q)
:p管理内置指针q所指向的对象,q必须指向new分配的内存,且能偶转换为T*类型;②shared_ptrp(u)
:p从unique_ptr u那里接管了对象的所有权,将u置为空;③shared_ptrp(q,d)
:p使用可调用对象d来代替delete;④shared_ptrp(p2,d)
:p是shared_ptr p2的拷贝;⑤p.reset()
/p.reset(q)
/p.reset(q,d)
:若p是唯一指向其对象的shared_ptr,reset会释放此对象,并将p置为空;若传递了参数内置指针q,会令p指向q;若还传递了参数d,会调用d来代替deleteshared_ptrp(&con,disconnection);
,此时资源会自动释放unique_ptru(d)
:创建一个空unique_ptr,指向类型为T的对象,用类型为D的对象d代替delete;②u.release()
:放弃对指针的控制权,将u置为空并返回指针;③u.reset()
/u.reset(q)
/u.reset(nullptr)
:释放u指向的对象,如果提供了内置指针q,令u指向这个对象,否则将u置为空unique_ptrp2(p1.release())
/p2.reset(p1.release())
。直接使用release并不会释放内存,而且会丢失指针。可以拷贝或赋值一个将要被销毁的unique_ptr,如从函数返回一个unique_ptr。重载一个unique_ptr的删除器必须在尖括号中提供删除器类型:unique_ptrp(&con,disconnection);
weak_ptrw(sp)
/w = sp
:将w指向shared_ptr指针sp指向的对象;②w.reset()
:将w置为空;③w.use_count()
:与w共享的shared_ptr的数量;④w.expired()
:若w.use_count()为0,返回true,否则返回false;⑤w.lock()
:若w.expired()为true,返回一个空shared_ptr,否则返回一个指向w的对象的shared_ptr12.4 动态数组
int *p = new int[10];
,此时会得到一个元素类型的指针(动态数组并不是数组类型),由于分配的内存并不是一个数组类型,因此不能对动态数组调用begin或end。new分配的对象,无论是单个分配还是数组中的都是默认初始化的,加上空括号后变为值初始化:int *p = new int[10]();
,释放动态数组:delete [] p;
unique_ptrp(new int[]10);
,可以使用下标运算符来访问数组中的元素。与unique_ptr不同,shared_ptr不直接支持管理动态数组,如果要使用shared_ptr管理,必须提供自定义的删除器shared_ptrp(new int[10],[](int *p){delete[] p});
,并且不能使用下标运算符,只能用gert()获取内置指针后再访问数组元素allocator
定义在头文件
中,提供了一种类型感知的内存分配方法,分配的内存是未构造的allocatora
:定义一个可以为类型T分配内存的allocator对象;②a.allocator(n)
:分配一段可以保存n个类型为T的对象的未构造的内存;③a.deallocator(p,n)
:释放从T*指针p开始的n个T类型对象的内存,p必须分配过n个T类型对象,且已被创建的对象必须调用过destroy;④a.construct(p,args)
:在p指向的未构造内存中通过args构造一个对象;⑤a.destory(p)
:对p指向的对象执行析构函数;⑥uninitialized_copy(b,e,b2)
/uninitialized_copy_n(b,n,b2)
:将迭代器b到e中的元素拷贝到迭代器b2指向的未构造内存中,b2的内存必须足够大;⑦uninitialized_fill(b,e,t)
/uninitialized_fill_n(b,n,t)
:在迭代器b到e的未构造内存中放入值为t的拷贝你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧