结构体
1.用结构体来明确数据关系,结构体可以把相关联的一组数据项聚集在一起。有时了解一个程序最为困难的部分就在于清理哪些数据之间互相有联系。
2.用结构体简化对数据块的操作,可以把相关的元素组织到结构体里,然后对该结构体执行操作。
3.用结构体来简化参数列表,与单独传递一个需要的元素相比,可以把相关的元素组织到一个结构体里,然后把它作为一个整体传递进去。
4.用结构体来减少维护,由于使用结构体的时候是把相关的数据组织在一起的,因此对结构体的修改只会导致程序做很小的改动。
指针
如何解释内存中某个位置的内容,是由指针的基类型决定的。即内存并不包含任何与之相关联的内在的解释。只有通过使用一个特定类型的指针,一个特殊位置的比特才能解释为有意义的数据。
使用指针的一般技巧
通常指针错误都产生于指针指向了它不应该指向的位置。当通过一个坏了的指针变量赋值时,会把数据写入本不应该写值的内存区域。
避免出错的一些建议:
1、把指针操作都限制在子程序或类里面,这样可以将可以减少访问指针代码位置的数量。
2、同时声明和定义指针
3、在与指针分配相同的作用域中删除指针,要保持指针分配和释放操作的对称性。
4、在使用指针之前检查指针,在使用指针之前应该首先检查它的合理性
5、先检查指针所引用的变量在使用它
6、用特定的字段来检测损毁的内存,可以在删除某一变量之前检查一下标记字段。损毁的标记会提示这一变量在生命期里其内容已经被损坏。
7、增加明显的冗余,另一种标记字段法就是将某些特定的字段重复两次。
8、用额外的指针变量来提高代码清晰度,一定不要节约使用指针,利用多个良好命名的指针可以提高可读性和减少出错率。
9、简化复杂的指针表达式,尽量减少很长的指针p->p->->p.data这种使用方式
10、按照正确的顺序删除链表中的指针,在释放当前指针前,要确保已经有指向链表中下一个元素的指针。
11、分配一片保留的内存后备区域,如果在程序中使用了动态内存,就需要避免发生程序忽然用尽了内存、把数据丢在RAM外面的情况发生。
12、粉碎垃圾数据,指针错误很难调试,因为无法确定指针所指向的内存何时变为非法,因此在释放内存区域之前用垃圾数据来覆盖这些内存区域,这样可以让与使用已释放的指针有关的错误的表现方式更一致。
13、在删除或者释放指针之后把他们设置为全空,一种常见的指针错误就是“悬空指针”,即使用了一个已经被delete或者free的指针。因此最好在释放之后将指针指向null。
14、在删除变量之前检查非法指针,再删除指针的时候应该检查一下这个指针的正确性,防止产生了多次删除的操作而产生错误
15、跟踪指针分配情况,维护一份已经分配的指针列表。这样能在释放一个指针之前检查它是不是位于列表内。
16、编写覆盖子程序,集中实现避免指针问题的策略
C++指针:
1、理解指针和引用之间的区别:引用必须总是引用一个对象,而指针则可以指向空值,此外,引用所指向的对象在该引用初始化之后不能改变。
2、把指针用于按“引用传递”参数,把const引用用于“按值传递”参数
3、使用auto_ptr,通过在离开作用域的时候自动释放内存,auto_ptr能避免很多与常规指针相关的内存泄露。
C指针:
1、使用显示指针类型而不是默认类型,C允许你对任何类型的变量使用char或void指针。C语言指针只关心这类指针有所指向,不会真正去关心它所指向的是什么。
2、避免强制类型转换,它与避免把一种类型的变量挤压入另一种类型变量的空间有关。一个需要有很多强制类型转换的程序在架构方面可能就存在一些需要修正的问题。如果可能,就请重新做设计;否则,就应该尽可能地避免强制类型转换。
3、遵循参数传递的型号规则
4、在内存分配中使用sizeof()确定变量的大小,由于sizeof()是在编译器件计算的,因此不会带来性能上的损失。它是可以移植的。
全局数据
全局变量的问题:
1、无意间修改了全局数据
2、与全局数据有关的奇异的和令人激动的别名:当一个全局变量被传递给一个子程序,然后该子程序将它既作全局变量又用作参数使用的情况下,就会出现这种现象。
3、与全局数据有关的代码重入问题:多线程代码造成了全局变量不但在多个子程序见共享,而且也将在同一个程序的不同拷贝之间共享。
4、全局数据阻碍代码重用:在重用代码时还得必须把全局数据引入,如果全局变量过多的话任务量可能很大。
5、与全局数据有关的非确定的初始化顺序事宜
6、全局数据破坏了模块化和智力上的可管理性:如果代码量很大的程序中引入了全局变量,这样不能在同一时间关注一个程序。
使用全局数据的理由:
1、保存全局数值
2、模拟具名常量
3、模拟枚举类型
4、简化对及其常用的数据的使用:在大量的引用一个变量的时候,这个时候使用全局数据。
5、消除流浪数据:在不同子程序之间反复传递的数据
只有万不得已时才使用全局变量
可以用访问子程序的方式来取代全局数据
用全局数据能做的任何事,都可以用访问子程序做得更好。使用访问子程序是实现数据类型和信息隐藏的一种核心方法。
访问器子程序的优势:
1.获得了对数据的集中控制
2.可以确保对变量的所有引用都得到了保护
3.可以自动获得信息隐藏的普遍益处
4.访问子程序可以很容易地转变为抽象数据类型
如何使用访问器子程序
用static关键字或者他的等价来声明该数据,以确保只存在该数据的单一实例。写出可以查看并且修改该数据的子程序来。要求类外部的代码使用该访问器子程序来访问该数据,而不是直接操作它。
1.要求所有的代码通过访问子程序来存取数据
2.不要把你所有的全局数据都扔在一起,如果把所有的全局变量堆到一起,然后为他们编写子程序,这样可以消除与全局数据的有关问题,但这也使代码丧失了信息隐藏和抽象数据类型所带来的好处。既然已经在编写访问器子程序,就请多花一些时间考虑哪些全局数据属于一个类,然后把归属同一个类的数据合并写成一个类,并且写出相应的子函数。
3.在访问子程序里构建一个抽象层,要在问题域这一层次上构建访问器子程序,而不是再细节实现层次上。这种方法会带来更好的可读性,同时防止在编写代码过程中不小心修改到实现细节。
4.使对一项数据所有访问都繁盛在同一个抽象层上
如何减低使用全局数据的风险
1创建一种命名规则来突出全局变量
2为全部的全局变量创建一份注释良好的清单
3不要用全局变量来存放中间结果
4不要把所有的数据都放在一个大对象中并到处传递,以说明没有使用全局的变量