cprimerxzben个人复习总结.docx

上传人:wux****ua 文档编号:9696742 上传时间:2020-04-07 格式:DOCX 页数:9 大小:44.42KB
返回 下载 相关 举报
cprimerxzben个人复习总结.docx_第1页
第1页 / 共9页
cprimerxzben个人复习总结.docx_第2页
第2页 / 共9页
cprimerxzben个人复习总结.docx_第3页
第3页 / 共9页
点击查看更多>>
资源描述
常量指针 : const int *a; int const *a; 指针的指向的对象值不可以改变,但指向的对象可以改变。指针常量 : int *const a; 指针指向的对象不可以改变,但是指向对象的值可以改变。指向常量的常量指针:const int * const a; int const * const a; 指针指向的对象和对象的值都不可以改变。我的助记理解: 1、常量指针:const int *a; 和 int const *a; const 修饰的 *a 也就是对对象的取值。所以对象的取值是常量,所以为常量指针对象的取值不可以改变。2、指针常量:int *const a; const 修饰的是 指针变量 a,所以就是说指针变量的值不能改变即指针指向的对象不能改变,为指针常量。注意:常量只能由常量指针指向,否则会报错,因为由非常量指针指向破坏了常量的约束。对于引用也是如此,常量只能由常量引用对其引用。另外对于 char *p = “const string”; 这条语句为什么又能通过编译?个人觉得可能是 “const string” 这个字符串常量的机制和我们自己定义的常量的机制有所不同的原因。函数传参重新理解:在函数传递数组形参的时候我们常说的是按值传递和按址传递,以前我也只是知道这么一回事。但是其实这两种传参说白了就是一种用已有的变量初始化刚申明变量的操作。比如按值传递就是定义一个形参变量然后将实参的值复制给他;而按址传递是定义一个指针(或是引用)变量然后将实参变量的地址传递给形参指针变量,这样形参指针变量就可以间接地操作实参变量的内容。理解的关键是如果我问:“我现在修改形参指针的值(注意不是指针指向的地址里的内容值),会否会影响实参变量呢?”。问题的答案是:不会。正如我们开始说的按址传递是定义一个形参指针变量指向实参的地址,所以这个形参指针变量和原实参没有关系,只是形参指针指向了实参的地址。通过引用传递数组:对于数组作为函数参数传递的时候,不管我们如何定义都离不开指针的范围。例如 int func(int *a); int func(int a);int func(int a4); 这三个函数的定义其实都是等价的都是第一种的不同表示,所以我们在给函数传参的时候有时候我们传递给函数的数组和我们预期的不同的时候编译时也不会报错。例如上面的第三种函数申明本意是只能传递一个四个元素的数组,但是实际上我们传递的数组的元素个数根本不受约束。因为在编译过程中根本不会管传递的数组的大小,而只关心是否这一类型的指针。如果我们要实现定义一个只能传递指定大小的数组的时候就要用到引用传递数组的方法这个方法可能一般人都感到很陌生,int func(int (&a)4 ) 这样的申明函数就是引用传递,这里要注意的是小括号不能省,因为 & 的运算优先级比 要低。通过引用传递数组,我们就限定传递数组的大小了。多级指针与多维数组:我们常常会遇到用多级指针指向多维数组的问题,但是往往我们却总是难以正确表达,在这里我们要注意的是多维数组必须要明确的是后面几维的大小,就如我们申明数组的时候int arr4; 这个二维的4必须指定,如果只指定第一维的大小如 int arr3 这种是肯定不行的。所以我们定义指向多维数组的指针时我们要申明的是指向几维数组的指针( int (*lparr)4 )而不是几维的指针数组(int *lparr4)。这里要注意的是 *的优先级没有 的优先级高。所以我们要注意使用小括号。函数默认实参:函数可以设置形参的默认实参,我们在为函数的形参列表设置默认实参时要注意在给一个形参设置了默认实参后,这个形参后面的形参都必须设置默认形参。对于函数的默认形参说明可以再函数申明中说明也可以在函数定义中说明但是只能在其中一个中说明。extern 使用:1、 extern 关键字说明变量或者函数可以在当前文件或者外部文件使用的。2、 extern “C” 修饰的语句以c 标准编译。关于用指针访问二维数组的解析:Int arr34 = 1,2,3,4,5,6,7,8,9,10,11,12; 定义了一个 3x4 的二维数组,如果要我们自己去申请这个二维数组的空间的话应该是,先申请一个三维的指针数组,然后给这个指针数组的每个单元申请一个思维的数组并返回数组的首地址保存。typedef 用法总结:1、 定义一种类型的别名,它比宏定义要好一些Example: 1) typedef char *lpstr1 比 define char* lpstr2 lpstr1 p1, p2; lpstr2 p3, p4; 这里 p1、p2、p3是字符指针但是p4就不是了。 2、 我们在跨平台的时候可以用typedef 自定义一些平台支持的类型。3、 为复杂的声明定义一个新的简单的别名,比如涉及函数指针的方面。Typedef void (*fun)(char, char) 这样就定义了一个类型 fun 它是一个返回类型为void参数列表为两个char型变量的函数指针。异常处理:1、通过 throw 表达式 (throw expression) 通过throw 人为抛出我们发现的异常。2、try 块 (try block),用try 将要进行异常检查和处理的程序括起来。3、catch 跟在try 后面根据try 里抛出的异常跳转到相应的catch里进行处理。注意:如果跟在try 后面的catch中没有try中抛出的异常类型处理子句则自动调用terminate终止程序的执行。例子:try if(发现异常) throw 异常类型catch( 异常类型 e)处理异常。预处理中几个有用的常量:_FILE_ 预处理的文件名_LINE_ 当前行号_TIME_ 文件被编译的时间_DATE_ 文件被编译的日期assert() 宏的用法:原型: void assert(int expression);assert 在 c 的 assert.h 头文件中,它的作用是,如果它的条件返回0,则向stderr打印一条出错信息,并调用abort 终止程序。频繁的调用会极大的影响程序的性能,增加额外的开销。禁用assert宏的方法:在调试结束后,可以通过在包含#include 的语句之前插入 #define NDEBUG 来禁用assert调用。(估计assert.h 文件中对宏 NDEBUG做了预处理)迭代器:一中检查容器内元素并遍历元素的数据类型。所有的标准库容器都定义了相应的迭代器类型。用迭代器我们可以访问任意容器中的数据。迭代器使用方法:1、通过容器的 begin()/(end() 方法获得容器中第一个元素的迭代器/(end()不返回任何元素的迭代器而是一个标志表示容器到结尾了,通常用来判断结束)。2、通过 “*” 来访问迭代器指向元素的值。3、通过自增和自减来将迭代器指向的元素向后和向前移动。4、迭代器相等当且仅当迭代器指向同一个元素的时候。Example:vector vect(10); / 定义?一?个? vector 对?象,它包含?的?int型元a素? for(vector:iterator iter = vect.begin(); iter != vect.end(); +iter)*iter = 10;标准库定义的三种顺序容器:Vector、list、deque (双端队列“double-ended queue”)。标准库定义的三种容器适配器:stack、queue、priority_queue(优先队列)Vector支持快速随机访问 #includeList支持快速插入删除#includeDeque双端队列#include顺序容器支持的构造函数C c; 创建元素类型为T的C容器类型的空容器对象cC c(c2);创建一个c2类型的容器并用c2初始化它C c(b, e); 创建容器c并用迭代器 b e 标示的范围内元素初始化。C c(n, t); 用n个值为t的元素创建容器c 其中t的类型必须是容器类型C的元素类型的值或者是可以转换的。注意:容器的元素必须:1、支持赋值运算2、支持复制Stack后进先出栈#includeQueue先进先出队列#includePriority_queue有优先级管理的队列#include关联容器:(基于pair 类型,即容器的元素是由pair组成)map 、set、multimap、multiset。定义方法:C a; 创建一个键类型为T1,值类型为T2的空C对象C b(a); 创建一个键类型为T1,值类型为T2的a C对象的副本对象C c(b.begin(), b.end(); 创建一个有迭代器初始化的C对象Pair类型:(pair类型的数据成员都是public)pair p1;创建一个空的pair对象元素类型为T1,T2pair p1(v1, v2);创建一个pair对象元素类型为 T1,T2并用v1,v2初始化make_pair(v1, v2); 创建一个pair对象元素类型为v1,v2的类型并用v1,v2初始化返回p1p2 p1.first() p2.first() | p1.first() = p2.first() & p1.second() p2.second()p1=p2 p1.first() = p2.first() & p1.second() =p2.second()p.first();p.second();map类型(键 - 值 类型的容器):一、添加元素:1、 用下标访问: map word_count; word_count“Anna” = 1;执行顺序:1、查找键值为 Anna的元素2、如果没有找到则创建一个键值为Anna的元素并用0初始化3、读取新插入的元素,并将它的值赋值为12、 用insert函数1)m.insert(e) e 为对应类型的 pair对象2)m.insert(beg, end) beg 与 end 代表与m同类型对象的迭代器3)m.insert(iter, e) 插入e,如果e对应的键值不存在则以iter为起点搜索新元素的位置。返回新元素的迭代器Insert的返回值为 pairmap:iterator, bool 代表插入新元素的位置迭代器与插入是否成功的bool值。二、查找元素m.count(keyValue) 返回键值出现的次数m.find(KeyValue) 返回一个迭代器,如果KeyValue键值存在则为元素迭代器,否则为 m.end()三、删除元素m.erase(KeyValue) 删除KeyValue对应的元素,并返回删除的元素个数m.erase(p) 删除迭代器p指向的元素,返回voidm.erase(b, e) 删除迭代器 b e 之间的元素。Set 类型(只有 键 没有值的集合容器, 且这个集合会自动将键值按字典序排序):支持map的大部分操作。multimap 与 multiset 类型:与map 和 set 类型一致,唯一区别为他们支持可以含有相同的键值类相关:在类成员函数函数的形参表后加 const,则在成员函数内部不能对对象的数据成员进行修改。mutable 关键字:用于突破const 的限制,由mutable修饰的变量永远处于可变的状态,即使是在const 函数中。explicit 关键字:只对构造函数起作用,用来抑制隐式转换。隐式转换:在c+中对于只有一个参数的构造函数同时定义了一个隐式转换,该构造函数对应数据类型的数据转换成该类的对象。Example:Class String String(const char *p);.;String s1 = “hello”; / 这里等价的 String s1 = String(“hello”); 将一个字符串转换成了String 对象。但是有时候这种转换时危险的。如:Class String String(int n); / 本意预先分配n个字节给字符串 String( const char* p); / 用 c 风格的字符串p作为初始化值;在这种时候 String s = 10; 这个操作由于第一个构造函数的存在而合法等价于 String s = String(10); 这样将是类的使用变得诡异所以为了避免这种情况我们用 explicit 约束构造函数来抑制构造函数的隐式转换。用友元引入的类名与函数(声明或定义),可以像预先声明的一样使用。Example:Class XFriend class Y;Firend void function();Class ZY *ymem;Void g() return :function(); ;这里在 X 类中用友元引入了 Y 类和 function 函数,那么就可以把 Y类和function函数当成预先定义好的使用,所以在Z类中直接使用了Y类和通过 全局域 :直接调用function。类的static 数据成员: 在类中声明,必须在类定义体外定义和初始化。但是 const static数据成员可以在类定义体内初始化, 也可以在类定义体外定义与初始化。Example:Class AStatic int value1; / ok此语句只是在类体中声明 staticvalue1,Static int value2 = 1; / error 它只能在类体外定义时初始化Static const int value3; /ok 在类体中声明const 型value2 Static const int value4 = 1; /ok定义并初始化 value3;int A:value1 = 1; / 定义并初始化 value1const int A:value3 = 2; / 定义初始化 value2 ,它也可以直接在类体中实现复制构造函数:当定义一个对象时用该对象类型对象初始化时会显示调用复制构造函数。在将类类型作为函数参数时在传参时会调用复制构造函数。在函数返回时也会调用。如果我们自己没有定义编译器会自动为我们定义它,我们称之为合成复制构造函数,它的操作为逐个成员(非static成员)的初始化,将新对象初始化为原对象的副本。如果我们要禁用复制构造函数就是自定义一个private的复制构造函数。类类型转换:我知道当类的构造函数含有非explicit 的以参数构造函数是,存在隐式转换的功能,这里实现的是转换成类类型,如果我们要实现从类类型转换成其它类型呢,那我们就要定义类类型转换操作符。对于这个功能的好处通过如下例子:class SmallIntpublic:SmallInt(int v) value = v; cout构1造函数yendl;operator int() coutint类型转a换?= fa; /将si转换成int 再转换成double If(si) 将si转换成int。我们如果同时定义多个类类型的转换会导致在隐式调用的时候不知道调用哪个而是编译器报错,我们只能显示的调用类型转换,但是我们一般不提倡定义多个类类型转换它常常导致很多的编译错误。另外编译器只会自动进行一个类类型转换:class SmallIntpublic:SmallInt(int v) value = v; cout构1造函数yendl;operator int() coutint类型转a换?endl;return value; / 定义?转a换?成int的?转a换?操作符?private:int value; class Intergralpublic:Intergral(int v) value = v;operator SmallInt() return value%256;private:int value;int main()SmallInt ca(1);Intergral nInt(10000);int a = (SmallInt)nInt;cout a endl;SmallInt cb = ca + 1; / 这a里?会将? ca 转a换?成 int 型得?到?int 再通过y隐t式?转a换?成SmallIntint nb = ca + 1; / 转a换?成int型int nc = 1 + ca; / 转a换?成int型double nd = 1.23232 + ca; / 转a换?成int型 然?后由int再转a换?成double型相加return 0;类的动态绑定:1、在c+中,通过基类的引用(或指针)调用虚函数时,发生动态绑定。引用(或指针)既可以指向基类对象也可以指向派生类对象,这一事实是动态绑定的关键。用引用(或指针)调用的虚函数在运行时确定,被调用的函数是引用(或指针)所指对象的实际类型所定义的。2、在c+中除了构造函数之外,任意非static成员函数都可以是虚函数。3、虚函数与默认实参,与其他函数一样,虚函数也可以有默认实参,如果在基类和派生类都对虚函数指定了默认实参调用函数时默认实参到底是哪个呢?。通常在编译的时候就会确定调用默认实参会要使用的值。如果通过基类的指针或引用调用虚函数则调用的是基类的默认实参,如果通过派生类的指针或者引用调用虚函数则默认实参时派生类中指定的。所以对于同一虚函数在基类和派生类指定不同版本的默认实参时不明智的,通常会导致很多麻烦。继承后的访问限定:继承方式 public protected privatePublic publicprotected不可访问Protected protectedprotected不可访问Private privateprivate不可访问友元关系不能继承。基类的友元对派生类的成员没有特殊访问权。如果基类被授予友元关系,则只有基类具有特殊访问权限,该基类的派生类不能访问授予友元关系的类。模板 (Template)C+中Template 有 两种,一种针对function,一种针对class。1、 template functiontemplateT1 function(T1 a, T2 b)T1 c = a + b;return c;使用的时候会根据传入的参数确定T1 和 T2 的类型。2、 template classtemplateclass CThreepublic:CThree(T t1, T t2, T t3);T Min();T Max();Private:T a, b, c;TemplateT CThree:Min()T minab = a b ? a :b;Return minab c ? minab : c;TemplateT CThree:Max()T maxab = a b ? a : b;Return maxab c ? maxab : c;TemplateCThree:CThree(T t1, T t2, T t3):a(t1), b(t2),c(t3)Return ;Void main()CThree obj1(2, 5, 4);CThree obj2(2.0, 8.5, 9.5);在定义类对象时类后面要指定T的类型。
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 工作总结


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!