C++Primer笔记-标准库特殊设施

前言

该系列是《C++Primer第五版》的笔记,包含本人认为值得记录和整理的主要的知识点,并不是全部内容,也不是具体的内容。
该系列文章的作用应该是作为复习或预习的参考,有哪些知识点忘记或想学,可以大致浏览下该文章,然后再去书中寻找详细解答。(本系列文章基本是按书本顺序罗列的知识点,便于大家去书中寻找)
所以看该文章前,需要有一定的C++基础,否则阅读起来可能有困难。

本文大致整理了第十七章的知识点,涉及到C++关于tuplebitset和随机数的知识。

链接目录

tuple类型

tuple定义在头文件tuple中:将一组数据组合成单一对象,常用于函数返回多个值。
图片.png

定义和初始化tuple
定义tuple时需要指出每个成员的类型,tuple的构造函数是explicit的,需要提供显式初始化。make_tuple通过参数列表判断类型。

tuple<size_t, size_t, size_t> threeD;//默认初始化为0
tuple<int, double> someVal(1, 3.14);
tuple<int, double> someVal = {1, 3.14};//错误

auto item = make_tuple("xx", 3, 3.14);

访问tuple成员:

//返回一个引用
auto book = get<0>(item);//返回第一个成员

//如果不知道tuple的准确类型,可以通过辅助类模板来查询
typedef decltype(item) trans;
//获取tuple中的元素数量
size_t sz = tuple_size<trans>::value;
//声明第二个元素类型的变量
tuple_element<1, trans>::type cnt = get<1>(item);

使用tuple返回多个值

typedef tuple<string, int, double> info;
info getInfo(...){
	info ret;
	...
	return ret;
}

使用函数返回的tuple

auto val = getInfo(...);
string s = get<0>(val);
int i = get<1>(val);
double d = get<2>(val);

bitset类型

bitset类定义在头文件bitset中。

定义和初始化bitset

bitset<32> bitvec(0xFFFF);//32位全1

位数大小必须是constexpr的,初始化方法如下:
图片.png

当使用一个整型值来初始化bitset时,会被转换为unsigned long long如果bitset长度大于unsigned long long剩余的高位置0。

当用string初始化bitset时,string中下标最大的字符用来初始化bitset的最低位。

bitset操作

图片.png

提取bitset的值:

unsigned long ulong = bitvec3.to_ulong();
cout << "ulong = " << ulong << endl;

随机数

C++应该使用default_random_engine类和恰当的分布类对象,而不应该使用rand库。

随机数引擎和分布

定义在头文件random中。
图片.png

default_random_engine e;
//输出十个随机数
for(size_t i = 0; i < 10; ++i)
	cout << e() << endl;

分布类型和引擎:

//生成[0, 9]之间均匀分布的随机数
uniform_int_distribution<unsigned> u(0, 9);
default_random_engine e;
for(size_t i = 0; i < 10; ++i)
	cout << u(e) << endl;

对于一个给定的发生器,每次运行都会返回相同的数值序列:

//每次调用都是相同的结果
void f(){
	default_random_engine e;
	uniform_int_distribution<unsigned> u(0, 9);
	for(size_t i = 0; i < 10; ++i)
		cout << u(e) << endl;
}
//将引擎和分布对象定义为static,则每次调用都会生成不同的序列
//虽然每次调用结果不一样,但是整个程序重复执行的结果仍然是一样的
void f(){
	static default_random_engine e;
	static uniform_int_distribution<unsigned> u(0, 9);
	for(size_t i = 0; i < 10; ++i)
		cout << u(e) << endl;
}

设置随机数发生器种子:在调试时,每次运行都产生相同的随机结果,但调试完毕,我们希望每次运行都会有不同的随机结果,此时可以通过种子来达到目的,引擎会利用种子从序列中的一个新位置重新开始生成随机数。
但是需要注意,种子相同,随机结果相同

有两种方式设置种子:

  • 创建引擎对象时
  • 调用seed成员
default_random_engine e(123);//使用给定的种子
e.seed(456);//设置种子值

最常用的随机种子生成:通过系统函数time(定义在头文件ctime中),time返回以秒计的时间。time返回从一个特定时刻到当前经过了多少秒。

default_random_engine e(time(0));//产生随机种子

其他随机数分布

生成随机实数:

default_random_engine e;
uniform_real_distribution<double> u(0, 1);

生成非均匀分布的随机数:例如正态分布,其中使用头文件cmath中的lround将随机数舍入到最接近的整数。

default_random_engine e;
normal_distribution<> n(4, 1.5);//均值为4,标准差为1.5的正态分布,类型为double
vector<unsigned> vals(9);
for(int i = 0; i < 200; ++i){
	unsigned v = lround(n(e));
	if(v < vals.size())
		++vals[v];//统计每个数出现了多少次
}
for(int i = 0; i < vals.size(); ++i)
	cout << i << ":" << vals[i] << endl;

bernoulli_distribution类:返回bool值,默认返回true的概率为0.5

bernoulli_distribution b(0.55);//有55%的概率返回true

IO库再探

  • 格式控制
  • 未格式化IO
  • 随机访问

格式化输入与输出

控制布尔值的格式:boolalpha,默认情况下bool打印10,通过boolalpha输出truefalse

cout << "alpha bool values:" << boolalpha << true << " " << false << endl;
//输出 true false
//取消格式控制
cout << noboolalpha;
//输出 1 0 

指定整型值的进制:通过showbase操纵符可以在输出中显示进制

  • hex:十六进制
  • oct:八进制
  • dec:十进制
cout << showbase;
cout << "八进制:" << oct << 20 << endl;
cout << "十六制:" << hex << 20 << endl;
cout << "十进制:" << dec << 20 << endl;
cout << noshowbase;

//另外十六进制中的字母默认是小写,可以通过uppercase来改为大写
cout << uppercase << showbase;
cout << hex << 1024;
cout << nouppercase << noshowbase << dec << endl;

控制浮点数格式:默认按六位精度打印,没有小数部分则不打印小数

  • 以多高精度打印浮点值,即多少位数字,包含整数部分
  • 数值打印为十六进制、定点十进制还是科学计数法形式
  • 没有小数部分的浮点值是否打印小数点

指定打印精度:会按当前精度进行舍入,而非简单截断,如3.1415舍入为3.142
通过precision成员或setprecision操纵符来改变精度,操纵符setprecision等定义在头文件iomanip中。

cout << setprecision(3) << 3.1415 << endl;
//等价
cout.precision(3);
cout << 3.1415 << endl;

指定浮点数记数法:

  • scientific:科学计数法
  • fixed:定点十进制
  • hexfloat:十六进制计数法

打印小数点:showpoint强制打印小数点,默认情况小数为0不打印小数点

输出补白:控制输出格式,这部分适合在使用的时候再进行查阅

  • setw:指定下一个数字或字符串值的最小空间
  • left:表示左对齐输出
  • right:表示右对齐输出,默认
  • internal:控制负数的符号的位置,左对齐符号,右对齐值,中间用空格填
  • setfill:指定一个字符代替空格输出空白

控制输入格式:默认情况,输入运算符会忽略空白符(空格、制表、换行、回车、换纸)

cin >> noskipws;//让cin能够读取空白符

未列入知识点

  • 未格式化的输入输出操作
  • 流随机访问
  • 正则表达式:书中只介绍了相关库的使用方法,这部分本身也比较难,本文不引入
上一篇 下一篇

评论 | 0条评论