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

网站一屏做多大做木材生意的外贸网站

网站一屏做多大,做木材生意的外贸网站,成都网络公司,wordpress导航仿制一.绪论#xff1a; 1.1 C简史#xff1a; 与C的关系#xff1a; 被设计为C语言的继任者#xff0c;C语言是一种过程型语言#xff0c;程序员使用它定义执行特定操作的函数#xff0c;而C是一种面向对象的语言#xff0c;实现了继承、抽象、多态和封装等概念。C支持类 1.1  C简史 与C的关系 被设计为C语言的继任者C语言是一种过程型语言程序员使用它定义执行特定操作的函数而C是一种面向对象的语言实现了继承、抽象、多态和封装等概念。C支持类而类包含成员数据及操作数的成员方法方法类似于C语言的函数。 C优点 C是一种中级变成语言这意味着使用它既可以高级编程方式编写应用程序又可以低级变成方式编写与硬件紧密协作的库。在很多程序员看来C既是一种高级语言让他们能够开发复杂的应用程序又提供了极大的灵活性让开发人员能够控制资源的使用和可用性从而最大限度地提高性能。 1.2 编写C应用程序  生成可执行文件的步骤 C代码通常包含在.CPP文本文件中被转换为处理器能够处理的字节码。编译器每次转换一个代码文件生成一个扩展名为.o或.obj的目标文件并忽略这个CPP文件可能对其他文件中代码的依赖。解析这些依存关系的工作由链接程序负责。除将各种目标文件组合起来外链接程序还建立依存关系如链接成功则创建一个可执行文件供程序员执行和分发。 C11新增的功能 auto能够定义这样的变量即编译器将自动推断其类型这简化变量声明同时又不影响类型安全。Lambda函数是没有名称的函数能够编写紧凑的函数对象而无需提供冗长的类定义从而极大地减少了代码。C11让程序能够编写可移植的多线程C应用程序同时确保它们遵守标准。这些程序支持并行执行范式在用户升级到多核CPU以改善硬件配置时其性能将相应提升。       二、C程序组成部分 C程序由类、函数、变量及其他元素组成。 预处理器编译指令#include: 预处理器编译指令时向预处理器发出命令总是以符号#打头。尖括号通常包含标准头文件#includeiostream。 名称空间概念 为避免添加限定符可使用using namespace。 #include test.h #include iostream int test::main1() {using namespace std;cout Hello World endl;return 0; }int test::main2() {std::cout Hello World std::endl;return 0; }int test::main3() {using std::cout;using std::endl;cout Hello World endl;return 0; } C函数 C函数与C语言函数相同。函数可将应用程序划分多个功能单元并按选择顺序调用。函数被调用时通常将一个值返回调用它的函数。 三、使用变量和常量 变量能够将数据临时存储一段时间而常量能够定义不允许修改的东西。 编译器支持的常见C变量类型           使用sizeof确定变量的长度 变量长度指的是声明变量时编译器将预留多少内存用于存储赋给该变量的数据。变量的长度随类型而异。 使用typedef替换变量类型 typedef unsigned int STRICTY_POSITIVE_INTEGER; int test::main1() {STRICTY_POSITIVE_INTEGER positiveInteger 55555;return 0; } 常量 常量类似于变量只是不能修改。与变量一样常量也是占用内存空间并使用名称标识为其预留空间的地址但是不能覆盖该空间的内容。 字面常量使用关键字const声明的常量使用关键字constexpr声明的常量表达式C11新增的使用关键enum声明的枚举常量使用#defind定义的常量已屏蔽不推荐。 四、管理数组和字符串 什么是数组 数组是以系列元素数据中所有元素的类型都相同这组元素形成一个完整的集合。 动态数组 #include vector int test::main1() {std::vectorint dynArr(3);dynArr[0] 365;dynArr[1] 36;dynArr[2] 35;dynArr.push_back(20);return 0; } 五、使用表达式、语句和运算 从本质上说程序是一组按顺序执行的命令。这些命令的表达式和语句使用运算符执行特定的计算或操作。 使用运算符 运算福是C提供的工具能够使用数据对其进行变换、处理甚至根据数据做决策。 赋值运算符左值通常是内存单元右值可以使内存单元的内容加法运算符、减法运算符-、乘法运算符*、除法运算符/和求模运算符%递增运算符和递减运算符--放在操作数时称为前缀递增或递减运算符而放在操作数时称为后缀递增或递减运算符。相等运算符和不等运算符!;关系运算符 逻辑运算符NOT、AND、OR、XOR逻辑NOT运算用运算符!表示用于单个操作数将提供的布尔标记反转逻辑AND运算用运算符表示仅当两个操作数都为true时结果才为true逻辑OR运算用||符号表示只要有一个操作数为true则结果为true逻辑XOR异或有且只有一个操作数为true时结果才为true符号为^表示。按位运算符NOT~、AND()、OR(|)、XOR(^)逻辑运算符和按位运算符之间的差别在于按位运算符返回的并非布尔值而是对操作数对应位执行指定运算的结果。按位右移运算符和左移运算符移位运算符将整个位序列向左或向右移动其用途之一是将数据乘以或除以2的N次方复合赋值运算符 运算符sizeof确定变量占用的内存量指出特定类型或变量的内存量单位位字节。sizeof(variable)或sizeof(type)。运算符的优先级 六、控制程序流程 if...else条件控制switch-case条件控制三目运算符?:条件控制不成熟的goto循环将指令指针移到代码的特定位置使用goto回过头再去执行特定语句。不推荐使用goto。 void test::main3() {JumpToPoint:std::vectorint dynArr(3);dynArr[0] 365;dynArr[1] 36;dynArr[2] 35;dynArr.push_back(20);goto JumpToPoint; } while循环do...while循环需要将代码放在循环中并确保至少执行一次for循环continue和break修改循环的行为。 七、使用函数组织代码 1.函数原型是什么 函数原型指出了函数的名称、函数接受的参数列表以及返回值的类型。 函数调用和实参 函数声明中包含形参调用函数时必须提供实参。 带默认值的函数参数 参数包含默认值的函数这种默认值可被用户提供的值覆盖。可以给出多个参数指定默认值但这些参数必须位于参数列表的末尾。 递归函数——调用自己的函数 递归函数必须有明确的退出条件满足这种条件后函数将返回而不再调用自己。 2. 使用函数处理不同类型的数据 并非只能每次给函数传递一个值还可将数组传递给函数。可创建多个名称和返回值类型相同但参数不同的函数。也可创建其参数不是在函数内部创建和销毁的为此可使用在函数退出后还可用的引用这样搞可在函数中操纵更多数据或参数。 函数重载 名称和返回类型相同但参数不同的函数被称为重载函数。 将数组传递给函数按引用传递参数 微处理如何处理函数调用 函数调用意味着微处理器跳转到属于被调用函数的下一条指令处执行。执行完函数的指令后将返回到最初离开的地方。为实现这种逻辑编译器将函数调用转换为一条供微处理器执行CALL指令该指令指出了接下来要获取的指令所在的地址该地址归函数所有。编译函数本身时编译器将return语句转换为一条供微处理器的RET指令。 遇到CALL指令时微处理器将调用函数后将执行的指令的位置保存到栈中再跳转到CALL指令包含的内存单元处。 该内存单元包含属于函数的指令。微处理器执行它们直到到达RET语句。 RET语句导致微处理器从栈中弹出执行CALL指令时存储的地址。该地址包含调用函数中接下来要执行的雨具的位置。这样微处理器将返回到调用函数从离开的地方继续执行。 内联函数 常规函数调用转换为CALL指令这会导致栈操作、微处理器跳转到函数处执行等。而inline函数被调用时就地展开。将函数声明为内联的会导致代码急剧膨胀在声明为内联的函数做了大量复杂处理时尤其如此。应尽可能少用关键字inline仅当函数非常简单需要降低其开销时才使用该关键字。 lambda函数 八、阐述指针和引用 指针 指针是存储内存地址的变量与所有变量一样指针也占用内存空间。指针的特殊之处在于指针包含的值被解读为内存地址因此指针是一种指向内存单元的特殊值。 声明指针 作为一种变量指针也需声明通常将指针声明为指定特定类型也可将指针声明为指向一个内存块这种指针被称为void指针。 使用引用运算符获取变量的地址 要将变量的地址存储到一个指针中需要声明一个同样类型的指针并使用引用运算符将其初始化为该变量的地址。 使用解除引用运算符*访问指向的数据 使用解除引用运算符*用于指针时应用程序从它存储的地址开始取回内存中4个字节的内容因此指针包含的地址必须合法。 将sizeof用于指针的结果 指针时包含内存地址的变量因此无论指针指向哪种类型变量其内容都是一个地址——一个数字。在特定的系统中存储地址所需的字节是固定的。因此将sizeof用于指针时结果取决于编译程序时使用的编译器和针对的操作系统与指针指向的变量类型无关。 动态内存分配 要编写根据用户需要使用内存资源的应用程序需要使用动态内存分配。能够根据需要分配更多内存并释放多余的内存。为帮助更好的管理应用程序占用的内存C提供了两个运算符——new和delete。指针是包含内存地址的变量在高效地动态分配内存方面扮演了重要角色。 使用new和delete动态地分配和释放内存 使用new来分配新的内存块。如成功new将返回指向一个指针指向分配的内存否则将引发异常。使用new时需要指定要为哪种数据类型分配内存使用new分配的内存最终都需要使用对应的delete进行释放。对于使用new[...]分配的内存块需要使用delete[]来释放。 int* pointer new int[10];delete pointer; 将递增和递减运算符和--用于指针的结果 将指针递增或递减时其包含的地址将增加或减少指向的数据类型的sizeof并不是一定1字节。这样编译器将确保指针不会指向数据的中间或末尾而只会指向数据的开头。 将关键字const用于指针 通过将变量声明为const的可确保变量的取值在整个生命周期内都是固定位初始值。这种变量的值不能修改因此不能将其用作左值。 指针指向的数据为常量不能修改但可以修改指针包含的地址即指针可以指向其他地方。 int housInDay 24;const int* pInt housInDay; //不能使用pInt去改变int monthsInyear 12;pInt monthsInyear; //可以修改包含的地址*pInt 13; //编译失败不能改变数据int * pInt1 pInt; //编译失败不能指定const 指针包含的地址是常量不能修改但可以修改指针指向的数据 int dayInMonth 30;int* const pDayInMonth dayInMonth; *pDayInMonth 31; //可以修改指向的数据int dayIn2Month 28;pDayInMonth dayIn2Month; //不能该指向的地址 指针包含的地址以及它指向的值都是常量不能修改  int hourInDay 24;const int* const pHourInDay hourInDay; //指针仅仅指向hourInDay*pHourInDay 25; //编译失败不能修改指向的数据int dayInDay 25;pHourInDay dayInDay; //编译失败不能修改指针指向的地址 将指针传递给函数 指针是一种将内存空间传递给函数的有效方式其中可以包含值也可以包含结果。将指针作为函数参数时确保函数只能修改要修改的参数很重要。 使用指针时时常犯的编程错误 C能够动态地分配内存以优化应用程序对内存使用。不同于Java和C#等基于运行时环境的新语言C没有自动垃圾收集器对程序已分配但不能使用的内存进行清理。 内存泄漏如在使用new动态分配的内存不再需要后没有使用配套的delete释放指针向无效的内存单元使用运算符*对指针解除引用以访问指向的值时务必确保指针指向了有效的内存单元否则程序要么崩溃要么行为不端。悬浮指针也叫迷途或失控指针使用delete释放后任何有效指针都将无效。为避免这种问题在初始化指针或释放指针后将其设置为NULL并在使用运算符*对指针解除引用前检查它是否有效。 指针编程最佳实践 检查使用new发出的分配请求是否得到满足 除非请求分配的内存量特大或系统处于临界状态可供使用的内存很少new一般都能成功。有些应用程序需要请求分配大块的内存如数据库应用程序一般而言不要假定内存分配能成功这很重要。C提供了两种确保指针有效的方法默认方法是使用异常即如内存分配失败将引发std::bad_alloc异常。这导致应用程序中断执行除非提供了异常处理程序否则应用程序将崩溃并显示一条类似于“异常未处理”的消息。 有一种new变种——newnewthrow它不引发异常而返回NULL能够在使用指针检查其有效性 int* pAge new(std::nothrow)int[0x1fffffff];if (pAge){delete[] pAge;} else{} 引用是什么 引用是变量的别名。声明引用时需要将其初始化为一个变量因此引用只是另一种访问相应变量存储的数据的方式。 引用能够访问相应变量所在的内存单元 Returntype doSomething(Type Parameter);//会将argumnet赋值给Parameter再被doSomething()调用// 如argumnet占用大量内存这个复制过程的开销很大Returntype returntype doSomething(argumnet);Returntype doSomething(Type Parameter);//由于argumnet1是按引用传递的Parameter不再是argumnet的拷贝而是它的别名Returntype returntype doSomething(argumnet1); 将关键字const用于引用 可能需要禁止通过引用修改它指向的变量的值为此 可在声明引用时使用关键字const。 int origin 30;const int contRef origin;contRef 40; //不被允许 引用contRef修改origin的值int ref2 contRef; //不被允许ref2没有被const修饰const int ref3 contRef; 按引用向函数传递参数 引用的有点之一是可避免将形参复制给形参从而极大地提高性能。然而让被调用的函数直接使用调用函数栈时确保被调用不能修改调用函数中的变量很重要。为此可将引用声明为const的。 九、类和对象 类、成员属性、函数访问 声明类可使用关键字class并在它后面一次包含类名、一组放在{}内的成员属性和方法以及结尾的分号实例化对象要使用类的功能通常需要根据类实例化一个对象并通过对象访问成员方法和属性使用句点运算符访问成员使用指针运算符-访问成员如对象是使用new在自由存储区中实例化或有指向对象的指针则可使用指针运算符-来访问成员属性和方法。 关键字public和private 构造函数 构造函数是一种特殊的函数方法在创建时被调用。与函数一样构造函数也可以重载。 声明和实现构造函数构造函数是一种特殊的函数它与类名同名且不返回任何值重载构造函数没有默认构造函数的类带默认值的构造函数参数包含初始化列表的构造函数 析构函数 与构造函数一样析构函数也是一种特殊的函数。与构造函数不同的是析构函数在对象销毁时被自动调用。 声明和实现析构函数与类同名的函数但前面有一个波浪号~。何时及如何使用析构函数每当对象不再作用域内或通过delete被删除进而被销毁都将调用析构函数。这使得析构函数是重置变量以及释放动态分配的内存和其他资源的理想场所析构函数不能重载每个类都只能有一个析构函数如未实现析构函数编译器将创建一个伪dummy析构函数并调用它伪析构函数为空即不释放动态分配的内存。 复制构造函数 浅复制及其存在的问题在一个类中包含一个指针成员它指向动态分配的内存这些内存是在构造函数中使用new分配的并在析构函数中使用delete[]进行释放。复制这个类的对象时将复制其指针成员但不复制指针指向的缓冲区其结果是两个对象指向一块动态分配的内存。这被称为浅复制会威胁程序的稳定性 #include MyString.h #include iostreamusing namespace std;MyString::MyString(const char *initInput) {cout 调用构造函数 endl;if (initInput ! NULL) {buffer new char[strlen(initInput)1];strcpy(buffer,initInput);} else {buffer NULL;} }MyString::~MyString() {cout 调用析构函数清除 endl;if (buffer ! NULL)delete[] buffer; }int MyString::getLength() {return strlen(buffer); }const char *MyString::getString() {return buffer; }//二进制复刻并不是深复制指向的内存单元导致MyString对象指向同一个内存单元。 void MyString::useMyString(MyString input) { cout 调用浅复刻函数 endl;cout Sting buffer: input.getLength();cout 获取String input.getString()endl;return; } 使用复制构造函数确保深复刻复制构造函数一个特殊的重载构造函数编写类必须提供当对象被复制包括对象按值传递给函数时编译器都将调用复制构造函数复制构造函数接收一个以引用方式传入的当前类的对象作为参数这个参数时源对象的别名使用它来编写自定义的复制代码确保对所有缓冲区进行深复刻。类包含原始指针成员时务必编写复制构造函数和复制复制运算符编写复制函数时务必接收源对象的参数声明为const引用。除非万不得已不要类成员声明为原始指针。 #include MyString.h #include iostreamusing namespace std;//在复刻构造函数声明中使用const可确保复制构造函数不会修改指向的源对象 //另外复制构造函数的参数必须按引用传递否则调用它时复制实参的值导致源对象 //进行浅复制。 void MyString::useMyString(const MyString intput) {cout 调用深复刻函数 endl;cout Sting buffer: intput.buffer;return; } 有助于改善性能的移动构造函数 //为了性能瓶颈还可编写移动构造函数。有移动构造函数时 //C编译器将自动使用它的“移动”临时资源 //从而避免深复制移动构造函数通常时利用移动赋值运算符实现的。 void MyString::useMyString(MyString intput) {return; } 构造函数和析构函数的其他用途 不允许复制的类要禁止对象被复制可声明一个私有的复制构造函数。这确保函数调无法通过编译。为禁止赋值可声明一个私有的赋值运算符。  只能有一个实例的单例类使用私有构造函数、私有复制运算符和静态成员。 将关键字static用于类的数据成员时该数据成员将在所有实例之间共享 将static用于函数声明的局部变量时该变量的值将在两次调用之间保存不变 将static用于成员函数时该方法将在所有成员之间共享。 禁止在栈中实例化的类关键在于将析构函数声明为私有。 this指针 在类中关键字this包含当前对象的地址换句话说其值为object。当在类成员方法中调用其他成员方法时编译器将隐式地传递this指针——函数调用中不可见的参数。调用静态方法时不会隐式传递this指针因静态函数不与类实例相关联而由所有实例共享。如要静态函数中使用实例变量应显示地声明一个形参让调用者将实参设置为this指针。 将sizeof()用于类 通过使用关键字class声明自定义类型可封装数据属性和使用数据的方法。sizeof()可用于类声明中所有数据属性占用的总的内存量。sizeof不考虑成员函数及其定义的局部变量。 友元类及函数 不能从外部访问类的私有数据成员和方法但这条规则不适用于友元类和友元函数。要声明友元类或友元函数可使用关键字friend。 十、实现继承 C入门知识点总结——面向对象/高级编程 十一、多态 C入门知识点总结——面向对象/高级编程 使用虚函数实现多态行为 通过使用Virual可确保编译器调用覆盖版本。 虚函数的工作原理——理解虚函数表编译器将为实现了虚函数的基类和覆盖了虚函数的派生类分别创建一个虚函数表Virtual Function TableVFT。实例化类的对象时将创建一个隐藏的指针我们称之为VFT*它指向相应的VFT。可将VFT视为一个包含函数指针的静态数组其中每个指针都指向相应的虚函数。每个虚函数表都由函数指针组成其中每个指针都指向相应虚函数的实现。抽象基类和纯虚函数不能实例化的基类被称为抽象基类这样的基类只有一个用途那就是从它派生出其他类。在C中要创建抽象基类可声明纯虚函数。虚继承解决二义性在继承层次结构中继承多个从同一类派生而来的基类时如这些基类没有采用虚继承将导致二义性在继承层次结构中使用关键字virtual将基类的实例个数限定为1 对于将派生类覆盖的基类方法务必将其声明为虚函数纯虚函数导致类变成抽象基类且在派生类中必须提供纯虚函数的实现务必考虑使用虚继承 别忘了给基类提供一个虚析构函数别忘了编译器不允许创建抽象基类的实现别忘了在二义性继承层次结构中虚继承旨在确保只有一个基类实现用于创建继承层次结构和声明基类函数时关键字virtual的作用不同。 十二、运算符类型和运算符重载 函数运算符operator operator()让对象像函数被称为函数运算符。函数运算符用于标准模板库STL中,通常时STL算法中。其用途包括决策。根据使用的操作数数量这样的函数对象称为单目谓词或双目谓词。    十三、类型转换运算符 类型转换是一种机制能够暂时或永久性改变编译器对对象的解释。注意这并意味着程序改变了对象本身而是改变了对对象的解释。可改变对象解释方式的运算符称为类型转换运算符。 static_cast用于在相关类型的指针之间进行转换还可显式地执行标准数据类型的类型转换——这种转换原本将自动或隐式地进行。static_cast实现了基本的编译阶段检查确保指针被转换为相关类型。使用static_cast可将指针向上转换为基类类型也可向下转换为派生类型。dynamic_cast与静态类型转换相反动态类型转换在运行阶段即应用程序运行时执行类型转换。可检查dynamic_cast操作的结果以判断类型转换是否成功。reinterpret_cast能够将一种对象类型转换为另一种不管它们是否相关这种类型转换实际上是强制编译器接受static_cast通常不允许的类型转换通常用于低级程序如驱动程序在这种程序中需要将数据转换成API能够接受的简单类型。const_cast能够关闭对象的访问修饰符const。 十四、宏和模板简介 预处理与编译器 预处理器在编译之前运行预编译器指令都以#打头。C程序通常在.h头文件中声明类和函数并在.cpp文件中定义函数因此需要在.cpp文件中使用预处理器编译指令#includeheader来包含头文件。 #define定义常量#ifndef和#endif在预处理器看来两个头文件包含对方会导致递归问题。为避免这种问题可结合使用过宏以及预处理器编译指令#ifndef和#endifassert使用assert宏验证表达式 模板 在C中模板能够定义一种适用于不同类型的对象的行为宏不是类型安全的而模板是类型安全的。模板声明以关键字template打头接下来是类型参数列表。 #include iostream #include stringusing namespace std;template typename T inline T const Max (T const a, T const b) { return a b ? b:a; } int main () {int i 39;int j 20;cout Max(i, j): Max(i, j) endl; double f1 13.5; double f2 20.7; cout Max(f1, f2): Max(f1, f2) endl; string s1 Hello; string s2 World; cout Max(s1, s2): Max(s1, s2) endl; return 0;} 模板函数  模板函数不仅可以重用就像宏函数一样而且更容易编写和维护还是类型安全的。 模板类使用模板类时可指定要为哪种类型具体化类。 template typename T class MyFristTemplateCalss { public:void setValue(const T newValue) {vaule newValue;}const T getValue() const {return vaule;} private:T vaule; }; 使用static_assert执行编译阶段检查static_assert是C新增的一项功能能够在不满足指定条件时禁止编译它是一种编译阶段断言可用于在开发环境或控制台中显示一条自定义消息。 void EverythingButInt(){static_assert(sizeof(T) ! sizeof(int),NO Int please!);}; 在实际C编程中使用模板模板最重要也是最强大的应用是在标准模板库STL中。STL由一系列模板类和函数组成分别包含泛型使用类和算法。这些STL模板类能够实现动态数组、链表以及包含键-值对的容器而sort等算法可用于这些容器从而对容器包含的数据进行处理。  十五、标准模板库简介 STL容器 容器是用于存储数据的STL类STL提供了两种类型的容器顺序容器和关联容器还提供了容器适配器Contsiner Adapter的类是顺序容器和关联容器的变种包含的功能有限用于满足特殊的需求。 顺序容器 顺序容器按顺序存储数据如数组和列表。顺序容器具有插入速度快但查找操作相对较慢的特征。 std::vector操作与动态数组一样在最后插入数据可将vector视为书架可在一端添加和拿走是图书std::deque与std::vector类似但允许在开头插入或删除元素std::list操作与双向链表一样。可将它视为链条对象被连接在一起可在任何位置添加或删除对象std::forward_lis类似于std::list但是单向链表只能一个方向遍历。 关联容器 关联容器按指定的顺序存储数据就像词典一样。这将降低插入数据的速度但在查询方面有很大的优势。 std::set存储各不相同的值在插入时进行排序容器的复杂度为对数std::unordered_set存储各不相同的值在插入时进行排序容器的复杂度为常数。这是容器是C新增的std::map 存储键值对并根据唯一的键排序容器的复杂度为对数std::unordered_map存储键值对并根据唯一的键排序容器的复杂度为对数这是容器是C新增的std::multiset与set类似但允许存储多个值相同的项即值不需要是唯一的std::unordered_multiset与unordered_set类似但允许存储多个值相同的项即值不需要是唯一的这是容器是C新增的std::multimap与map类似但不要求键是唯一的std::unordered_multimap与unordered_map类似但不要求键是唯一的这是容器是C新增的 选择正确的容器 容器适配器 std::stack以LIFO后进先出的方式存储元素 能够在栈顶插入压入和删除弹出元素 std::queue以FIFO先进先出方式存储元素能够在栈顶插入和删除元素 std::priority_queue以特定顺序存储元素因为优先级最高的元素总工室位于队列开头。 STL迭代器 最简单的迭代器是指针。给定一个指向数组的第一元素的指针可递增该指针使其指向下一个元素还可直接对当前位置的元素进行操作。 STL中的迭代器是模板类从某种程度上说它是泛型指针。这些模板类能够对STL容器进行操作注意操作也可以以模板函数的方式提供STL算法迭代器是一座桥梁让这些模板函数能够以一致而无缝的方式处理容器而容器是模板类 输入迭代器通过对输入迭代器解除引用它将引用对象而对象可能位于集合中。最严格的输入迭代器确保只能以只读的方式访问对象输出迭代器输出迭代器能对集合执行写入操作。最严格的输出迭代器确保只能执行写入操作前向迭代器这是输入迭代器和输入迭代器的一种细化它允许输入和输出。前向迭代器可以使const的只能读取它指向的对象也可以改变对象即可读写对象。前向迭代器通常用于单链表双向迭代器这是前向迭代器的一种细化可对执行递减从而向后移动。双向迭代器通常用于双向链表随机访问迭代器这是对双向迭代器的一种细化可将其加减一个偏移量还可将两个跌大气相减以得到集合中两个元素的相对距离。随机访问迭代器通常用于数据。 STL算法 std::find在集合中查找值。std:find_if根据用户指定的谓词在集合中查找值std::reverse反转集合中元素的排列顺序std::remove_if根据用户定义的谓词将元素从几个中删除std::trasnsform使用用户定义的变换函数对容器中的元素进行变换。 STL字符串类 std::string基于插入的std:basic_string具体化用于操纵简单字符串std:wstring基于wchar_t的std:basic_string具体化用于操纵宽字符串。 十六、STL String类 标准模板库STL提供了一个用于字符串操作的容器类。string类不仅能够根据应用程序的需求动态调整大小还提供了很有用的辅助函数可帮助操作字符串能够在应用程序中使用标准的、经过测试的可移植功能并将其主要精力放在开发应用程序的重要功能上。 STL字符串类std::string 和std::wstring 减少了程序员在创建和操作字符串方面需要做的工作在内部管理内存分配细节从而提高了应用程序的稳定性提供了复制构造函数和赋值运算符可确保成员字符串得以正确复制提供了帮助执行复制、截短、删除等操作的实用函数提供了帮助用于比较的运算符让程序员能够将精力放在应用程序的主要需求而不是字符串操作细节上。 实例化和复制STL string; 访问std::sting的字符内容 拼接字符串 在string中查找字符串或子字符串 截短STL string 字符串反转 字符串的大小写转换 基于模板的STL string实现 std::string类实际上是STL模板类std::basic_string T具体化。 十七、STL 动态数组类 std::verctor的特点 在数组末尾添加元素所需的时间是固定的即在末尾插入元素的所需时间不随数组大小而异在末尾删除元素也如此在数组中间添加或删除元素所需的时间与该元素后面的元素个数成正比存储的元素数是动态的而vector类负责管理内存。 实例化vector 使用push_back在末尾插入元素 使用insert()在指定位置插入元素 使用数组语法访问vector中元素 使用指针语法访问vector中的元素 删除vector中的元素 STL deque类 deque是一个STL动态数组类与vector非常类似。但支持在数组开头和末尾插入或删除元素。 支持使用方法push_back()和pop_back()末尾插入和删除元素还允许使用push_front和pop_front在开头插入和删除元素。 十八、STL list 和 forward_list: 标准模板类STL以模板类std::list的方式提供了一个双向链表。双向链表的主要特点是插入和删除元素的速度快且时间是固定。从C11起还可使用单向链表std::forwead_list这种链表只能沿一个方向遍历。 std::list的特点 链表是一系列节点其中每个节点除包含对象或值外还指向下一个节点即每个节点都连接到下一个节点和前一个节点。 基本的list操作 实例化vector::list对象在list开头或末尾插入元素push_front()和push_back()在list中间插入元素删除list中元素对包含对象的list进行排序以及删除其中的元素 对list中元素进行反转和排序 使用list::reverse()反转元素的排列顺序对元素进行排序 std::forward_list: 单向链表std::forwead_list这种链表只能沿一个方向遍历。 十九、STL 集合类 标准模板库提供了一些容器类以便在应用程序中进行频繁而快速的搜索。std::set和std::multiset用于存储一组经过排序的元素其查找元素的复杂度为对数而unordered集合的插入和查找时间是固定的。 STL set和multiset的基本操作 实例化std::set对象在set或multiset中插入元素在set或multiset中查找元素删除set或multiset中的元素 STL散列集合实现std::unordered_set和std::unordered_multiset set和multiset使用了std::lessT或提供的谓词对元素同时也是键进行排序。相对与vector等未经排序的容器在经过排序的容器中查找的速度更快其sort的复杂度为对数。这意味着在set中查找元素时所需的时间不是与元素数成正比而是与元素数的对数成正比。 相比于未经排序的容器查找时间与元素数成正比这极大地改善了性能但有时候这还不够。探索出插入和排序时间固定的方式一种这样的方式是使用基于散列的实现即使用散列函数来计算排序索引。将元素插入散列集合时首先使用散列函数计算出一个唯一的索引在根据该索引决定将元素放在哪个桶bucket中。 二十、STL 映射类 STL映射类简介 map和multimap是键-值对容器支持根据键进行查找。 map和multimap区别在于后者能存储重复的键而前者只能存储唯一的键。 std::map和std::multimap的基本操作 实例化std::map和std::multimap在std::map和std::multimap中插入元素在std::map和std::multimap中查找元素删除std::map和std::multimap中的元素 提供自定义的排序谓词 std::map和std::multimap使用std::less提供的默认排序标准该谓词运算符比较两个对象。 散列表的工作原理 可将散列表视为一个键-值对集合根据给定的键可找到相应的值。散列表与简单映射的区别在于散列表将键值对存储在桶中每个桶都有索引指出了它的散列表中的相对位置类似于数组。这种索引使用散列函数根据键计算的得到的 index HashFunction(key,TableSzie); 使用find(0根据键查找到元素时将使用HashFunction()计算元素的位置并返回该位置的值就像数组返回其存储的元素那样。如HashFunction()不佳将导致多个元素的索引相同进而存储在同一个桶中即桶变成了元素裂表。这种情形被称为collision它降低查找速度是查找时间不再固定。 std::unordered_map和std::unordered_multimap 在不发生冲突的情况下unordered_map的插入和查找时间几乎是固定的不受元素数的影响。然而这并不意味着它优于在各种情形复杂度都为对数的map。在包含的元素不太多的情况下固定时间可能长得多导致unordered_map的速度比马屁慢。 二十一、 理解函数对象 函数对象与谓词的概念 函数对象是用做函数的对象但从实现上说函数对象是实现了operator()的类的对象。虽然函数和函数指针也可归为函数对象但实现了operator()的类对象才能保存状态即类的成员属性的值才能用于标准模板库。 一元函数接受一个参数的函数如f(x)。如一元函数返回一个布尔值则该函数称为谓词二元函数接受两个参数的函数如f(x,y)。如二元函数返回一个布尔值则称该函数为二元谓词。 template typename elementType struct displayElement{void operator() (const elementType element) const {//doSomething} }; 函数对象用途 返回布尔值的一元函数时谓词这种函数可供STL算法用于判断接受连个参数并返回一个布尔值的函数时二元谓词。这种函数用于如std::sort()等STL函数中。 二十二、 C lambda表达式 可将lambda表达式视为包含公有operator()的匿名结构或类。 如何定义lambda表达式 lambda表达式的定义必须以方括号[]打头。这些括号告诉编译器接下来是一个lambda表达式。方括号的后面是一个参数列表该参数列表与不使用lambda表达式时提供给operator()的参数列表相同。 一元函数对应的lambda表达式 [](Type paramname){  ///  lambda表达式} [](Type paramname){  ///  lambda表达式} 一元谓词对应的ambda表达式 [](Type paramname){  //  lambda表达式    return bool} 通过捕获列表接受状态变量的lambda表达式 [Divisor ](int dividend){  return  (dividend % Divisor 0; )} lambda表达式的通用语法 lambda表达式总是以方括号打头并可接收多个状态变量为此可在捕获列表[....]中指定这些状态并用逗号分隔 二元谓词对应的ambda表达式 [](Type paramname2Type paramname2){  ///  lambda表达式} 一元谓词对应的ambda表达式 [](Type paramname2Type paramname2){  //  lambda表达式    return bool} 二十三、 STL算法 查找、搜索、删除和计数是一些通用算法其应用范围很广。STL通过通用的模板函数提供了些算法以及其他的很多算法可通过迭代器对容器进行操作。要使用STL算法必须包含头文件algoithm 非变序算法 不改变容器中元素的顺序和内容的算法称为非变序算法。 变序算法 变序算法改变其操作的序列的元素顺序或内容。 使用STL算法 根据值或条件查找元素计算包含给定值或满足给定条件的元素数在集合中搜索元素或序列将容器中的元素初始为指定值使用std::generate()将元素设置为运行阶段生成的值使用for_each()处理指定范围内的元素使用std::transform()对范围进行变换复制和删除操作替换值以及替换满足给定条件的元素排序、在有序集合中搜索以及删除重复元素将范围分区在有序集合中插入元素 二十四、 自适应容器栈和队列 栈和队列的行为特征 栈和队列与数组或list极其相似但插入、访问和删除元素的方式有一定的限制。可将元素插入到什么位置以及可从什么位置删除元素决定了容器的行为特征。 栈 栈是LIFO后进后出系统只能从栈顶插入或删除元素。 队列 队列是FIFO先进先出系统元素被插入到队尾最先插入的元素最先被删除。 使用STL stack类 实例化stackstack的成员函数push、pop、empty、size、top使用push()和pop()在栈顶插入和删除元素 使用STL queue 实例化queuequeue的成员函数push、pop、empty、size、front、back使用push()在队尾插入以及使用pop()从队首删除 使用STL优先级队列 实例化priority_queue类priority_queue的成员函数push、pop、top、empty、size使用push()在priority_queue末尾插入以及使用pop()在priority_queue开头删除 二十五、使用STL位标志 位是存储设置与标志的高效方法。 bitset类 实例化std::bitset使用std::bitset及其成员可用于在bitset中插入位、设置内容、读取内容还提供了一些运算符用于显示位序列、执行按位逻辑运算等std::bitset的运算符 std::bitset的成员方法 vectorbool: vectorbool 是对std::verctor的部分具体化用于存储布尔数据。这个类可动态地调整长度。 实例化vectorbool vectorbool 的成员函数和运算符 二十六、理解智能指针 二十七、使用流进行输入和输出 二十八、异常处理 二十九、继续前行
http://www.zqtcl.cn/news/293804/

相关文章:

  • 宁波建站模板厂家太原企业网站排名
  • 厦门网站建设定制多少钱wordpress能用一个数据库
  • 找人做网站需要准备什么材料怎么建设自己淘宝网站首页
  • 汽车网站建设费用js怎么做网站
  • 四川万景建设工程有限公司网站做公司网站用什么系统
  • 长沙企业建站系统3d视频制作公司
  • 长沙的网站制作公司网站建设方案的需求分析
  • 电子商务网站发展建设论文网站开发需要经过的几个主要阶段
  • 建设网站外贸做网站必须会php吗
  • 网站建设费用的请示丹徒区建设局网站
  • 上海网站制作机构个人做外贸网站违法吗
  • 咖啡厅网站开发目标汕头最新消息今天
  • 广州做外贸网站的公司简介做行业门户网站注意什么
  • 专业网页网站设计图书成都医院做网站建设
  • 浙江网站建设dyfwzx网站开发的广告词
  • 网站 seo 优化 效果中华室内设计网公众号下载
  • 如何自己建网站企业网站建站快车的优点
  • 目前做网站的公司有哪些管理系统中的计算机应用
  • 百度网站服务器企业网站报价
  • 网站后台账户如何做会计分录电商数据查询平台
  • 素材动图网站90设计app下载
  • 绍兴网站设计公司网站空间位置是什么
  • 高端网站设计品牌珠海网站建设最新报价
  • 做网站的商家怎么赚取流量费房地产怎么做网站推广
  • 企业网站建设基本流程网站积分方案
  • 网站定位与功能分析网站常见故障
  • 深圳电子商务网站制作桂林市防疫最新政策
  • 北京网站建设备案代理网站建设计划建议
  • 湛江公司做网站wordpress如何设置网站地图
  • wordpress攻防优化方案