### C/C++高质量编程知识点概览 #### 一、文件结构 **1.1 版权和版本声明** - 每个源文件都应该有明确的版权和版本声明,以确保代码的所有权归属清晰,并记录其版本历史。 **1.2 头文件的结构** - 头文件通常包含了函数原型、数据类型定义等公共信息,应该按照一定的结构组织起来,方便其他模块引用。 - 常见的做法是在头文件顶部加入版权声明和版本信息,随后是宏定义防止重复包含,接着是全局变量、类型定义、函数原型等声明。 **1.3 定义文件的结构** - 定义文件是指实现了某些功能的具体源文件,一般包括了具体的函数实现、数据结构定义等。 - 这些文件通常按照功能块划分,如变量声明、函数实现等,以保持代码的整洁性和可读性。 **1.4 头文件的作用** - 头文件的主要作用是提供给其他模块或文件的信息,如函数接口、数据类型定义等。 - 通过合理组织头文件,可以减少代码间的耦合度,提高代码的复用性和维护性。 **1.5 目录结构** - 良好的项目应该有一个清晰的目录结构,便于管理和维护。 - 通常包括源代码目录、头文件目录、测试代码目录等。 #### 二、程序的版式 **2.1 空行** - 在不同的代码段之间使用空行来分隔,增加可读性。 - 例如,在函数定义前后添加空行,或者在不同逻辑段之间插入空行。 **2.2 代码行** - 每一行代码应简洁明了,避免在一个代码行中执行多个操作。 - 长度应适中,避免过长导致阅读困难。 **2.3 代码行内的空格** - 在运算符、逗号、括号等符号前后适当添加空格,提高代码的可读性。 - 例如,在赋值操作符 "=" 的前后都加上空格。 **2.4 对齐** - 通过适当的缩进和对齐,使代码层次分明,逻辑清晰。 - 例如,在 if 语句或多层嵌套时,使用缩进来表示不同的层次。 **2.5 长行拆分** - 当一行代码过长时,可以适当拆分为多行,每行以不超过80字符为宜。 - 使用括号来分隔表达式,提高代码的可读性。 **2.6 修饰符的位置** - 类成员的访问修饰符(如 public、private)应放在成员声明之前,且每个修饰符后用空行隔开不同的访问级别。 **2.7 注释** - 代码应该有适当的注释来解释复杂或不直观的部分。 - 注释应准确、简洁,避免过多的废话。 **2.8 类的版式** - 类的定义应按照一定的格式排列,通常包括类名、基类、成员变量和成员函数等。 - 成员变量和成员函数之间使用空行分隔,以便区分不同的部分。 #### 三、命名规则 **3.1 共性规则** - 变量、函数、类等的命名应遵循一致的规则,如驼峰命名法或下划线命名法。 - 避免使用过于简短的名称,应具有描述性。 **3.2 简单的WINDOWS应用程序命名规则** - 在Windows环境下,可能会有一些特定的命名习惯,如使用大写首字母表示类名,小写加下划线表示变量名等。 **3.3 简单的UNIX应用程序命名规则** - 在UNIX环境下,通常采用小写加下划线的方式命名变量和函数,类名则采用大写字母开头。 #### 四、表达式和基本语句 **4.1 运算符的优先级** - 应熟悉C/C++中的运算符优先级规则,避免因优先级问题导致的错误。 - 如有必要,可以通过括号显式地改变优先级。 **4.2 复合表达式** - 避免在一个表达式中进行复杂的计算,尤其是当它涉及到多个变量或逻辑分支时。 **4.3 IF语句** - IF语句用于条件判断,应尽量保持简单明了,避免过深的嵌套。 - 使用 else if 而不是多个独立的 if 语句,以提高代码的逻辑清晰度。 **4.4 循环语句的效率** - 循环语句是程序中常见的结构,应考虑循环的效率问题。 - 尽量减少循环体内的计算量,将不变的表达式移出循环体外。 **4.5 FOR语句的循环控制变量** - 在FOR循环中,循环控制变量的选择和使用直接影响到循环的效率和可读性。 - 尽量使用局部变量作为循环控制变量,并在循环结束时释放它们。 **4.6 SWITCH语句** - SWITCH语句用于多路分支选择,适用于选项数量较多的情况。 - 注意使用 break 语句来结束每个 case 分支,避免“穿透”现象。 **4.7 GOTO语句** - GOTO语句虽然提供了跳转的能力,但在现代编程实践中不推荐使用。 - 应尽量避免使用GOTO,改用更结构化的控制流语句。 #### 五、常量 **5.1 为什么需要常量** - 常量用于表示固定不变的值,如圆周率π、最大值等。 - 使用常量可以提高代码的可维护性和可读性。 **5.2 CONST与#DEFINE的比较** - CONST关键字用于定义C++中的常量,而 #DEFINE 是预处理器指令。 - CONST定义的常量类型安全,可以被编译器检查;而 #DEFINE 不类型安全,可能导致运行时错误。 **5.3 常量定义规则** - 常量的命名应遵循一定的规则,如使用大写字母表示全局常量。 - 常量应定义在头文件中,方便在整个项目中使用。 **5.4 类中的常量** - 在类中定义常量时,可以使用 static const 关键字。 - 这样的常量只能在类外部定义,但可以在类内部使用。 #### 六、函数设计 **6.1 参数的规则** - 函数的参数应尽量简洁,避免过多的参数导致函数难以理解和维护。 - 使用默认参数值来简化函数调用。 **6.2 返回值的规则** - 函数的返回值应清晰表示函数的执行结果,避免使用非直观的返回值。 - 如果函数可能失败,应通过返回值或异常来指示失败的原因。 **6.3 函数内部实现的规则** - 函数内部应尽量保持简单,避免过度复杂的逻辑。 - 使用局部变量来存储中间结果,提高代码的可读性。 **6.4 其它建议** - 遵循DRY(Don't Repeat Yourself)原则,避免重复代码。 - 函数应该只做一件事情,避免函数承担过多职责。 **6.5 使用断言** - 断言是一种调试工具,用于检查程序运行时的状态是否符合预期。 - 应在关键位置使用断言,但避免在生产环境中使用。 **6.6 引用与指针的比较** - 引用和指针都可以用来访问对象,但引用更加安全和易于使用。 - 指针需要额外的操作来访问对象,容易引发空指针异常。 #### 七、内存管理 **7.1 内存分配方式** - C/C++中有多种内存分配方式,如静态分配、栈分配和堆分配。 - 不同的分配方式适用于不同的场景。 **7.2 常见的内存错误及其对策** - 常见的内存错误包括野指针、内存泄漏、越界访问等。 - 通过代码审查、单元测试等手段检测并修复这些问题。 **7.3 指针与数组的对比** - 指针和数组在C/C++中有着紧密的联系,但也存在区别。 - 数组的大小是固定的,而指针可以指向不同大小的对象。 **7.4 指针参数是如何传递内存的** - 当一个函数接受指针作为参数时,实际上是传递了指针所指向内存地址的副本。 - 修改该指针的值不会影响原始指针,但通过指针修改内存中的值是可见的。 **7.5 FREE和DELETE把指针怎么啦** - FREE和DELETE都是用于释放内存的操作。 - FREE释放的是通过MALLOC分配的内存,而DELETE释放的是通过NEW分配的内存。 **7.6 动态内存会被自动释放吗** - C/C++中动态分配的内存不会自动释放,需要手动释放。 - 忘记释放内存会导致内存泄漏。 **7.7 杜绝“野指针”** - “野指针”指的是指向已释放内存的指针。 - 一旦指针指向的内存被释放,应立即将指针设为NULL。 **7.8 有了MALLOC/FREE为什么还要NEW/DELETE** - MALLOC/FREE用于基础内存分配,而NEW/DELETE还支持构造和析构操作。 - NEW/DELETE更适合C++对象的管理。 **7.9 内存耗尽怎么办** - 当内存耗尽时,程序可能会崩溃。 - 可以采取措施优化内存使用,或者增加系统资源。 **7.10 MALLOC/FREE的使用要点** - MALLOC/FREE适用于C风格的内存管理。 - 使用时应注意内存的正确释放,避免内存泄漏。 **7.11 NEW/DELETE的使用要点** - NEW/DELETE是C++中的内存管理操作。 - 在类的设计中,应考虑内存管理策略,如使用智能指针等。 **7.12 一些心得体会** - 内存管理是C/C++编程的重要方面,需要深入理解。 - 实践经验和技巧对于解决内存相关问题是宝贵的。 #### 八、C++函数的高级特性 **8.1 函数重载的概念** - 函数重载允许在同一个作用域内定义多个同名函数,只要它们的参数列表不同即可。 - 重载可以提高代码的复用性和可读性。 **8.2 成员函数的重载、覆盖与隐藏** - 成员函数可以重载、覆盖或隐藏基类的成员函数。 - 重载发生在同一个类中,而覆盖发生在派生类中,隐藏则是指派生类的成员函数完全遮蔽了基类的成员函数。 **8.3 参数的缺省值** - 参数可以设置缺省值,这样在调用函数时可以省略这些参数。 - 缺省值可以提高函数的灵活性和可读性。 **8.4 运算符重载** - C++允许用户自定义运算符的行为,以支持自定义类型的运算。 - 运算符重载应谨慎使用,以避免引起混淆。 **8.5 函数内联** - 内联函数在编译时会被展开,以减少函数调用的开销。 - 但是,过度使用内联函数可能导致代码膨胀。 **8.6 一些心得体会** - C++函数的高级特性为编写高效、灵活的代码提供了强大的支持。 - 理解这些特性并合理使用是非常重要的。 #### 九、类的构造函数、析构函数与赋值函数 **9.1 构造函数与析构函数的起源** - 构造函数和析构函数是C++中用于初始化和清理对象的重要机制。 - 它们的存在使得C++能够更好地管理对象的生命周期。 **9.2 构造函数的初始化表** - 初始化表是构造函数的一种特殊语法,用于初始化成员变量。 - 使用初始化表可以更有效地初始化成员变量。 **9.3 构造和析构的次序** - 构造函数和析构函数的调用顺序遵循对象的构造顺序。 - 理解这个顺序对于避免内存管理错误非常重要。 **9.4 示例:类STRING的构造函数与析构函数** - STRING类通常需要实现自己的构造函数和析构函数。 - 构造函数负责初始化字符串,析构函数负责释放字符串占用的内存。 **9.5 不要轻视拷贝构造函数与赋值函数** - 拷贝构造函数和赋值函数用于复制对象。 - 忽视这些函数可能会导致对象状态的混乱或内存泄漏。 **9.6 示例:类STRING的拷贝构造函数与赋值函数** - STRING类中的拷贝构造函数和赋值函数需要仔细设计。 - 它们应确保深拷贝,即创建新的内存空间来存放拷贝的数据。 **9.7 偷懒的办法处理拷贝构造函数与赋值函数** - 有时可以使用编译器自动生成的默认拷贝构造函数和赋值函数。 - 但在处理资源管理时,通常需要自己实现。 **9.8 如何在派生类中实现类的基本函数** - 派生类可以从基类继承构造函数和析构函数。 - 在必要时,可以重写或覆盖这些函数。 **9.9 一些心得体会** - 构造函数、析构函数和赋值函数是类设计的关键部分。 - 合理地实现这些函数可以显著提高代码的质量和可靠性。 #### 十、类的继承与组合 **10.1 继承** - 继承是面向对象编程的一个核心概念,用于创建具有继承关系的类。 - 通过继承,子类可以重用和扩展父类的功能。 **10.2 组合** - 组合是另一种面向对象的设计方法,通过将对象组合在一起实现复杂功能。 - 与继承相比,组合更灵活,但实现起来可能稍微复杂一些。 #### 十一、其它编程经验 **11.1 使用CONST提高函数的健壮性** - CONST关键字可以帮助开发者定义不可修改的变量和参数。 - 使用CONST可以避免意外修改,提高代码的安全性。 **11.2 提高程序的效率** - 优化算法和数据结构是提高程序效率的关键。 - 适当使用缓存、提前计算等技术也可以提升性能。 **11.3 一些有益的建议** - 遵循良好的编码规范,如一致的命名约定、适当的注释等。 - 定期进行代码审查,以发现潜在的问题。 以上是对《C C++高质量编程》中关于良好编程风格的一些关键知识点的概述。通过遵循这些原则和最佳实践,开发人员可以编写出高质量、易于维护的C/C++代码。
剩余100页未读,继续阅读
- 粉丝: 3188
- 资源: 13
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助