C++ 学习笔记之(17)-标准库特殊设施(tuple类型、bitset类型、正则表达式、随机数以及IO库再探)

C++ 学习笔记之(17)-标准库特殊设施(tuple类型、bitset类型、正则表达式、随机数以及IO库再探)

标准库内容巨大,故仅介绍某些标准库设施:tuplebitset、正则表达式以及随机数,此外还有一些IO库功能:格式控制、未初始化IO和随机访问

tuple类型

tuple类似与pair,但pair只有两个成员,tuple却有任意数量的成员

tuple_supported_operations

定义和初始化tuple

  • 标准库函数make_tuple类似于make_pair函数,用来生成tuple对象
  • 使用标准库函数模板get访问tuple成员
  • 可使用tuple_sizetuple_element辅助类查询tuple的数量和类型
  • tuple定义了<==运算符,故可将tuple序列传递给算法,并在无序容器中将tuple作为关键字类型
tuple<size_t, size_t, size_t> threeD;  // 三个成员都设置为 0. 调用默认构造函数,执行值初始化
tuple<size_t, size_t, size_t> threeD = {1, 2, 3};  // 错误,因为该构造函数为 explicit
tuple<size_t, size_t, size_t> threeD{1, 2, 3};  // 正确:explicit 构造函数只能执行直接初始化
auto item = make_tuple("0-999", 3, 20.00);  // tuple<const char *, int , double>
auto book = get<0>(item);  // 返回 item 的第一个成员

typdef decltype(item) trans;  // trans 是 item 的类型
size_t sz = tuple_size<trans>::value; // 返回 trans 类型对象中成员的数量, 3
tuple_element<1, trans>::type cnt = get<1>(item); //cnt 的类型与 item 中第二个成员相同,为 int
  • tuple可用作从函数的返回值

bitset类型

bitset可使得位运算更为简便,且能够处理超过最长整形类型大小的位的集合

定义和初始化bitset

bitset中的二进制位未命名,可通过位置访问。从0开始编号的二进制位为 低位, 编号到31结束的二进制位为 高位

下图为bitset构造函数

bitset_initialize_methods
* 整型值初始化bitset时,值将转换为unsigned long long类型,并被当做位模式处理。若bitset的大小小于一个unsigned long long中的二进制位数, 则超出bitset大小的高位被丢弃。 否则,剩余的高位置为0

c++
// bitvec1 比 初始值小;初始值中的高位被丢弃
bitset<13> bitvec1(0xbeef); // 二进制位序列为 1111011101111
// bitvec2 比初始值大,它的高位被置为0
bitset<20> bitvec2(0xbeef); // 二进制位序列为 0000 1011 1110 1110 1111

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

    string str("1001001100");
    bitset<8> bitvec5(str, 5, 4);  // 从 str[5]开始的四个二进制位, 0110, 结果为 00000110

bitset操作

bitset_operations

bitset<32> bitvec(1U);  // 32位,低位为1, 剩余位为0
quizA |= 1UL << 27;  // 将第27位置1
quizA &= ~(1UL << 27);  // 将第27为置0

正则表达式

暂时未整理此部分内容,详情请查阅

随机数

  • 随机数引擎(random-number engines):生成unsigned随机数序列
  • 随机数分布类(random-number distribution):使用引擎类生成指定类型的、在给定范围内的、服从特定概率分布的随机数
  • C++程序不应该使用库函数rand, 而应使用default_random_engine类和恰当的分布类对象

随机数引擎和分布

随机数引擎为函数对象类,定义了函数调用运算符,不接受参数并返回一个随机unsigned整数

  • 随机数发生器:指分布对象和引擎对象的组合
    randome_number_engines_operations
default_random_engine e;  // 生成随机无符号数,原始随机数
for(size_t i = 0; i < 10; ++i)
    cout << e() << " ";  // 调用 e() 对象生成下一个随机数, 范围为[0, unsigned 最大值]

uniform_int_distribution<unsigned> u(0, 9);  // 均匀分布的随机数, [0, 9]
for(size_t i = 0; i < 10; ++i)
    cout << u(e) << " ";  // u 作为随机数源, 生成均匀分布的随机数
  • 一个给定的随机数发生器一直会生成相同的随机数序列。一个函数如果定义了局部的随机数发生器,应该将其(包括引擎和分布对象)定义为static的,否则,每次调用函数都会生成相同的序列。
  • 可通过随机数种子生成不同的随机结果, 一般使用系统函数time

其他随机数分布

random_number_distribution_type_operations
* uniform_real_distribution: 随机浮点数,默认为double类型
* bernoulli_distributiion:类,非模板,返回bool值,概率为0.5, 概率可调整
* 新标准库可生成非均匀分布的随机数,定义了20种分布类型

IO库再探

格式化输入与输出

iostream对象不仅包含条件状态,还维护一个格式状态控制格式化细节

  • 操纵符(manipulator):修改流的格式状态, 比如endl
  • 操纵符用于控制数值的输出形式以及控制补白的数量和位置
  • 当操纵符改变流的格式状态时,通常改变后的状态对所有后续IO都生效
  • 操纵符hexoctdec只影响整形运算对象,浮点值的表示形式不受影响

io_library_manipulators

  • 定义在iomanip中的操纵符

io_library_iomanip_manipulators

  • 默认情况下,输入运算符会忽略空白符(空格符、制表符、换行符、换纸符和回车符),可使用操纵符noskipws令输入运算符读取空白符

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

标准库提供了一组低层操作,支持 未格式化IO,即允许将流当做一个无解释的字节序列处理

io_library_single_byte_low_level_io_operations
* 将字符放回输入流:有时需要读取一个字符才能知道还未准备好处理它,此时需要放回流中

  • peek:返回输入流下一个字符的副本,但不会将它从流中删除,peek返回的值仍留在流中
  • unget:使输入流向后移动,从而最后读取的值又回到流中。即使不知道从流中读取什么值,也可调用
  • putback:特殊版本的unget,退回从流中读取的最后一个值,接受一个参数,此参数与最后读取的值相同

    • 输入操作返回int值:可以返回文件尾标记,用来表示文件尾

    • 一些未格式化IO操作一次处理大块数据,要求自己分配并管理用来保存和提取数据的字符数组

    io_library_multi_bytes_low_level_io_operations

流随机访问

  • 随机IO本质上依赖于系统,需查询系统文档

  • istreamostream类型不支持随机访问, 故seektell函数只适用于fstreamsstream类型

io_library_seek_and_tell_function

  • 标准库虽然区分seek函数和tell函数的放置和获得,但在流中只维护单一的标记

结语

本文介绍了特殊的IO操作和四个标准库类型:tuplebitset、正则表达式和随机数。库的更多使用可参阅

猜你喜欢

转载自blog.csdn.net/u011221820/article/details/80240187
今日推荐