[读书笔记] C++Primer (第5版) 第17章标准库特殊设施

1.tuple类型:

每个tuple的成员类型可以都不相同,可以有任意数量的成员。

tuple<string, vector<double>, int> someVal("Contants", {2.1, 3.6, 9}, 32);

pair总有两个成员(first和second),tuple的成员个数不确定,所以不能用这种方式访问。
要访问tuple的成员,就要使用名为get的标准库函数模板。

auto nVal = get<2>(someVal);       // 返回someVal的第3个成员

tuple_size和tuple_element可以获得到tuple成员的数量和某个成员,前提是知道tuple的类型。

typedef decltype(someVal) trans;  // trans是someVal的类型
size_t sz = tuple_size<trans>::value;   // 获取trans类型对象的成员数量
tuple_elements<1, trans>::type cnt = get<1>(someVal);   // cnt与someVal的第二个成员类型一致

tuple之间的比较必须成员数量一致,并且各成员类型一致。

2.bitset类型:

bitset使位运算更加方便,能够处理超过最长整形类型大小的位集合。
bitset<32> bitvec(1U); // 32位,低位为1,其他位为0
编号从0开始的二进制位被称为低位,编号到31结束的二进制位被称为高位。
当用整型来初始化bitset时,整型会转换成unsigned long long 。bitset的位大于unsigned long long时,剩余高位被置0,。bitset的位小于unsigned long long时,超出bitset的高位部分被丢弃。

bitset<n> b(str, pos, m, zero, one);  	// 从str的pos位拷贝m个字符到b中

str:字符串 pos:str的第pos位,默认0 m:截取m个
zero:遇到该字符转换成b中的0,默认’0’ one:遇到该字符转成1,默认‘1’
str只能包涵zero和one,否则抛出invalid_argument异常。

3.正则表达式:

一种描述字符序列的方法,是极其强大的计算工具。新标准库的一部分,RE库定义在头文件regex中。
regex使用的正则表达式语言是ECMAScript。

string strPattern = "[[:alpha:]][^c]ei[[:alpha:]]";  // 模式[[:alpha:]]匹配任何字符,非c后接ei
regex r(strPattern);	// 构造一个用于查找模式的regex
smatch ret;             // 用于保存查找结果
string strTest = "receipt friend theif";	// 测试字符串
bool IsFind = regex_search(strTest, ret, r);	// 是否有匹配的字符串

regex_search是查找是否有匹配的子字符串,regex_match是是否匹配。还有一个没有参数ret的版本。
最后一个参数是可选regex_constants::match_flat_type的值。
regex r(re, f);
re可以是正则表达式,string,表示范围的迭代器等。
f指出对象如何处理标识,默认是ECMAScript。
一个正则表达式的语法是否正确是在运行时解析的。
正则表达式编译是一个很慢的过程,因此应该尽量避免构造和赋予操作。
RE为这些不同的输入序列类型都定义了对应的类型:
在这里插入图片描述
// 遍历迭代器b到e,it定位到第一个匹配的位置,++操作表示找到下一个匹配位置
sregex_iterator it(b, e, r);
子表达式是模式的一部分,本身也具有意义,正则表达式语法通常用括号表示子表达式。
在这里插入图片描述
如果pattern有n个子表达式,则smatch会有n+1个ssub_match元素。位置[0]表示整个匹配,位置[1]到[n]表示每个对应的子表达式。
regex_replace在输入序列中查找并替换一个正则表达式。

string fmt="$2.$5.$7"   //$后跟子表达式的索引号来表示一个特定的子表达式
regex r(phone);
string num = "(908) 555-1800"
regex_replace(num,  r,  fmt);

4.随机数:

随机数引擎类生成随机unsigned整数序列。
随机数分布类使用引擎返回服从特定概率分布的随机数。

default_random_engine e;      //  生成随机无符号数
cout<<e();  

标准库定义了多个随机数引擎类,区别在于性能和随机性质不同。每个编译器都会指定其中一个作为default_random_engine类型。
大多数场合随机数引擎的输出是不能直接使用的。因为生成的值范围通常与需要的不符。

uniform_int_distribution<unsigned> u(0,  9);  cout <<u(e);

uniform_int_distribution类型生成均匀分布的unsigned值。
随机数发生器:指分布对象和引擎对象的组合。
一个给定的随机数发生器一直会生成相同的随机数序列。
一个函数如果定义了局部的随机数发生器,应该将其(包括引擎和分布对象)定义为static的。因为static会在函数调用之间保持住状态。否则每次调用函数都会产生相同的序列。
种子:为了达到每次运行都产生不同的随机结果的目的,可以提供一个种子,种子就是一个数值。引擎可以利用它从序列中的一个新位置重新开始生成随机数。

  • 创建引擎对象时提供种子:default_random_engine e(3214);
  • 调用引擎的seed成员:e.seed(3453);
    没有设置种子使用默认种子,种子一样时,生成的序列也一样。
    可以选择调用系统函数time, 它返回从特定时刻到当前经历多少秒。如果是一个周期循环的函数,使用这个函数可能就无效了。
    uniform_real_distribution类型可以生成随机浮点数。
 uniform_int_distribution<double> u(0,1);  u(e);	// 0到1的均匀分布的随机浮点数

正态分布的随机数使用normal_distribution。

normal_distribution<> n(4, 1.5);		// 使用默认模板参数,4是均值,1.5是标准差
bernnoulli_distribution b(.55);         //返回一个bool类型,概率是55/45,默认概率是50/50

5.IO库再探:

除了条件状态外,每个iosteam对象还维护一个格式状态。来控制io如何格式化的细节。格式状态控制格式化的某些方面如整型值是几进制,浮点值的精度,一个输出元素的宽度等。
操纵符:标准库定义了一组操纵符来修改流的格式状态。一个操纵符是一个函数或是一个对象,会影响流的状态,并能用作输入或输出运算符的运算对象。类似输入或输出运算符操纵符也返回它所处理的流对象。因此我们可以在一条语句中组合操纵符合数据。
操纵符用于两大类输出控制:控制数值的输出形式,以及控制补白的数量和位置。
大多数改变格式状态的操纵符,都是设置/复原成对的。一个用来将格式状态设置为一个新值,另一个用来将其复原为默认格式。

cout <<true <<" "<<false <<"changed:"<<boolalpha <<true <<" "<<false;

输出结果: 1 0changed:true false 后面再加<<noboolalpha 将流恢复到初始状态
操纵符hex、oct和dec将其改为十六进制、八进制或是改回十进制(只影响整型)。
showbase操纵符:在输出结果中显示进制。恢复用noshowbase。
uppercase操纵符:输出大写的0X,以及十六进制a~f以大写输出。
默认情况,浮点数按六位数字精度打印。可以通过调用io对象的precision成员或使用precision操纵符来改变精度。
cout<<cout.precition(8)<<setprecition(12); // 精度6->8->12
endl和flush也是操纵符。
默认情况下,输入运算符会忽略空白符(空格符,制表符,换行符,换纸符和回车符)。
操纵符noskipws会令输入运算符读取空白符。
未格式化IO:这些操作允许我们将一个留当作一个无解释的字节序列来处理。
is.get(ch) 从is读取下一个字节存入字符ch中,返回is
os.put(ch) 将字符ch输出到os,返回os
is.get() 将is的下一个自己作为int返回
is.putback(ch) 将字符ch放回is,返回is
is.unget() 将is向后移动一个字节,返回is
is.peek() 将下一个字节作为int返回,但不从流中删除它函数
peek和无参的get版本都已int类型从输入流返回一个字符。返回int的函数将他们要返回的字符先转化成unsigned char,然后再将结果提升到int。所以返回的int是正值,而标准库使用负值表示文件尾。
头文件cstdio定义了一个名为EOF的const,可以用它来检测从get返回的值是否是文件尾。
也可以从流中读取多个字节(其他版本的get以及write,getline)。
标准库为所有流类型都定义了seek和tell函数。绑定到cin,cout等流时,操作会将流置于一个无效状态。由于stream和ostream类型通常不支持随机访问。所以只适用于fstream和sstream。
输入和输出版本的差别在于名字的后缀是g(get输入流使用)还是p(put输出流使用)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值