1 / 8
文档名称:

高质量C++编程学习笔记.docx

格式:docx   大小:27KB   页数:8页
下载后只包含 1 个 DOCX 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

高质量C++编程学习笔记.docx

上传人:小屁孩 2024/4/3 文件大小:27 KB

下载得到文件列表

高质量C++编程学习笔记.docx

文档介绍

文档介绍:该【高质量C++编程学习笔记 】是由【小屁孩】上传分享,文档一共【8】页,该文档可以免费在线阅读,需要了解更多关于【高质量C++编程学习笔记 】的内容,可以使用淘豆网的站内搜索功能,选择自己适合的文档,以下文字是截取该文章内的部分文字,如需要获得完整电子版,请下载此文档到您的设备,方便您编辑和打印。编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:普通程序员应该做到:(1)知错就改; (2)经常温故而知新; (3)坚持学****天天向上。C++/C程序通常分为两个文件:(.h)Implementation保存程序的实现(.c)头文件的作用:通过头文件来调用库功能;加强类型安全检查。头文件一般保存于include目录,定义文件按保存于source目录。版式:一行代码值做一件事情。尽可能在定义变量的同时初始化该变量。代码行最大长度宜控制在70至80字符以内。类的版式:以行为为中心,重点关注是类应该提供什么样的接口(服务),public类型的函数写在前面,private类型的数据写在后面。命名规则:匈牙利法:在变量和函数名中加入前缀以增进人们对程序的理解。(ppch:指向字符指针的指针) Windows应用程序的标示符通常采用大小写混排的方式,如AddChild Unix应用程序的标示符通常采用小写加下划线的方式,(别用隐含错误的方式写代码)不可将布尔变量直接与TRUE,FALSE或者1,0进行比较,不同编译器的bool值是不同的不可将浮点变量用“==”或“!=”与任何数字比较,因为有精度限制。应当将指针变量用“==”或“!=”与NULL比较。循环语句的效率(降低循环的复杂性) 多重循环中,如有可能,应当将最长的循环放在最内层。 如果循环体内存在逻辑判断,并且循环次数很大,最好将逻辑判断移到循环体外面。Switch语句存在的理由:多分支选择语句,虽然可以用嵌套if语句来实现多分支选择,但那样程序冗长难读。 Switch语句中每个case语句不要忘了加break。 不要忘记default分支,即使不需要,也要保留default:break;常量:值在运行期间恒定不变。C语言中用#define来定义常量(称为宏常量),c++中除了#define外,还可以用const来定义常量(const常量)。Const与#define比较:const优点:,宏常量没有数据类型。 ,但不能对宏常量调试●在c++中只使用const常量而不使用宏常量。编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:需要对外公开的常量放在头文件中,不需要对外公开的常量放在定义文件的头部。为便于管理,可以把同模块的常量集中存放在一个公共的头文件中。类中的常量:只能用枚举常量来实现!Const数据成员只在某个对象生存期内是常量,而对整个类而言却是可变的,因为类可以创建多个对象,不同的对象其const数据成员的值可以不同。不能在类声明中初始化const数据成员,因为类的对象未被创建时,编译器不知道值是什么。Const数据成员的初始化,只能在类构造函数的初始化表中实现。函数设计函数接口的两个要素是参数和返回值:C语言中,函数的参数和返回值的传递方式有两种;值传递和指针传递,c++多了引用传递。引用传递:性质像指针传递,而使用方式却像值传递。参数的规则:参数的书写要完整,如果函数没有参数,用void填充。参数命名要恰当,顺序要合理。(目的参数放在前面,源参数放在后面)。如果参数是指针,且仅作输入用,应在类型前加const,以防止该指针在函数体外被修改。如果输入参数以值传递的方式传递对象,宜改用“const&”,省去零时对象的构造和析构过程,提高效率。参数个数尽量控制在5个以内。尽量不要使用类型和数目不确定的参数。返回值的规则:不要省略返回值的类型。函数名字和返回者类型在语义上不可冲突。(getchar其实int类型,而不是char类型)不要将正常值和错误标志混在一起返回,正常值用输出参数获得,错误标志用return语句返回。有时候函数原本不需要返回值,但为了增加灵活性,可以附加返回值。函数内部实现的规则:(在函数体的入口处和出口处把关) 在函数体的入口处,对参数的有效性进行检查,从分理解并正确使用“断言”(assert)在函数体的出口处,对return语句的正确性和效率进行检查。return语句不可返回指向“栈内存”的指针或者引用,因为该内存在函数体结束时被自动销毁。搞清楚返回的究竟是值,指针还是引用。如果函数返回值是一个对象,要考虑return语句的效率。函数体功能要单一,不要设计多用途的函数;函数体的规模要小,尽量控制在50行代码以内;尽量避免函数带有“记忆”功能。Debug版本release版本的区别:debug版本用于内部调试,release版本发型给用户使用。 断言assert是仅在debug版本起作用的宏,用于检查“不应该”发生的情况。使用断言捕捉不应该发生的非法情况;在函数的入口处,使用断言检查参数的有效性。引用与指针的比较编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:引用是c++中的概念。引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。不能有NULL引用,引用必须与合法的存储单元关联(指针则可以使NULL)。一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。引用的主要功能是传递函数的参数和返回值。★内存管理内存是片雷区,需要细心阅读,做到真正通晓内存!发生内存错误是非常麻烦的事情,编译器不能自动发现这些错误,通常在程序运行时才能捕捉到。大多没有明显的症状,时隐时现。内存分配方式(三种)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。如全局变量,static变量。在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但内存容量有限。从堆上分配,即所谓的动态内存分配。程序在运行时用malloc或new申请任意多少的内存,程序员自己动手用free或delete释放内存。动态内存的生存期由我们决定,使用灵活,但问题也最多。常见的内存错误及其对策:内存分配未成功,却使用了它。新手犯的。解决办法:在使用内存钱检查指针是否为NULL,如果指针P是函数的参数,那在函数入口处用assert(p!=null)进行检查。如果是用malloc或new来申请内存,用if(p==NULL)或if(p!=NULL)来进行防错处理。内存分配虽然成功,但没有初始化就引用它。(没有初始化的概念,或者误以为内存缺省值为0)解决办法:无论用何种方式创建数组,都别忘了赋初值,即便是赋0值也不可省略。内存分配成功且已经初始化,但操作越界例如在使用数组时常发生下标“多1”或“少1”,尤其是for循环中,要慎重。忘记了释放内存,造成内存泄漏。含有这种错误的函数每被调用一次就丢失一块内存。系统会显示“内存耗尽”解决办法:动态内存的申请与释放必须配对,程序中malloc与free的使用次数一定要相同,否则肯定有错误(new/delete)。释放了内存却继续使用它。ⅰ程序中的对象调用关系过于复杂。这是数据结构设计问题,要重新设计一下。ⅱreturn语句写错了,注意不要返回指向“栈内存”的指针和引用,那个东西在函数体结束时被自动销毁的!ⅲ使用free或delete释放了内存后,没有将指针设置为NULL,导致“野指针”……规则:,。,特别要当心“多1”或者“少1”,防止内存泄漏(malloc/free)(new/delete)编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:,立即将指针设置为NULL,防止产生“野指针”指针和数组的对比:数组要么在静态存储区被创建(全局数组),要么在栈上被创建。数组名对应着一块内存(而不是指向),其地址与容量在生命期内保持不变,只有数组的内容可以改变。指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。若想把数组a的内容复制给数组b,不能用b=a,用标准库函数strcpy进行复制;比较b和a的内容是否相同,不能用b==a来判断,用标准库函数strcmp进行比较。P=a并不能把a的内容复制给指针p,而是把a的地址赋给了p。得先用malloc为p申请一块容量为strlen(a)+1个字符的内存,在用strcpy进行字符串复制。用运算符sizeof可以计算出数组的容量,字节数。但sizeof指针,只能告诉你指针类型的大小,而不是它所致的内存的容量。C++/c没有办法知道指针所致的内存容量的。Win32位系统,所有的指针都是4位的。Char是1位,int,float是4位,double是8位。注意:当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。Free和delete只是把指针所指的内存给释放掉,但并没有把指针本身干掉。指针被free以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,成了所谓的“野指针”,如果这时候不把该指针设置为NULL,会让人误以为它是个合法的指针。对于野指针,if(p!=NULL)起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。“野指针”不是NULL指针,是指向“垃圾”内存的指针。If语句对它不起作用。生成野指针的原因:。如果被创建时没有初始化指针,它会乱指一气。因此在指针变量创建时要初始化,要么设置为NULL,要么让它指向合法的内存。,没有置为NULL,让人误以为它是个合法的指针。。Malloc/free和new/delete的区别。(c程序只能用malloc/free管理动态内存)Malloc与free是c++/c语言的标准库函数,new/delete是c++的运算符。他们都可以用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求。因为对象在创建的同时要自动执行构造函数,消亡之前要自动执行析构函数。而malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能把执行构造函数和析构函数的任务强加于malloc/++需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。所以,不要企图用malloc/free来完成动态对象的内存管理,应该用new/“多项”没有构造和析构的过程,对它们而言malloc/free和new/dekete式等价的。处理内存耗尽问题。如果申请动态内存时找不到足够大的内存块,malloc和new将返回NULL指针,宣告内存申请失败。处理方法:,如果是则马上用return语句终止本函数。 ,如果是则马上用exit(1)终止整个程序的运行。编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码: 。Malloc/free的使用要点Malloc原型:void*malloc(size_tsize);例:int*p=(int*)malloc(sizeof(int)*length);在malloc中使用sizeof是良好的编程风格。Free原型:voidfree(void*memblock);●如果不是NULL指针,那么free对p的连续操作两次就会导致程序运行错误;如果p是NULL指针,那么无论操作多少次都不回出问题。Mew/delete的使用要点New:int*p2=newint[length];因为new内置了sizeof、类型转换和类型检查功能。对非内部数据类型的对对象,new同时完成了初始化工作。Delete:用delete释放对象数组的时候,不要随意掉了符号‘[]’,例如delete[]objects;对指针需要做的:越是怕指针,也是要使用指针。不会正确使用指针,肯定算不上合格的程序员。必须养成“使用调试器逐步跟踪程序”的****惯,只有这样才能发现问题的本质。C++函数的高级特性对比与C语言的函数,C++增加了重载(overloaded),内联(inline),const和virtual四种新机制。重载和内联机制既可以用于全局函数也可用以类的成员函数。Const与virtual机制仅用于类的成员函数。C++程序要调用已经被编译后的C函数,通过extern“C”解决:#ifdef__cplusplusextern“C”{#endif//加c函数#ifdef__cplusplus}#endif重载:在C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,即函数重载。优点(理由):便于记忆,提高函数的易用性;类的构造函数需要重载机制。因为C++规定构造函数与类同名,构造函数只能有一个名字。通过参数的不同来区分重载函数。由于数字本身没有类型,将数字当作参数时将自动进行类型转换,成为隐式类型转换。成员函数的重载、覆盖与隐藏:容易混淆!成员函数被重载的特征:(在同一类中);;;。覆盖时指派生类函数覆盖基类函数,特征:(分别位于派生类和基类);;;:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:irtual关键字。运算符重载在C++中,可以用operator加上运算符来表示函数,叫做运算符重载。函数内联:C++语言支持函数内联,其目的是为了提高函数的执行效率。C++语言的函数内联机制既具备宏代码的效率,又增加了安全性,而且可以自由操作类的数据成员。所以在C++程序中,应该用内联函数取代所有宏代码,“assert”是唯一的例外。关键字inline必须与函数定义体放在一起才能使函数成为内联,仅将inline放在函数声明前面不起任何作用。类的构造函数、析构函数与赋值函数构造函数、析构函数与赋值函数是每个类最基本的函数。每个类只有一个析构函数和赋值函数,但可以有多个构造函数(包含一个拷贝构造函数,其他的普通构造函数)。C++语言里,把对象的初始化工作放在构造函数中,把清除工作放在析构函数中。在对象被创建时,构造函数被自动执行;当对象消亡时,析构函数被自动执行。构造函数与析构函数的另一个特别之处是没有返回值类型。类的const常量只能在初始化表里被初始化,因为它不能在函数体内用赋值的方式来初始化。拷贝构造函数和赋值函数非常容易混淆,常导致错写、错用。拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用。基类的构造函数、析构函数、赋值函数都不能被派生类继承。派生类的构造函数应在其初始化表里调用基类的构造函数;基类和派生类的析构函数应该为虚(加virtual关键字);在编写派生类的赋值函数时,注意不要忘记对基类的数据成员重新赋值;使用const提高程序健壮性Const不仅能定义常量,它还可以修饰函数的参数、返回值,甚至函数的定义体。:如果参数做输出用,不论它是什么数据类型,都不能加const修饰。Const只能修饰输入参数:如果输入参数采用“指针传递”,那么加const修饰可以防止意外的改动该指针,起到保护作用。如果输入参数采用“值传递”,由于函数将自动产生临时变量用于复制该参数,所以不要加const。对于非内部数据类型的参数而言,为了提高效率,可以将voidfunc(Aa)用voidfunc(constA&a)代替。将之改成const的引用传递,使得a这个引用传递不能改变。对于内部数据类型的输入参数,不要改。用const修饰函数的返回值如果给以“指针传递”方式的函数返回值加const修饰,那么函数返回值的内容不能被修改,该返回值只能被付给加const修饰的同类型指针。如果函数返回值采用“值传递方式”,由于函数会把返回值赋值到外币临时的存储单元中,加const没有任何价值,因此不需要用const修饰。编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在累的赋值函数中,为了实现链式表达。Const成员函数:任何不会修改数据成员的函数都应该声明为const类型。Const成员函数的声明有点奇怪:const关键字只能放在函数声明的尾部!intGetCount(void)const;提高程序的效率程序的时间效率是指运行速度,空间效率是指程序占用内存或者外存的状况。先优化数据结构和算法,再优化执行代码。如果原有的代码质量比较好,尽量复用它。不要修补很差劲的代码,应当重新编写。在32位程序里,所有类型的指针的值都是一个32位的整数,因为32位程序里内存地址全都是32位长。Sizeof:char是1,int是4,float是4,double是8,每遇到一个指针,看一下这个指针的类型,指针指的类型,该指针指向了哪里。 类的继承与组合对象是类的一个实例。继承的规则:若在逻辑上B是A的“一种”,且A的所有功能和属性对B而言都有一一,则允许B继承A的功能和属性。编号:时间:2021年x月x日书山有路勤为径,学海无涯苦作舟页码:精品文档欢迎下载