尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

27. 其他库

27. 其他库 其他库专用类库complex、random、valarrayC 还提供了一些更专用的类库。头文件 complex 为复数提供了类模板 complex包含用于 float、double 和 long double 的具体化提供标准的复数运算及能够处理复数的标准函数。C11 新增的头文件 random 提供了更多的随机数功能原因复数运算、随机数、数值数组是三类专用的数值计算需求由独立库提供比在语言核心中内建更合理。#include complex // 复数模板类所在头文件 #include random // C11 随机数功能所在头文件 #include valarray // 数值数组模板类所在头文件 std::complexdouble z(1.0, 2.0); // 复数对象 std::valarraydouble v(10); // 10 个 double 的数值数组vector、valarray 与 array 的设计定位C 提供三个数组模板由不同的小组开发、用于不同的目的。vector 模板类是容器类和算法系统的一部分支持面向容器的操作如排序、插入、重新排列、搜索、将数据转移到其他容器中。valarray 类模板面向数值计算不是 STL 的一部分——没有 push_back() 和 insert() 方法但为很多数学运算提供了一个简单、直观的接口。array 是为替代内置数组而设计的通过提供更好、更安全的接口让数组更紧凑、效率更高它表示长度固定的数组因此不支持 push_back() 和 insert()但提供了多个 STL 方法包括 begin()、end()、rbegin()、rend()使得很容易将 STL 算法用于 array 对象。三类数组各自服务于不同场景——vector 面向通用容器操作、valarray 面向数值计算、array 面向定长且安全的数组替代。规则限制valarray 类关注的东西比 vector 少但这使得它的接口更简单array 因定长不支持调整大小的操作。valarray 的算术运算符重载定义是什么valarray 类重载了所有算术运算符使其能够用于 valarray 对象。// valarray 重载算术运算符逐元素运算 vad3 vad1 vad2; // 对应元素相加 vad3 vad1 * vad2; // 对应元素相乘 vad3 2.5 * vad3; // 标量乘法运算符重载 vad3 * 2.5; // 组合赋值运算符valarray 的数学函数与 applyvalarray 类重载了数学函数如 log使之接受一个 valarray 参数并返回一个 valarray 对象因此可以写 vad3 log(vad1);。也可以使用 apply() 方法该方法适用于非重载函数vad3 vad1.apply(log);。// 数学函数重载接受 valarray 参数、返回 valarray 对象 vad3 log(vad1); // log() 被重载用于 valarray vad3 vad1.apply(log); // apply()适用于非重载函数 // apply() 不修改调用对象返回包含结果的新对象valarray 的简单接口与性能执行多步计算时valarray 接口的简单性更为明显。valarray 类还提供了方法 sum()计算所有元素的和、size()返回元素数、max()返回最大元素值和 min()返回最小元素值。它有 resize() 方法但不能像 vector 的 push_back 那样自动调整大小没有支持插入、排序、搜索等操作的方法。// 多步数值计算valarray 简洁表达 // vad3 10.0 * ((vad1 vad2) / 2 vad1 * cos(vad2)); double total vad1.sum(); // 所有元素之和 size_t n vad1.size(); // 元素数 double hi vad1.max(); // 最大元素 double lo vad1.min(); // 最小元素将 STL 用于 valarray自由函数 begin()/end()valarray 类没有 begin() 和 end() 方法因此不能将它们用作指定区间的参数vad 是对象而非指针也不能用 vad 和 vad 10 作为区间参数。使用地址运算符 sort(vad, vad[10]) 可能可行但 valarray 没有定义下标超过尾部一个元素的行为不保证可靠。为解决这个问题C11 提供了接受 valarray 对象作为参数的模板函数 begin() 和 end()——使用 begin(vad) 而不是 vad.begin()这些函数返回的值满足 STL 区间需求。// valarray 不能使用成员 begin/end也没有指针算术 // sort(vad.begin(), vad.end()); // 错误无 begin/end 方法 // sort(vad, vad 10); // 错误vad 是对象不是地址 // sort(vad, vad[10]); // 可能可行但无保证 std::sort(begin(vad), end(vad)); // C11 自由函数返回满足区间需求的值valarray 与 slice 类valarray 类还有其他特性。若 numbers 是 valarraydouble 对象valarraybool vb001 numbers 9; 创建 bool 数组其中 vb001[i] 被设置为 numbers[i] 9 的值true 或 false。还有扩展的下标指定版本——slice 类对象可用作数组索引表示的不是一个值而是一组值。slice 对象被初始化为三个整数值起始索引start index第一个被选中的元素的索引、索引数number of indices要选择多少个元素和跨距stride元素之间的间隔。// slice起始索引、索引数、跨距三个整数 std::slice(1, 4, 3); // 选中索引 1、4、7、10 的元素 valint[std::slice(1, 4, 3)] 10; // 把选中元素都设置为 10 // 用一维 valarray 表示二维数据 // slice(0, 3, 1) 表示第 1 行元素 0、1、2 // slice(0, 4, 3) 表示第 1 列元素 0、3、6、9 // slice 指定的单元不定义 须先构造完整 valarray 对象模板 initializer_listC11与容器初始化模板 initializer_list 是 C11 新增的可使用初始化列表语法将 STL 容器初始化initialization为一系列值如 std::vectordouble payments {45.99, 39.23, 19.95, 89.01};要在代码中使用 initializer_list 对象必须包含头文件 initializer_list。这个模板类包含成员函数 begin() 和 end()可用来访问列表元素还包含成员函数 size()返回元素数。可按值传递 initializer_list 对象也可按引用传递这种对象本身很小通常是两个指针或一个指针和一个表示元素数的整数因此传递方式不会带来重大的性能影响STL 按值传递它们。除非类要用于处理长度不同的列表否则让它提供接受 initializer_list 作为参数的构造函数没有意义。对于存储固定数目值的类。因为定长类的数据成员数目固定用长度可变的初始化列表表达没有意义保留普通构造函数即可。为容器提供统一的“用值列表初始化”语法省去逐个 push_back 或区间构造。// 初始化列表构造容器 std::vectordouble payments {45.99, 39.23, 19.95, 89.01}; // 若类有 initializer_list 构造函数{} 语法调用它 // std::vectorint vi(10); // 10 个未初始化元素 // std::vectorint vi({10}); // 1 个元素设为 10 // 元素类型须相同编译器做必要转换禁止隐式窄化 // std::vectorint values{10, 8, 5.5}; // 错误5.5 窄化知识点描述专用类库complex复数模板类float/double/long double 具体化randomC11更多随机数功能valarray数值数组模板类支持数组相加、逐元素数学函数、线性代数运算。vector、valarray 与 array 的定位vector 是容器类/算法系统一部分支持排序、插入、搜索valarray 面向数值计算非 STL 一部分无 push_back/insert数学接口直观array 替代内置数组、定长、更安全紧凑有 STL 方法便于用算法。valarray 的算术运算符重载重载全部算术运算符vad3 vad1 vad2逐元素、vad3 vad1 * vad2、标量乘vad3 2.5 * vad3、组合赋值vad3 * 2.5。valarray 的数学函数与 apply()数学函数如 log重载为接受 valarray 参数并返回 valarrayapply()适用于非重载函数apply() 不修改调用对象、返回新对象。valarray 的接口与性能多步计算表达简洁提供 sum/size/max/min有 resize() 但无自动调整、无插入/排序/搜索方法接口简单不必然性能更高通常以循环实现但硬件矢量操作在原则上可被利用。将 STL 用于 valarrayvalarray 无 begin/end 成员、对象非指针vad[10]超尾语义无保证C11 提供接受 valarray 的模板自由函数 begin()/end()返回满足 STL 区间需求的值。valarray 与 slice 类valarraybool v numbers 9生成比较结果数组slice(起始索引, 索引数, 跨距) 作下标选中一组元素可用于一维 valarray 表示二维数据slice 指定的单元不定义须先构造完整对象gslice 表示多维下标。模板 initializer_list 与容器初始化C11 新增容器有接受 initializer_list 的构造函数{}语法初始化容器有该构造函数的类用{}调用它vi(10)vsvi({10})元素须同类型且禁止隐式窄化。无 initializer_list 构造函数的类定长类无须提供 initializer_list 构造函数无此构造函数时{}语法调用普通构造函数如Position A {20, 30, 0}。使用 initializer_list头文件initializer_list含 begin/end/size对象很小两指针或指针整数STL 按值传递参数可为字面量或变量迭代器为 const 不可修改但可赋值给另一个。
返回列表