当前位置: 首页 > news >正文

博罗网站建设本地app制作公司

博罗网站建设,本地app制作公司,产品市场营销策划书,无本钱一天挣1000其他库 C 还提供了其他一些类库#xff0c;它们比本章讨论前面的例子更为专用。例如#xff0c;头文件 complex 为复数提供了类模板 complex#xff0c;包含用于 float、long 和 long double 的具体化。这个类提供了标准的复数运算及能够处理复数的标准函数。C11 新增的头文…其他库 C 还提供了其他一些类库它们比本章讨论前面的例子更为专用。例如头文件 complex 为复数提供了类模板 complex包含用于 float、long 和 long double 的具体化。这个类提供了标准的复数运算及能够处理复数的标准函数。C11 新增的头文件 random 提供了更多的随机数功能。 第14章介绍了头文件 valarry 提供的模板类 valarray。这个类模板被设计成用于表示数值数组支持各种数值数组操作例如将两个数组的内容相加、对数组的每个元素应用数学函数以及对数组进行线性代数运算。 vector、valarray 和 array 你可能会问C 为何提供三个数组模板vector、valarray 和 array。这些类是由不同的小组开发的用于不同的目的。vector 模板类是一个容器类和算法系统的一部分它支持面向容器的操作如排序、插入、重新排列、搜索、将数据转移到其他容器中等。而 valarray 类模板是面向数值计算的不是 STL 的一部分。例如它没有 push_back() 和 insert() 方法但为很多数学运算提供了一个简单、直观的接口。最后 array 是为替代内置数组而设计的它通过提供更好、更安全的接口让数组更紧凑效率更高。Array 表示长度固定的数组因此不支持 push_back() 和 insert()但提供了多个 STL 方法包括 begin()、end()、rbegin() 和 rend()这使得很容易将 STL 算法用于 array 对象。 例如假设有如下声明 vectordouble vedl(10), ved2(10), ved3(10); arraydouble, 10 vod1, vod2, vod3; valarraydouble vad1(10), vad2(10), vad3(10);同时假设 ved1、ved2、vod1、vod2、vad1 和 vad2 都有合适的值。要将两个数组中第一个元素的和赋给第三个数组的第一个元素使用 vector 类时可以这样做 transform(ved1.begin(), ved1.end(), ved2.begin(),, ved3.begin(), plusdouble() );对于 array 类也可以这样做 transfrom(vod1.begin(), vod1.end(), vod2.begin(), vod3.begin(), plusdouble() );然而valarray 类重载了所有算术运算符使其能够用于 valarray 对象因此您可以这样做 vad3 vad1 vad2; // overloaded要将数组中每个元素的值扩大 2.5 倍STL 方法如下 transform(ved3.begin(), ved3.end(), ved3.begin(), bind1st(multipliesdouble(), 2.5) );valarray 类重载了将 valarray 对象乘以一个值的运算符还重载了各种组合赋值运算符因此可以采取下列两种方法之一 vad3 2.5 * vad3; // * overloaded vad3 * 2.5; // * overloaded假设您要计算数组中每个元素的自然对数并将计算结果存储到另一个数组的相应元素中STL 方法如下 transform(ved1.begin(), ved1.end(), ved3.begin(), log);valarray 类重载了这种数学函数使之接受一个 valarray 参数并返回一个 valarray 对象因此您可以这样做 vad3 log(vad1); // log() overloaded也可以使用 apply() 方法该方法也适用于非重载函数 vad3 vad1.apply(log);方法 apply() 不修改调用对象而是返回一个包含结果的新对象。 执行多步计算时valarray 接口的简单性将更为明显 vad3 10.0 * ( (vad1 vad2) / 2.0 vad1 * cos(vad2) );有关使用 STL vector 来完成上述计算的代码留给您去完成。 valarray 类还提供了方法 sum()计算 valarray对象中所有元素的和、size() 返回元素数、max()返回最大的元素值和 min() 返回最小的元素值。 正如您看到的对于数学运算而言valarray 类提供了比 vector 更清晰的表示方式但通用性更低。valarray 类确实有一个 resize() 方法但不能像使用 vector 的 push_back 时那样自动调整大小。没有支持插入、排序、搜索等操作的方法。总之与 vector 类相比valarray 类关注的东西更少但这使得它的接口更简单。 valarray 的接口更简单是否意味着性能更高呢在大多数情况下答案是否定的。简单表示法通常是使用类似于您处理常规数组时使用的循环实现的。然而有些硬件设计允许在执行 vector 操作时同时将一个数组中的值加载到一组寄存器中然后并行地进行处理。从原则上说valarray 操作也可以实现成利用这样的设计。 可以将 STL 功能用于 valarray 对象吗通过回答这个问题可以快速地复习一些 STL 原理。假设有一个包含 10 个元素的 valarraydouble 对象 valarraydouble vad(10);使用数字填充该数组后能够将 STL sort() 函数用于该数组吗valarray 类没有 begin() 和 end() 方法因此不能将它们用作指定区间的参数 sort(vad.begin(), vad.end()); // NO, no begin(), end()另外vad 是一个对象而不是指针因此不能像处理常规数组那样使用 vad 和 vad 10 作为区间参数即下面的代码不可行 sort(vad, vad 10); // NO, vad an object, not an address可以使用地址运算符 sort(vad[0], vad[10]); // maybe?但 valarray 没有定义下标超过尾部一个元素的行为。这并不意味着使用 vad[10] 不可行。事实上使用 6 中编译器测试上述代码时都是可行的但这确实意味着可能不可行。为让上述代码不可行需要一个不太可能出现的条件如让数组与预留给堆的内存块相邻。然而如果 3.85 亿的交易金命悬与您的代码您可能不想冒代码出现问题的风险。 为解决这种问题C11 提供了接受 valarray 对象作为参数的模板函数 begin() 和 end()。因此您将使用 begin(vad) 而不是 vad.begin。这些函数返回的值满足 STL 区间需求 sort(begin(vad), end(vad) ); // C11 fix!下面的程序演示了 vector 和 valarray 类各自的优势。它使用 vector 的 push_back() 方法和自动调整大小的功能来收集数据然后对数字进行排序后将它们从 vector 对象复制到一个同样大小的 valarray 对象中再执行一些数学运算。 // valvect.cpp -- comparing vector and valarray#include ios #includeiostream #includevalarray #includevector #includealgorithmint main() {using namespace std;vectordouble data;double temp;cout Enter numbers (0 to quit):\n;while(cin temp temp 0){data.push_back(temp);}sort(data.begin(), data.end());int size data.size();valarraydouble numbers(size);int i;for(i0; isize; i){numbers[i] data[i];}valarraydouble sq_rts(size);sq_rts sqrt(numbers);valarraydouble results(size);results numbers 2.0 * sq_rts;cout.setf(ios_base::fixed);cout.precision(4);for (i0; i size; i){cout.width(8);cout numbers[i] : ;cout.width(8);cout results[i] endl;}cout done\n;return 0; }下面是程序的运行情况 Enter numbers (0 to quit): 3.3 1.8 5.2 10 14.4 21.6 26.9 01.8000: 4.48333.3000: 6.93325.2000: 9.760710.0000: 16.324614.4000: 21.989521.6000: 30.895226.9000: 37.2730 done除前面讨论的外valarray 类还有很多其他特性。例如如果 numbers 是一个 valarraydouble 对象则下面的语句将创建一个 bool 数组其中 vbool[i] 被设置为 numbers[i] 9 的值即 true 或 false valarraybool vbool numbers 9;还有扩展的下标指定版本来看其中的一个——slice 类。slice 类对象可用作数组索引在这种情况下它表的不是一个值而是一组值。slice 对象被初始化为三个整数值起始索引、索引数和跨距。起始索引是第一个被选中的元素的索引索引数指出要选择多少个元素跨距表示元素之间的间隔。例如slice(1,4,3) 创建的对象标识选择 4 个元素它们的索引分别是1、4、7、10。也就是说从起始索引开始加上跨距得到下一个元素的索引依此类推直到选择了 4 个元素。如果 varint 是一个 valarrayint对象则下面的语句将把第1、4、7、10个元素都设置为10 varint[slice(1,4,3)] 10; // set selected elements to 10这种特殊的下标指定功能让您能够使用一个一维 valarray 对象来表示二维数据。例如假设要表示一个4行3列的数组可以将信息存储在一个包含12个元素的valarray对象中然后使用一个 slice031)对象作为下标来表示元素0、1、2即第1行。同样下标 slice(0,4,3)表示元素0、3、6、9即第一列。下面的程序演示了 slice 的一些特性。 // vslice.cpp -- using valarray slices #includeiostream #includevalarray #includecstdlibconst int SIZE 12; typedef std::valarrayint vint; // simplify declaratrions void show(const vint v, int cols);int main(){using std::slice; // from valarrayusing std::cout;vint valint(SIZE); // think of as 4 rows of 3int i;for (i0; i SIZE; i){valint[i] std::rand()%10;}cout Original array:\n;show(valint, 3); // show in 3 columnsvint vcol(valint[slice(1,4,3)]); // extract 2nd columncout Second column:\n;show(vcol, 1); // show in 1 columnvint vrow(valint[slice(3,3,1)]); // extract 2nd rowcout Second row:\n;show(vrow, 3);valint[slice(2,4,3)] 10; // assign 10 to 3 columncout Set last column to 10:\n;show(valint, 3);cout Set first column to sum of next two:\n;// not defined for slices, so convert to valarrayintvalint[slice(0,4,3)] vint(valint[slice(1,4,3)]) vint(valint[slice(2,4,3)]);show(valint, 3);return 0; }void show(const vint v, int cols){using std::cout;using std::endl;int lim v.size();for (int i 0; i lim; i){cout.width(3);cout v[i];if(i%cols cols -1 )cout endl;elsecout ;}if(lim%cols!0)cout endl; }对于 valarray 对象如 valint和单个 int 元素如 valint[1]定义了运算符但正如程序指出的对于使用 slice 下标指定的 valarray 单元如 valint[slice(1,4,3)]并没有定义运算符。因此程序使用 slice 指定的元素创建一个完整的 valint 对象以便能够执行加法运算 vint(valint[slice(1,4,3)]) // calls a slice-based constructorvalarray 类提供了用于这种目的的构造函数。 下面是该程序的运行情况 Original array:1 7 40 9 48 8 24 5 5 Second column:7985 Second row:0 9 4 Set last column to 10:1 7 100 9 108 8 104 5 10 Set first column to sum of next two:17 7 1019 9 1018 8 1015 5 10由于元素值是使用 rand() 设置的因此不同的 rand() 实现将设置不同的值。 另外使用 gslice 类可以表示多维下标但上述内容应足以让您对 valarray 有一定的了解。 模板 initializaer_list(C11) 模板 initializer_list 是 C11 新增的。您可使用初始化列表语法将 STL 容器初始化为一系列值 std::vectordouble payments { 45.99, 39.23, 19.95, 89.01};这将创建一个包含 4 个元素的容器并使用列表中的 4 个值来初始化这些元素。这之所以可行是因为容器类现在包含将 initializer_listT 作为参数的构造函数。例如vectordouble 包含一个将 initializer_listdouble 作为参数的构造函数因此上述声明与下面的代码等价 std::vectordouble payments({45.99, 39.23, 19.95, 89.01});这里显式地将列表指定为构造函数参数。 通常考虑到 C11 新增的通用初始化语法可使用表示法{} 而不是 () 来调用类构造函数 shared_ptrdouble pd {new double}; // ok to use {} instead of ()但如果类也有接受 initializer_list 作为参数的构造函数这将带来问题 std::vectorint vi{10}; // ??这将调用哪个构造函数呢 std::vectorint vi(10); // case A: 10 uninitialized elements std::vectorint vi({10}); // case B: 1 element set to 10答案是如果类有接受 initializer_list 作为参数的构造函数则使用语法 {} 将调用该构造函数。因此在这个示例中对应的是情形 B。 所有 initializer_list 元素的类型都必须相同但编译器将进行必要的转换 std::vectordouble payments {45.99, 39.23, 19, 89}; // same as std::vectordouble payments { 45.99, 39.23, 19.0, 89.0 };在这里由于 vector 的元素类型为 double因此列表的类型为 initializer_listdouble所以 19 和 89 将被转换为 double。 但不能进行隐式的缩窄变换 std::vectorint values {10, 8, 5.5 }; // narrowing, compile-time error在这里元素类型为 int不能隐式地将 5.5 转换为 int。 除非类要用于处理长度不同的列表否则让它提供接受 initializer_list 作为参数地构造函数没有意义。例如对于存储固定数目值得类您不想提供接受 initializer_list 作为参数的构造函数。在下面的声明中类包含三个数据成员因此没有提供 Initializer_list 作为参数的构造函数 class Position { private:int x;int y;int z; public:Position(int xx 0, int yy 0, int zz 0 ): x(xx), y(yy), z(zz) {}// no initializer_list constructor... };这样使用语法 {} 时将调用构造函数 Position(int, int, int): Position A {20, -3}; // uses Position(20,-3,0);使用 initializer_list 要在代码中使用 initializer_list 对象必须包含头文件 initializer_list。这个模板类包含成员函数 begin() 和 end()您可使用这些函数来访问列表元素。它还包含成员函数 size()该函数返回元素数。下面的程序时一个简单的 Initializer_list 使用示例它要求编译器支持 C11 新增的 initializer_list。 // ilist.cpp -- use initializer_list (C111 feature)#includeiostream #includeinitializer_listdouble sum(std::initializer_listdouble il); double average(const std::initializer_listdouble ril);int main(){using std::cout;cout List 1: sum sum({2, 3, 4}) , ave average({2, 3, 4}) \n;std::initializer_listdouble dl {1.1, 2.2, 3.3, 4.4, 5.5};cout List 2: sum sum(dl) , ave average(dl) \n;dl {16.0, 25.0, 36.0, 46.0, 64.0};cout List 3: sum sum(dl) , ave average(dl) \n;return 0;}double sum(std::initializer_listdouble il){double tot 0;for (auto p il.begin(); p ! il.end(); p){tot *p;}return tot; }double average(const std::initializer_listdouble ril){double tot 0;int n ril.size();double ave 0.0;if (n0) {for (auto p ril.begin(); p!ril.end(); p){tot *p;}ave tot / n;}return ave; }该程序的输出如下 List 1: sum 9, ave 3 List 2: sum 16.5, ave 3.3 List 3: sum 187, ave 37.4可按值传递 initializer_list 对象也可按引用传递如 sum() 和 average() 所示。这种对象本身很小通常是两个指针一个指向开头一个指向末尾的下一个元素也可能是一个指针和一个表示元素数的整数因此采用的传递方式不会带来重大的性能影响。STL 按值传递它们。 函数参数可以是 initializer_lit 字面量如 {2, 3, 4}也可以是 initializer_list 变量如 dl。 initializer_list 的迭代器类型为 const因此您不能修改 initializer_list 中的值 *dl.begin() 2011.6; // not allowed然而提供 initialzier_list 类的初衷旨在让您能够将一系列值传递给构造函数或其他函数。
http://www.ho-use.cn/article/10812006.html

相关文章:

  • 网站备案的要求重庆seo是什么
  • 黄山网站建设找哪家做网站域名的成本
  • canvas效果网站上海本地app推荐
  • 如何做一个内部网站中文响应式网站
  • 校园电子商务网站建设精品网站开发
  • 12黄页网站建设网站做推广百度好还是360好
  • 企业网站建设怎么样鲜花网站建设店
  • 做网站 服务器多少钱一年网站建设宣传的目的
  • 制作网站要什么软件百度代发排名
  • 不需要网站备案的广告联盟网站建设辅助导航
  • 可以做伦铜的网站上市公司
  • 深圳甜富设计网站seo最新优化方法
  • 甘露园网站建设商业网站源码免费下载
  • 受欢迎的唐山网站建设济南市建设工程交易网
  • 哪个网站能帮助做试卷学网站建设的好处
  • 做视频导航网站农家乐网站模板
  • 做网站软件下载搬家公司收费价格表
  • 做餐饮如何加入外卖网站西安前端开发培训机构哪个比较好
  • wap网站自动西安企业电话
  • 比较大网站建设公司南山制作网站公司
  • 柳州做网站有kv文创产品设计手绘
  • 北京市丰台区建设部官方网站怀化主要网站
  • 购物网站设计目标焦作专业做网站公司
  • 北京 代理前置审批 网站备案注册公司经营范围怎么选择
  • 洛阳网站建设哪家好培训学校网站建设要点
  • 网站开发后台数据怎么来网站建设擎宇
  • 网站排名站长之家济宁房地产网站建设
  • 建站之星怎么用博创网站建设团队
  • 收纳用品网站建设北京室内设计公司排名榜
  • 智能科技网站模板下载网站名和域名