C++//标准库特殊设施

1. tuple类型

n个元素,类型可以各不相同。
在这里插入图片描述
为什么要用get而不像pair那样,使用first和second?
因为不知道tuple有多少元素。

get中尖括号内的i需要是一个整形常量表达式

tuple提供了两个类模板来查询里面的元素信息,这些模板都需要将tuple的类型信息作为参数传入,如果不知道tuple具体类型咋办?
decltype即可求出tuple的类型信息,用它来实例化模板。

只有当两个tuple有相同的元素数量时才可以比较它们,且必须保证逐元素使用关系运算符都是合法的。

在这里插入图片描述

2. bitset类型(方便的进行位管理)

bitset类定义在bitset头文件内。biteset是一个类模板,有固定大小,声明时需指定大小,大小必须是一个常量表达式
在这里插入图片描述

在这里插入图片描述

使用字符串初始化bitset时,字符串中下标最小的字符对应高位。

string下标最大(最右侧)的字符用来初始化bitset的低位
在这里插入图片描述
对bitset的操作,分为两大类,一类是返回整个bitset状态的,这类操作不接受参数。二是改变bitset状态的,这类函数一般都是重载的,有不接受参数(对整个集合执行操作)和接受一个位置参数(对指定位执行操作)的版本

count和size返回size_t类型的值。

在这里插入图片描述
当使用cin>>往bitset内写入东西时,会先从输入流读取字符,保存到一个临时的string对象内,直到string长度达到bitset大小,或者遇到非0/1字符,或遇到文件尾/输入错误,读取停止。然后用临时的string对象初始化bitset

3. 正则表达式

RE库定义在头文件regex中。
在这里插入图片描述
regex_search找到一个匹配的子串就会停止寻找。

3.1 regex选项

在这里插入图片描述
上表的最后六个标志必须设置且只能设置其中的一个。默认设置的位MCMAScript

C++使用正则表达式中的.需要用\\.\\. 第一个反斜线去掉第二个反斜线在C++语言中的特殊含义,即正则表达式为\.,而正则表达式中的\(即第二个反斜线)去掉正则表达式中.的特殊含义。

3.2 正则表达式错误

正则表达式在regex对象被初始化或者赋值时才检查正确性,即是在运行时解析正则表达式的正确性的。

如果正则表达式出错,会抛出regex_error异常。regex_error有what操作描述发生了什么错误,有code成员返回错误编码
在这里插入图片描述
正则表达式很慢,且每次创建都要解析,尽量避免用,如果要在循环内使用正则表达式,在循环外创建regex对象。

RE库类必须要与输入序列的类型匹配,不同类型用不同的组件,否则会报错:
在这里插入图片描述

3.3 匹配与regex迭代器类型

regex迭代器是一种迭代器适配器,被绑定到输入序列和一个regex对象上。
在这里插入图片描述在这里插入图片描述
调用regex迭代器的构造函数对给定的输入序列根据regex调用regex_search解引用迭代器会返回最近一次搜索结果的smatch对象递增迭代器会返回下一个regex_search的匹配
在这里插入图片描述

对于没有定义begin()和end()类型的迭代器,都使用空迭代器表示尾后迭代器
在这里插入图片描述
可用smatch对匹配的结果获取更多的信息:
在这里插入图片描述
prefix和suffix所表示的范围:
在这里插入图片描述

3.4 使用子表达式

每个match对象根据子表达式数目不同会包含不同数目的子元素,可以用下标完成子元素的访问。对返回的子元素可以进行子匹配操作

用括号表示子表达式,括号间的符号不是子表达式的部分。
在这里插入图片描述
子表达式适用的操作:
在这里插入图片描述

3.5 regex_replace

在这里插入图片描述
在这里插入图片描述
注意将匹配标志和前文的regex标志区分。
前者是为了在替换过程中控制匹配或格式的标志。后者是在控制正则表达式匹配的标志。
前者类型为match_flag_type,后者类型为syntax_option_type,二者都在名为regex_constants的命名空间内。

4. 随机数

新标准前,C和C++都依赖rand生成随机数。
大部分情况下,不同应用需要不同范围的随机数,程序员需要转换rand生成的值的范围类型或分布,这就会引入非随机性。

C++新标准不应使用rand,而应该使用下列的两个相互协作的类。
在这里插入图片描述

4.1 随机数引擎和分布

随机数引擎是一个函数对象类

标准库有多个随机数引擎类,且各自的性能和随机性质量不同。每个编译器会指定其中一个作为default_random_engine类型。

在这里插入图片描述
使用示例:
在这里插入图片描述
输出为:
在这里插入图片描述
由上述输出可知,随机数引擎生成的随机数难以直接使用,如何转换范围到我们想要的范围内是很关键的。

使用分布类型的对象可以得到一个指定范围内的数而不失随机性:
在这里插入图片描述
分布类型也是函数对象类,重载了函数调用运算符,接受一个随机数引擎(不是e(),这时e生成的值)作为参数,并使用该引擎生成随机数,并将其映射到指定分布。同时,分布类型还是一个模板,通过在尖括号内指定类型可调节输出数据的类型,如果尖括号为空,则输出对应分布类型的默认类型

分布类型可进行的操作:
在这里插入图片描述
分布对象引擎对象组成为随机数发生器

4.2 随机数引擎和rand的区别

局部的随机数发生器生成的数值序列每次都是一样的。因为每次都重新生成该发生器,状态又是从新状态开始。

如果想要每次的值不一样,可以将发生器(以及随机数引擎对象和分布对象)声明为全局或者静态的。从而保持住上次调用的状态
在这里插入图片描述

4.3 设置随机数发生器种子

将发生器声明为静态可解决多次调用函数生成种子同样的问题,但是如果想每次启动程序,第一次调用函数时生成的种子不一样,可为引擎设置种子,可在创建引擎对象时提供种子,或者调用引擎的seed成员设置种子。

种子其实就是一个数,引擎可以利用种子从序列的一个新位置重新开始生成随机数。

拥有相同种子引擎的发生器将生成相同的序列。

如下:
在这里插入图片描述
可用time系统函数生成种子,定义在头文件ctime中,他返回从一个特定时刻到现在经过了多少秒,time接受一个指针,如果指针非空,往指针所指的数据结构写时间,如果为空,简单的返回时间
在这里插入图片描述
time不能为执行频次大于每秒一次的函数生成种子。

4.4 其他随机数分布

使用随机数引擎生成的是unsigned类型的数且每个数的概率都是相同的,但在实际应用场景可能需要不同类型或者不同分布的随机数。可用不同的随机数分布对象实现。

生成范围内随机实数(不同类型):
在这里插入图片描述
除此外,还可以改变随机数的分布:
如使用normal_distribution生成正态分布的浮点值。使用bernoulli_distribution以伯努利分布的概率返回bool值。

5. IO库再探

5.1 格式化输入输出

标准库定义了一组操作符来修改流的格式状态。
操作符是对象或者函数,影响流状态,可用于输入或输出运算符对象,可返回所处理的流对象。

5.1.1 格式化输出

一般而言,输出操作符控制数值输出格式和补白数量和位置
在这里插入图片描述
默认情况下,bool值被打印为0/1,用boolalpha可打印true/false。用noboolalpha可取消。
在这里插入图片描述

可用hex(十六进制)、oct(八进制)、dec(十进制)确定输出整形数值的进制。在下一个操作符之前,都会生效。

使用showbase可显示进制,使用noshowbase可取消显示。

控制浮点数输出格式比较复杂点,有精度、进制、没有小数部分的是否补0和保留小数点几个格式:

精度:默认情况为6位数字。可调用IO对象的presion成员,或使用setpresion操作符修改精度。
在这里插入图片描述

进制:默认根据值大小选择,非常大和非常小的选择科学计数,其他值打印为定点十进制。可使用操作符scientific指定科学计数法,使用操作符fixed使用定点十进制,使用fixfloat使用十六进制。用了前面的操作符后,精度的含义便会改变位小数点后面的位数,默认情况精度为总位数。使用defaultfloat恢复到默认状态。
在这里插入图片描述

补0:默认不补,不保留小数点。可用showpoint操作符强制打印小数点,使用noshowpoint取消。留白控制见下述:
在这里插入图片描述
使用示例:
在这里插入图片描述
在这里插入图片描述

程序结果:
在这里插入图片描述

在这里插入图片描述
接收参数的操纵符都定义在iomanip内。

5.1.1 格式化输入

noskipws令输入运算符读取空白符而不是跳过他们。

5.2 未格式化的输入/输出操作

格式化操作:输入输出运算符根据读取/写入的数据类型来格式化它们。输入运算符忽略空白,输出运算符有设置精度,补白等操作。

非格式化操作:将流当成无解释的字节序列处理。

5.2.1 单字节操作

单字节非格式化操作,由于把流当成字节序列,所以空格也会被处理:在这里插入图片描述
对于里面的退回流操作,在读取下一个值之前,标准库保证最多退回一个值

为什么无参数版的get和peek返回的是int类型?逐字节处理不应该返回char更合理吗?
需要能够返回文件尾标记,char范围的值都表示真实字符,没有空间额外表示文件尾。这种方式也会带来些困扰,比如在以get的返回值作为退出循环的条件时,如果不清楚它的返回类型,可能导致意料之外的事情发生。

标准库为什么用负值表示文件尾?
上述返回int的函数是先将要返回的字符转化为unsigned char,然后将结果提升至int。所以任何合法字符返回的都是正数,文件尾定义为负数可以保证和任何合法字符都不同。

头文件cstdio定义了名为EOF的常量表示文件尾,这样就不必记住文件尾到底是是什么值了。

5.2.2 多字节操作

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
gcount返回上一个未格式化输入操作读取了多少字符。(将字符退回流也属于未格式化输入)

5.3 流随机访问

流的随机访问是指跳过某一段,重定位到另一段数据进行读取。iostream不支持随机访问,fstream和sstream支持随机访问。

5.3.1 seek和tell函数

在这里插入图片描述
g版本表示流正在获取/读取数据(gain),p版本表示流正在放置/写入数据(put)。这两个版本放置的标记实际上是一样的—不存在读标记和写标记这种说法。这个只是为了反映流本身特点而已,g版本只能用于可以读入数据的流,p版本只能用于可以写数据的流

两个参数版本的seek有两个参数,off参数是off_type类型的,from参数是pos_type类型,两个类型定义在istream和ostream内。off_type可正可负

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值