C++primer笔记:IO库、顺序容器、关联容器、面向对象、泛型算法、模板和泛型编程

第八章:IO库不直接来处理输入输出,而是通过在标准库中的一些类型来处理io

istream
ostream
cin
cout
cerr
getline函数

iostream:定义了用于基本读写流的基本类型
fstream:  定义了基本的读写命名文件的类型
sstream:定义了读写内存的string对象的类型

IO对象无拷贝或者赋值

条件状态:IO定义了一些函数和标志,可以帮助我们访问和操作流得条件状态
strm::iostate   条件状态的完整功能
strm::badbit    流已崩溃
strm::failbit   io操作已经失败
strm:eofbit    流到达了文件的结束
strm:goodbit   指出流未处于错误状态

管理条件状态:
管理输出缓冲:
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————
文件输入输出:
头文件的fstream:
ifstream:给定文件读取数据,
ofstream: 给定文件写入数据,
fstream:  读写给定文件

fstream fstrm;
fstream fstrm;
fstream.open();
fstream.close();
fstream.is_close();

文件模式:
每个流对应的一个关联模式:文件模式
in      读方式打开
out     写方式打开
app     每次写操作前均定位到文件末尾
ate     打开文件后就立即定位到文件末尾
trunc   截断文件
binary  二进制文件

——————————————————————————————————————————————————————————————————————————————————————————————————————————————————
string流
sstream头文件定义了三个类型来支持内存IO
istringstream: 从string读取数据
ostringstream: 向string写入数据
stringstream :既可以从string也可以向string写数据

sstream中定义的类型继承来至于我们使用的iostream头文件的流的类型
还增加了与string流相关类型的
关系:
                    iostream
                       |
                    sstream
                       |
                    istringstream、ostringstream   

总结:
C++使用标准库类来处理面向流的输入输出

iostream:处理控制台IO
fstream: 处理命名文件IO
stringstream:完成内存的string的IO

条件状态:可以被任何流类使用的一组函数和标志,用来指出给定流是否可用
文件模式:类fstream定义的一组标志,在打开文件的时候,控制文件如何被使用

-iostream
  -sstream
    -stringstream、istringstream、ostringstream
    -fstream、ifstream、ofstream

__________________________________________________________________________________________________________________
第九章:容器

9.1顺序容器:
vector:可变大小数组,快速随机访问,在尾部之外的位置插入或者删除元素都很慢,尾部插入删除速度快
array: 固定大小数组,快速随机访问
string:与vector相似,但专门用于保存字符,字符串数组,随机访问快,尾部插入删除速度快,

list:双向链表,只支持双向顺序访问,任何位置插入删除都很快
forward_list:单向链表,只支持单向顺序访问,任何位置插入删除都很快
deque:双端队列,支持快速随机访问,在头尾插入删除很快,

9.2容器操作:
类型别名:
iterator:此容器的迭代器
const_iterator:
size_type: 容器的大小,这个大小指的是在特定类型下的大小
value_type:元素值对应的类型
difference_type:两个不同迭代器之间的距离

赋值和swap:
swap(a,b)
a.swap(b)
C1={a,b,c...}

大小:
c.size()
c.max_size()
c.empty()

添加删除元素:
c.insert()
c.clear()
c.erase()

获取迭代器
c.begin(),c.end()
c.cbenin(),c.cend()

反向容器:
reverse_iterator:按逆序寻址元素的迭代器
c.rbegin(),c.rend():
c.crbegin(),c.crend():

迭代器范围:由一对迭代器表示,两个迭代器分别指向同一个容器中的元素
分别被称为begin和end,他们标记了容器元素的一个范围
第二个迭代器指向尾元素之后的位置,[begin,end),但不包含最后一个元素,也不能指向begin之前的元素
[begin,end)

使用左闭合的编程假定:while(begin!=end)

c.begin()
c.rbegin()   //reverse
c.cbegin()   //const
c.crbegin()  //const_reverse

注:以C开头的版本都是C++新引入的,不以C开头的都是被重载过的

assign()
(1) list<string> names;
    vector<const char*> old;
    names.assign(old.cbegin(),old.cend());

(2) list1.assign(10,"table");

array
与内置的数组不同,标准库array允许赋值,赋值左右两边的运算对象具有相同的类型
array<int,10> a1={1,2,3,4,5,6,7,8,9,0};
array<int,10> a2={0};
array不支持assign,不允许用花括号包围的值列表进行赋值

swap
使用swap:交换两个相同的类型容器的内容
调用swap之后,两个容器中的元素将会交换,除array之外,交换两个容器内容的操作保证会很快,
元素本身未交换,swap只是交换了两个容器内部的数据结构
但是对于array,会真正交换两个元素

元素不会被移动。意味着除string外,指向容器的迭代器,引用,指针在swap操作之后不会失效
他们仍然指向swap操作之前的哪些元素,但是swwap之后,这些元素已经属于不同的元素了
但是对一个string的调用会导致swap之后的迭代器和引用,指针会失效

9.3 顺序容器操作
添加元素:  c.push_back(t)   尾部创建
          c.push_front(t)  头部创建
          push_back():  将元素追加到vector的尾部
          push_front():将元素追加到vector的头部
          insert():    将元素追加到vector的任意位置
          emplace_back:直接在内存中创建元素
          push_back:  在容器的局部创建元素

访问元素:  c.at(n)
          c.back()
          c.front()
          c[n]

删除元素: c.pop_back()
          c.pop_front()
          c.erase(ele1,ele2)
          c.clear()

改变容器的大小:resize()

容器操作可能使迭代器失效:
  (1):如果是vector或者string,若存储空间重新分配,则指向迭代器或者指针,引用会失效
                                   若存储空间未重新分配,则插入之前的会不变,之后的失效

  (2):deque:插入到首尾之外的会失效,在首尾添加会使迭代器失效,但引用和指针不变

  (3):list和for_ward:指向容器的迭代器(尾后和首前)和指针、引用仍有效

额外的string操作
1:构造string的其他方法:
   string(s1,pos,len);
   s.substr(0,5);

2:改变string的其他方法:
  assign、insert、erase
  append、replace函数 

3:string的搜索操作
  s.find(args);           搜索出现的第一次的位置
  s.rfind(args);          搜索出现的最后一次的位置
  s.find_first_of(args);  搜索任何一个字符出现的第一次的位置
  s.find_last_of(args);    搜索任何一个字符出现的最后一次的位置
  s.find_first_not_of(args);搜索任何一个字符不出现的第一次的位置
  s.find_last_not_of(args); 搜索任何一个字符不出现的最后一次的位置

4 compare函数
  compare函数与C语言函数的strcmp函数类似,
  s.compare返回0,正数,负数

5 数值转换函数:  to_string(val);  转换成string
                stod(s);         转换成double
                stof(s);         转换成float
                stoi(s);         转换成int
                stol(s);         转换成long
                stoul(s);        转换成unsigned long
                stoull(s);       转换成unsigned long long

容器适配器:stack、queue、priority_queue
除了顺序容器之外:还定义了3个顺序适配器:stack、queue、priority_queue
一个适配器是一种机制,能使某种事物看起来像另外一些事物,
一个适配器接受一种已有的容器,使其行为看起来像另外一种事物
stack、queue、priority_queue

支持的操作:
size_type:
value_type:
empty();
swap();

定义1个适配器:
deque<int> deq;
stack<int> stk(deq);

stack<string,vector<string>> str_stk;   //在vector上的实现的栈,

两个类型函数;默认情况下:stack和queue是基于deque实现的
                      priority_queue是在vector上实现的

stack:满足push_back、pop_back、back                可以基于除array和forward_list之外的上面
queue:满足push_back、back、front和push_front       可以基于list和deque之上,不能vector
priority_queue:随机访问,push_back、front            可以基于vector和deque之上,不能list    

—————————————————————————————————————————————————————————————————————————————————————————————————————————————————
第10章:泛型算法
10.1泛型算法:独立于容器的通用算法
            在头文件algorithm里面
            不直接作用于容器,而是遍历两个迭代器之间的一个元素范围
            find(vec.cbegin,vec.end,val)

泛型算法永远不会执行容器的操作,他们只会独立于迭代器上面
迭代器令算法不依赖于容器,但算法依赖于元素类型的操作

10.2 初识泛型算法
只读算法:          搜索find
                  求和连接accumulate
                  判断相同equal,只有3个迭代器,
写容器元素的算法:填充赋值fill: 2个迭代器,3个参数
                  拷贝copy:2个迭代器,3个参数
                        replace():2个迭代器,4个参数
                        replace_copy():3个迭代器,5个参数
                  重排:sort unique:只有2个迭代器

10.3迭代器
 插入迭代器:back_insert/front_insert/insert
 流迭代器  : istream_iterator/ostream_iterator
 反向迭代器: rbegin/rend/crbegin/crend
 移动迭代器: 

 10.5泛型算法结构
 5个迭代器类别
 输入:只读不写,单遍扫描,只能递增
 输出:只写不读,单遍扫描,只能递增
 前向:读写均可,多遍扫描,只能递增       replace
 双向:读写均可,多遍扫描,能递增递减     reverse
 随机访问:可读写,多遍扫描,             sort
_______________________________________________________________________________________________________________
第11章:关联容器

按照关键字来保存和访问的
map和set等

按关键字的有序保存元素:
map         关联数组,保存关键字-值对
set         关键字即可
multimap    关键字可重复
multiset    关键字可重复

按关键字的无序集合:
unordered_map           哈希组织的map
unordered_set           哈希组织的set
unordered_multimap      哈希组织的map,关键字可重复
unordered_multiset      哈希组织的set,关键字可重复

使用map:
map<string,size_t> word_count;       //建立map的键值对类型:string-size_t
string word;                         //建立健:word
while(cin>>word)
  ++word_count[word];
for(const auto&w:word_count)
    cout<<w.first<<"oocures"<<w.second<<endl;

使用set:
set<string> exclude={"the","but","he","good","wo","hi"};
while(cin>>word)
    if(exclude.fide(word)==exclude.end())
        ++word_count[word];

关联容器不支持:push_front和push_back

定义容器:
map<string,string> authors={{"he","jim"},
                            {"she","tom"},
                            {"it","lili"}};

pair类型:定义在头文件:utility里面
保存两个数据成员,类似容器,pair用来生成特定类型的模板
pair操作
    pair<T1,T2> p(v1,v2);
    make_pair(v1,v2);
    p.first;
    p.second;
    p1==p2;
    p1!=p2;

关联容器的额外的类型别名
key_type;
mapped_type;   //只适用于map,每个关键字关联的类型,
value_type;    //对于set,与key_type一致
               //对于map;为pair<const key_type,mapped_type>
只有map类型定义了mapped_type

例如:
map<string,int>::mapped_type v1;      //v1 int
map<string,int>::key_type v2;         //v2 string
map<string,int>::value_type v3;       //v3 pair<const string,int>

关联容器的迭代器:会获得value_type类型的引用
对于map而言,value_type是一个pair类型,first成员保存const关键字,second保存值
对于set迭代器,是const的,只允许访问set不能改变关键字

map<string,size_t> word_count;     //map关联容器
auto map_it=word_count.begin();    //map迭代器
cout<<map_it->first;               //迭代器指向关键字
cout<<map_it->second;              //迭代器指向值

遍历关联容器:map和set支持begin和end操作
auto map_it=word_count.cbegin()
while(map_it!=word_count.cend())
{
    cout<<map_it->first;     //打印键
    cout<<map_it->second;    //打印值
    ++map_it;
}

添加元素:insert:有两个版本,分别接受一对迭代器或者一个初始化列表
map的insert操作的元素类型必须是pair

c.insert(ivec.begin(),ivec.end());          //set的insert
c.insert({1,2,3,4,5});                         //set的insert

word_count.insert({word,1});                                 //map的insert类型
word_count.insert(make_pair(word,1));                        //map的insert类型
word_count.insert(map<string,size_type>::value_type(word,1));//map的insert类型

删除元素:erase
下标操作:下标运算符和at函数,但是set,multimap,unorder_multimap不支持下标  c[k]和c.at(k)
访问元素:find、count

无序容器:新的标准里面新增加了4个新的无序容器
          无序容器使用一个哈希函数将元素映射到桶
          为了得到元素,先要计算元素的哈希值,他指出应该搜索那个桶
          容器将具有一个特定的哈希值的所有元素都保存在相同的桶里面

桶接口:
c.bucket_count()          正在使用桶的数目
c.max_bucket_count()      容器里面的最大容纳的通的数目
c.bucket_size(n)          第n个桶有多少个元素
c.bucket(k)               关键字的k在哪个桶里面

桶迭代:
local_iterator
const_local_iterator
c.begin(n),c.end(n)
c.cbegin(n),c.cend(n)

哈希策略:
c.looad_factor()    : 每个桶的平均元素数量,返回float值
c.max_load_factor() :c试图维护每个桶的平均元素数量,必要的时候添加新的桶
c.rehash(n)         :重组hash,使得max_bucket_count>=n
c.reserve(n)        :重组hash,使得c可以保存n个元素,而且不用rehash

无序容器对于关键字的类型要求:
默认情况下使用==运算符来比较元素
而且使用一个hash<key_type>类型的对象来生成每个元素的哈希值
对应的是默认的hash模板

总结:
hash:标准的库模板,无序容器用它来管理元素的位置
关联容器:保存对象的集合,支持通过关键字的高效查找
关联数组:元素通过关键字而不是位置来索引的数组

key_type:   就是关联容器的关键字的类型
mapped_type:就是映射中关键字的关键字关联的值的类型
value_type:容器里面的元素的类型,对于map容器是一个pair,first是const_key_type,second是mapped_type
pair:保存名为first和second的数据成员,是一个模板类型,接受两个类型参数,作为其两个对应的成员的类型

______________________________________________________________________________________________________________
第12章:动态内存
______________________________________________________________________________________________________________

第15章:面向对象程序设计

15.3虚函数:每个虚函数都必须定义
对于虚函数的调用可能直到运行时才被解析
virtual虚函数关键字

final和override说明符
C++11里面使用override来说明派生类里面的虚函数

struct B{
    virtual void f1(int) const;
    vittual void f2();
}

struct D:B{
    void f1(int) const override;
}
_________________________________________________________________________________________________________________
第16章:模板和泛型编程

泛型编程:独立于任何特定的类型来编写代码
泛型编程:容器、迭代器、算法
只是对于类型不同

16.1定义模板
定义模板:只是参数对应的类型不同
1:函数模板
template <typename T>
int compare(const T &v1,const T &v2)
{
    if(v1<v2) return -1;
    if(v1<v2) return  1;
    return 0;
}

关键字:template 后跟模型参数列表 用<>表示
编译器用推断的模板参数来为我们实例化一个特定版本的参数

模板类型参数:template后面必须跟上typename或者class
template <typename T,class U> T clac(const T&,const T &)

非类型参数:表示的是一个值而非类型,但必须是常量表达式,
template <unsigned N,unsigned M>
int compare(const char(&p1)[N],const char(&p2)[M])
{
    return strcmp(p1,p2);
}

inline和constexpr的函数模板
template <typename T> inline T min(const T&,const T&)
inline放在模板参数列表后,返回类型之前

模板编译:当编译器遇到一个模板定义的时候,并不生成代码
          只有实例化一个特定模板时候,才会生成特定的代码
          只有使用而不是被定义模板的时候才会生成代码
          模板的头文件通常既会包含声明,也会包含定义

类模板:编译器不能推断麻痹你参数类型,必须通过额外的信息
template <typename T> class Bob{};        

可变参数模板:参数包
           模板参数包
           函数参数包
时间: 2024-10-25 22:28:17

C++primer笔记:IO库、顺序容器、关联容器、面向对象、泛型算法、模板和泛型编程的相关文章

C++ Primer笔记5_STL之顺序容器

1.STL(Standard Template Library) 标准模板库.从根本上说,STL是一些"容器"的集合,这些"容器"有list, vector,set,map等,STL也是算法和其它一些组件的集合.这里的"容器"和算法的集合指的是世界上很多聪明人很多年的杰作.每一个C++程序员都应该好好学习STL.大体上包括container(容器).algorithm(算法)和iterator(迭代器),容器和算法通过迭代器可以进行无缝连接. 2

C++ Primer 学习笔记_45_STL实践与分析(19)--泛型算法的结构

STL实践与分析 --泛型算法的结构 引言: 正如全部的容器都建立在一致的设计模式上一样,算法也具有共同的设计基础. 算法最主要的性质是须要使用的迭代器种类.全部算法都指定了它的每一个迭代器形參可使用的迭代器类型.比方,假设形參必须为随机訪问迭代器则可提供vector或 deque类型的迭代器,或者提供指向数组的指针.而其它容器的迭代器不能用在这类算法上. C++还提供了另外两种算法模式:一种模式由算法所带的形參定义;还有一种模式则通过两种函数命名和重载的规范定义. 一.算法的形參模式 大多数的

C++ primer笔记——第九章 顺序容器

顺序容器的元素按照其位置存储和访问.除了顺序容器之外,标准库还提供了几种关联容器,其元素按照键(key)排序.每组容器都提供一组不同的时间和功能的折中方案.顺序容器根据位置来存储和访问元素,元素的排列次序与元素值无关,而是由元素添加到容器的顺序决定.标准库定义了三种顺序容器:vector.list.dequeue.他们的差别在于元素访问的方式以及添加和删除元素相关操作的运行代价.标准库还提供了三种适配器.适配器是根据原始的容器类型所提供的操作,通过定义新的操作接口来适应基础的容器类型.顺序容器适

《C++primer》v5 第11章 关联容器 读书笔记 习题答案

11.1 map是关联容器,vector是顺序容器 11.2 略 11.3 int main() { map<string,int> word; string s; while(cin>>s) word[s]++; for(auto i:word) cout<<i.first<<" "<<i.second<<endl; return 0; } 11.4 void convers(string &s) { s

STL 笔记(二): 关联容器 map、set、multimap 和 multimap

STL 关联容器简介 关联容器即 key-value 键值对容器,依靠 key 来存储和读取元素.在 STL 中,有四种关联容器,分别是: map 键值对 key-value 存储,key 不可重复,即一个 key 只能对应一个 value, 对应头文件<map> multimap 键值对 key-value 存储,key 可以重复,即一个 key 可以对应多个 value, 对应头文件<map> set 只有 key, key 不可重复,对应头文件<set> mult

C++ Primer学习总结 第11章 关联容器

第11章 关联容器 1.    使用map的简单例子: 运行结果为: 2.    初始化map和set: 3.    set与multiset的区别: 4.    使用map和set时,其元素类型必须是定义了严格弱序的(即定义了<号比较的),如果元素类型没有定义<号操作也可以通过外部函数来比较: 5.    pair类型:pair是一个用来生成特定类型的模板. pair的默认构造函数对数据成员进行值初始化. 6.    遍历map和set关联容器: 7.    如何往set和map中添加指定元

【C++ Primer 第11章】《关联容器》目录

关联容器 •   set的用法 原文地址:https://www.cnblogs.com/sunbines/p/9155009.html

STL2——关联容器

关联容器 关联容器支持通过键(key)来高效地查找和读取元素.两个基本的关联容器是map和set,map的元素以键-值对形式组织,键用做索引,值表示存储和读取的数据,set包含一个键,并有效地支持关于某个键是否存在的查询. 引言:pair类型 #include<utility> pair<int,int>p; p.first=5; p.second=6; pair<int,int>p2; p2=make_pair(5,7); pair<int,int>p3(

第十一章:关联容器

关联容器 关联容器支持高效率的关键字查找和访问. 关联容器和顺序容器的本质差别在于:关联容器通过键(key)存储和读取元素,而顺序容器则通过元素在容器中的位置顺序存储和访问元素. 关联容器(associative-container) :两个主要关联容器:map 和 set map 的元素以键-值(key-value)对的形式组织:键用作元素在 map 中的索引,而值则表示所存储和读取的数据.set 仅包含一个键,并有效地支持关于某个键是否存在的查询. 一般来说,如果希望有效地存储不同值的集合,

C++学习STL之关联容器 --- pair、map、set

本博文我们继续讨论标准模板库STL的关联容器: 主要有:pair.map.set. 一:pair pair是一种简单的关联类型,不属于容器范围.而是代表一个 key-value键值对. 创建.初始化.操作 示例代码如下: 1 #include <iostream> 2 #include <string> 3 #include <vector> 4 using namespace std; 5 //将pair放入容器&initpair 6 int main(int