C++ Primer 第四版读书笔记(二)之标准库类型-程序员宅基地

技术标签: c/c++  

C++定义了一个内容丰富的抽象数据类型标准库,其中最重要的标准库类型是string和vector,它们分别定义了大小可变的字符串和集合。string和vector往往将迭代器用作配套类型,用于访问string中的字符,或者vector中的元素。

另一种标准库类型为bitset,提供了一种抽象方法来操作位的集合。

string类型支持长度可变的字符串,vector用于保存一组指定类型的对象。

bitset类标准库类型提供了更方便和合理有效的语言级的抽象设施。通过这个类可以把某个值当作位的集合来处理。

1.1 命名空间的using声明

using的含义是右操作数的名字可以在做操作数的作用域中找到。如:std::cin中名字cin是在命名空间std中定义的。

using声明是一种最安全的机制

1、每个名字都需要一个using声明

一个using声明一次只能作用于一个命名空间成员。using声明可用来明确指定在程序中用到的命名空间中的名字,如果希望使用std(或其他的命名空间)中的几个名字,则必须为要用到的每个名字都提供一个using声明。

2、使用标准库类型的类定义

有一种情况下,必须总是使用完全限定的标准库名字:在头文件中。理由是头文件的内容会被预处理器复制到程序中。

2.1 标准库string类型

2.1 .1 string对象的定义和初始化

当没有明确指定对象初始化式时,系统将使用默认构造函数。

几种初始化string对象的方式
string s1; 默认构造函数,s1为空串
string s2(s1); 将s2初始化为s1的一个副本
string s3("value"); 将s3初始化为一个字符串字面值副本
string s4(n, 'c'); 将s4初始化为字符串‘c’的n个副本





2.1.2 string对象的读写

string类型的输入操作符:

(1)、读取并忽略开头所有的空白字符(如空格,换行符,制表符)。

(2)、读取字符直至再次遇到空白字符,读取终止。

如:如果输入到程序的是" Hello World!  "(注意到开头和结尾的空格和制表符),则屏幕上将输出“Hello”,而不含任何空格。

1、读入未知数目的string对象

2、用getline读取整行文本

这个函数接受两个参数:一个输入流对象和一个string对象。getline函数从输入流的下一行读取,并保存读取到的内容到string中,但不包括换行符。和输入操作符不一样的是,getline并不忽略开头的换行符。只要getline遇到换行符,即便它是输入的第一个字符,getline也将停止读入并返回。如果第一个字符就是换行符,则string参数将被置为空string。

2.1.3 string对象的操作

常用的string操作
s.empty() 如果s为空串,则返回true,否则返回false
s.size() 返回s中的字符的个数
s[n] 返回s中位置为n的字符,位置从0开始计数
s1 + s2 将s1和s2连接成一个新字符串,返回新生成的字符串
s1 = s2 将s1的内容替换为s2的副本
v1 == v2 比较v1和v2的内容,相等则返回true,否则返回false
!=, <, <=, >, >= 保持这些操作符惯有的含义
(1)、string的size和empty操作

(2)、string::size_type类型

从逻辑上来讲,size()成员函数似乎应该返回整型数值,但事实上,size操作返回的是string::size_type类型的值。

string类类型和许多其他库类型都定义了一些配套类型。通过这些配套类型,库类型的使用就能与机器无关。size_type就是这些配套类型中的一种。它定义为与unsigned性(unsigned或unsigned long)具有相同的意义,而且保证足够大能够任意存储任意string对象的长度。

(3)、string关系操作符

string类定义了几种关系操作符用来比较两个string值的大小。这些操作符实际是比较每个string对象的字符。

关系操作符比较两个string对象时采用了和(大小写敏感的)字典排序相同的策略:

1)、如果两个string对象长度不同,且短的string对象与长的string对象的前面部分相匹配,则短的string对象小于长的string对象。

2)、如果两个string对象字符不同,则比较第一个不匹配的字符。

(4)、string对象的赋值

大多数string库类型的赋值等操作的实现都会遇到一些效率上的问题,但值得注意的是,从概念上讲,赋值操作确实需要做一些工作。它必须先把st1占用的相关内存释放掉,然后再分配给st1足够存放st2副本的内存空间,最后把st2中的所有字符复制到新分配的内存空间。

(5)两个string对象相加

string对象的加法被定义为连接。也就是说,两个或多个string对象可以通过使用加操作符+或者复合复制操作符+=连接起来。

(6)、和字符串字面值的连接

当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的。

(7)、从string对象获取字符

string类型通过下标操作符([])来访问string对象中的单个字符。下标操作符需要取一个size_type类型的值,来表明要访问字符的位置。这个下标中的值通常被称为“下标”或者“索引(index)”

string对象的下标从0开始。

(8)、下标操作可用于左值

标准库不要求检查索引值,所用索引的下标越界是没有定义的,这样往往会导致;严重的运行错误。

2.1.4 string对象字符的处理

我们经常要对string对象中的单个字符进行处理,例如:通常需要知道某个特殊字符是否为空白字符、字母、数字等。下表中列出了各种字符操作函数,适用于string对象的字符(或其他任何char值)。这些函数都在cctype头文件中定义。

cctype定义的函数
isalnum(c) 如果c是字母或者数字,则为true
isalpha(c) 如果c是字母,则为true
iscntrl(c) 如果c是控制字符,则为true
isdigit(c) 如果c是数字,则为true
islower(c) 如果c是小写字母,则为true
isprint(c) 如果c是可以打印的小写字母则为true
ispunct(c) 如果c是标点符号,则为true
isspace(c) 如果c是空白符号,则为true
isupper(c) 如果c是大写字母,则为true
isxdigit(c) 如果c是十六进制数,则为true
tolower(c) 如果c是大写字母,则返回其小写字母形式,否则直接返回c
toupper(c) 如果c是小写字母,则返回其大写字母形式,否则直接返回c
isgraph(c) 如c不是空格,但可打印,则为true













3.1 标准库vector类型

vector是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。和string对象一样,标准库将负责管理与存储元素相关的内存。我们把vector称为容器,因为它可以包含其他对象。一个容器中的所有对象都必须是同一种类型的。

使用vector之前,需要包含相应的头文件。

#include <vector>

using std::vector

vector是一个模板类。使用模板可以编写一个类型一或者函数定义,而用于多个不同的数据类型。

声明从类模版产生的某种类型的对象,需要提供附加信息,信息的种类取决于模板。以vector为例,必须说明vector保存何种对象的类型,通过将类型放在模板名称后面的尖括号中来指定类型:

vector <int > ivec;

vector <Sales_item> Sales_vec;

vector不是一种数据类型,而只是一个类模板,可用来定义任意多种数据类型。vector类型的每一种都指定了其保存元素的类型。

3.1.1 vector对象的定义和初始化

几种初始化vector对象的方式
vector <T> v1; vector保存类型为T的对象。默认构造函数v1为空
vector <T> v2(v1); v2是v1的一个副本
vector <T> v3(n, i); v3包含n个值为i的元素
vector <T> v4(n); v4含有值初始化的元素的n个副本

(1)、创建确定个数的元素

若要创建非空的vector对象,必须给出初始化元素的值。当把一个vector对象复制到另一个vector对象时,新复制的vector中每个元素都初始化为原vector中相应元素的副本。但这两个vector对象必须保持同一种元素类型:

vector <int> ivec1;

vector <int> ivec2(ivec1);//复制ivec1到icec2正确

vector <string> svec(ivec1);//错误,类型不同

可以用元素个数和元素值对vector对象进行初始化。构造函数用元素个数来决定vector对象保存的元素的个数,元素值指定每个元素的初始值:

vector <int> ivec4(10, -1);

vector <string> svec(10, "hi!");

关键概念:vector对象(以及其他标准库容器对象)的重要属性就在于可以在运行时高效的添加元素。因为vector增长的效率高,在元素值已知的情况下,最好是动态的添加元素。

(2)、值的初始化

如果没有指定元素的初始化式,那么标准库将自行提供一个元素初始值进行值初始化。这个由库生成的初始值将用来初始化容器中的每一个元素,具体值为何,取决于存储在vector中的元素的数据类型。

3.1.2 vector对象的操作

vector标准库提供了许多类似于string对象的操作:

vector操作
v.empty() 如果v为空,则返回true,否则返回false
v.size() 返回v中元素的个数
v.push_back(t) 在v的末尾增加一个值为t的元素
v[n] 返回v中位置为n的元素
v1 = v2 把v1中的元素替换为v2中的元素的副本
v1 ==v2 如果v1与v2相等,则返回true
!=, <, <=, >, >= 保持这些操作符惯有的含义

(1)、vector对象的size

empty和size操作类似于string类型的相关操作。

使用size_type类型时,必须指出该类型是在哪里定义的。vector类型总是包括vector的元素类型:

vector <int> :: size_type;//正确

vector ::size_type;//错误
(2)、向vector添加元素

(3)、vector的下标操作

vector中的对象是没有命名的,可以按vector中对象的位置来访问他们。通常使用下标操作符来获取元素。

(4)、不能用下标操作添加元素

注:必须是已存在的元素才能用下标操作符进行索引。通过下标操作符进行赋值时,不会添加任何元素。

4.1 迭代器简介

除了使用下标来访问vector对象的元素外,标准库还提供了另一种访问元素的方法:使用迭代器。迭代器是一种检查容器内元素并遍历元素的数据类型。

标准库为每一种标准容器定义了一种迭代器类型。迭代器类型提供了比下标操作符更通用化的方法:所有的标准库容器都定义了相应的迭代器类型,而只有少数的容器支持下标操作。因为迭代器对所有容器都适用,现代C++程序更倾向于使用迭代器而不是下标操作访问元素,即使对支持下标操作的vector类型也是这样。

(1)、容器的iterator类型

每种容器类型都定义了自己的迭代器类型,如vector:

vector <int> :: iterator iter;

这条语句定义了一个名为iter的变量,它的数据类型是由vector <int> 定义的 iterator类型。每个标准库容器类型都定义了一个名为iterator的成员,哲理的iterator与迭代器实际类型的含义形同。

术语:迭代器和迭代器类型

程序员首次遇到有关迭代器的术语时可能会困惑不解,原因之一是由于同一个术语iterator往往表示两个不同的事物。一般意义上是指迭代器的概念;而具体而言时指的是由容器定义的具体的iterator类型,如vector <int>。

重要理解的是,有许多用作迭代器的类型,这些类型在概念上是相关的。若一种类型支持一组确定的操作(这些操作可用来遍历容器内的元素,并访问这些元素的值),我们就称这种类型为迭代器。

(2)begin和end操作

每种容器都定义了一对命名为begin和end的函数,用于返回迭代器。如果容器中有元素的话,由begin返回的迭代器指向的第一个元素:

vector <int> :: iterator iter = ivec.begin();

上述语句 把iter初始化为由名为begin的vector操作返回的值。

由end操作返回的迭代器只想vector的“末端元素的下一个”。通常称为超出末端迭代器,表明它指向了一个不存在的元素。

注:由end操作返回的迭代器并不指向vector中的任何实际的元素,相反,它只起一个哨兵的作用,表示我们已经处理完vector中所有的元素。

(3)、vector迭代器的自增和解引用运算

迭代器类型定义了一些操作来获取迭代器所指向的元素,并允许程序员将迭代器从一个元素移动到另一个元素。迭代器类型可使用解引用操作符(*操作符)来访问迭代器所指向的元素:

*iter = 0;

解引用操作符返回迭代器当前所指向的元素。

从逻辑上说,迭代器的自增操作和int型对象的自增操作类似。对int对象来说,操作结果就是把int型值“加1”,而对迭代器对象则是把容器中的迭代器“向前移动一个位置”。因此,如果iter指向第一个元素,则++iter指向第二个元素。

注:由于end操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作。

(4)、迭代器的其他操作

另一对可执行迭代器操作就是比较:用==或!=操作符来比较两个迭代器,如果两个迭代器对象指向同一个元素,则它们相等,否则就不相等。

5.1 标准库bitset类型

有些程序要处理二进制位的有序集,每个位可能包含0(关)值或1(开)值。位是用来保存一组项或条件的yes/no信息(有时也称标志)的简洁方法。标准库提供的bitset类简化了位集的处理。要使用bitset类就必须包含相关的头文件。

#include <bitset>

using std::bitset;

(1)、bitset对象的定义和初始化

初始化bitset对象的方法
bitset <n> b; b有n位,每位都为0
bitset <n> b(u); b是unsigned long型u的一个副本
bitset <n> b(s); b是string对象s中含有位串的副本
bitset <n> b(s, pos, n); b是s中从位置pos开始的n个位的副本

类似于vector,bitset类是一种类模板;而与vector不一样的是bitset类型对象的区别仅在其长度而不在其类型。在定义bitset时,要明确bitset含有多少位,必须在见括号内给出它的长度:

bitset <32> bitvec;



转载于:https://www.cnblogs.com/SunkingYang/p/11049238.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/baixingzhi2917/article/details/102089694

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签