第十三章--不常见的数据类型
13.1--结构体
使用结构体的理由:
(1)用结构体来明确数据关系。结构体把相关联的数据聚集在一起。
(2)用结构体简化对数据块的操作。如将一个结构体作为参数,而不是一堆的参数。
(3)用结构体来简化参数列表。
(4)用结构体来减少维护。因为结构体将相关数据组织在一起,所以改变结构体只需要对程序做很少的修改。
13.2--指针
1.用来理解指针的范例
每一个指针都包含两个部分:内存中的某处位置,以及如何解释该位置中的内容。
2.使用指针的一般的技巧
通常,指针错误都产生于指针指向了它不应该指向的位置。因此,更正指针错误的大部分工作便是找出它的位置。
下面是使用指针的一些技巧:
(1)把指针操作限制在子程序或者类里。
(2)同时声明和定义指针。
(3)在与指针分配相同的作用域中删除指针。如在构造函数中分配了一个指针,应该在析构函数中释放。
(4)在使用指针之前检查指针。
(5)先检查指针所引用的变量再使用它。
(6)用狗牌字段来检测损毁的内存。意思是在你的结构体内加入一个专门用来检测错误的字段。如果这个字段的值被改变了,说明出现了错误。
(7)增加明显的冗余。替代标记字段的一个方案,就是某些特定的字段重复两次。如果位于冗余字段中的数据不匹配就可以确定数据已经被破坏了。
(8)用额外的指针变量来提高代码清晰度。
(9)简化复杂的指针表达式,如两层以上的指针a->b->c。
(10)画图,使指针使用流程清晰。
(11)按照正确的顺序删除链表中的指针。
(12)分配一片保留的内存后备区域。避免发生程序忽然用尽了内存,而把数据丢在RAM。一旦用光了内存,就可以释放预留的后备区域。
(13)粉碎垃圾数据。在释放内存区域之前用垃圾数据来覆盖这些内存区域。
(14)在删除或释放指针之后把它们设为空值。
(15)在删除变量之前检查非法指针。
(16)编写覆盖子程序,集中实现避免指针问题的策略。
(17)采用非指针的技术。
3.C++指针
(1)理解指针和引用之间的区别:最重要的区别是,引用必须总是引用一个对象,而指针则可以指向空值,还有引用所指向的对象在该引用初始化之后不能改变。
(2)把指针用于“按引用传递”参数,把const引用用于“按值传递”参数。
(3)使用auto_ptr,以避免内存泄露,因为在离开作用域的时候自动释放内存。
(4)灵活运用智能指针。
4.C指针
(1)使用显式指针类型而不是默认类型。
(2)避免强制类型转换。
(3)遵循参数传递的星号规则:只有当你在赋值语句的参数前面加了星号(*),才能把该参数从子程序中传回去。
(4)在内存分配中使用sizeof()确定变量的大小。
13.3--全局数据
1.与全局数据有关的常见问题:
(1)无意间修改了全局数据。
(2)与全局数据有关的奇异的和令人激动的别名问题。当一个全局变量被传递给一个子程序,然后该子程序将它即用作全局变量又用作参数使用的情况下,就会出现这种情况。
(3)与全局数据有关的代码重入问题。
(4)全局数据阻碍代码重用。
(5)与全局数据有关的非确定的初始化事宜。有些语言,特别是C++,没有定义不同“转义单元”(文件)里的数据初始化的顺序。所以要注意不要用一个全局变量来初始化另一个全局变量。
(6)全局数据破坏了模块化和智力上的管理性。
2.使用全局变量的理由
一般要尽量避免使用全局变量,但是如果遵循一定的规则,使用全局变量也很有用的。
(1)保存全局数据。
(2)模拟具名常量。
(3)模拟枚举类型。
(4)简化对极其常用的数据的使用。如某一个变量几乎出现在每一个子程序中。
(5)消除流浪数据。
3.只有万不得已时才使用全局数据
(1)首先把每一个变量设置为局部的,仅当需要时才把变量设置为全局的。
(2)区别全局变量和类变量。
4.用子访问器程序来取代全局数据
a.访问器子程序的优势:
(1)获得了对程序的集中控制。
(2)确保对变量的所有引用都得到了保护。
(3)可以自动获得信息隐藏的普遍益处。
(4)可以很容易地转变为抽象数据类型。
b.如何使用访问器子程序:
(1)要求所有的代码通过访问器子程序来存取数据。
(2)不要把你所有的全局数据都扔在一处。
(3)用锁来控制对全局变量的访问,对于多线程来说。
(4)在你的访问器子程序里构造一个抽象层。
(5)使得对一项数据的所有访问都发生在同一个抽象层上。
5.如何降低使用全局数据的风险
(1)创建一种命名规则来突出全局变量。
(2)为全部的全局变量创建一份注释良好的清单。
(3)不要用全局变量来存放中间结果。
(4)不要把所有的数值都放在一个大对象中并到处传递。