现在的位置: 首页 > 综合 > 正文

读《0 bug C/C++商用工程之道》——记录1

2013年11月10日 ⁄ 综合 ⁄ 共 2027字 ⁄ 字号 评论关闭

一、程序真谛

1.程序就是“搬数”

       动作:读取——技术——写出(输入——处理——输出)

       数据结构决定数据如何组织,搬动起来效率较高

       算法语言决定了如何搬效率较高

2.程序就是“写文章”

       双可读性:程序员阅读无障碍、计算机阅读无错误

3.程序就是“复制”

       建立自己常用工程程序库,将常用算法和程序经过多年总结和归纳,使之具有高可用性和高正确性,在后期工作时可直接“复制”,缓解工作压力

二、定名

1.函数命名原则

1)首字母大写

2)函数名可很长,要表意清晰

3)无参数的函数在括号内使用void

2.变量命名原则

1)以小写的缩写前缀显示说明该变量的类型,如nCountpBuffer

2)对于不同作用域的变量,如类成员变量和全局变量,必须以显式的m_g_前缀区分

3)变量名表意要清晰

4)变量在函数使用过程中严禁转义

5)静态数组指针以sz为前缀,不需要后续程序释放

6)动态申请指针以p为前缀,需要后续程序释放

7)结构体内部成员变量用m_作前缀

8)匈牙利命名法常用的变量前缀

       n            int

       c            char

       b            bool

       sz           静态数组

       p            动态指针

       us           unsigned short

       ui            unsigned int

       ul            unsigned long

       d            double

3.类定名

以大写C为前缀

4.结构体定名

1)使用typedef显式定义出一个类型,以便于后续的变量命名

2)每定义完一个结构体,定义一个结构体长度的变量,方便后续的内存申请动作

3)原则上,结构体内部不允许使用成员函数,仅用于数据的表示

5.宏定名

1)常量宏(C++中使用const定义常量)

2)函数型宏(C++中使用内联函数常量)

6.标签定名

1)定义原则:类名+下划线+函数名+下划线+用途

2)标签在编译时一般具有全局性,因此不能重名

3)结合goto使用较多

三、无错化程序的基本书写原则

1.写简单易懂的程序

       建议每个函数不超过100

       建议每个函数中最好只有一个循环体,可内嵌多重,不可并列

       建议每个函数只能有一个和业务相关的完整的判断逻辑,即if…else…逻辑,可内嵌多重,不可并列

       建议每个函数只能有一个完整的switch结构

       建议每个函数内部的大括号层数不要超过3

       建议每个函数的返回值尽量使用bool类型

       建议每个类包含的数据种类最好只有1-2

       建议结构体主要用于参数传递,不要包含成员函数

2.严禁变量转义

       变量声明后马上赋初值,避免使用“野变量”,变量转义本身就可以看做野变量,如果后续代码不做显式赋值,变量的初值完全取决于前面逻辑的计算结果

       多定义几个变量,每个变量各司其职

3.严禁一语多义

       ?(…):(…)结构是典型的一语多义

4.函数只能有一个出口

       1)保护二元动作的正确性,如:

内存申请动作mallocfree

C++中的newdelete操作

加锁和解锁动作

文件句柄的打开与关闭,如文件、SOCKET

       2)确保死循环中的sleep操作起作用

5.变量如不使用保持初值以供后续代码可访问到正确的变量

       以释放动态申请指针为例

       if( pBuffer )

       {

              free( pBuffer );

              pBuffer = NULL;

       }

6.常量必须使用宏或const显示定名

       如:

for(int i=0; i<100; i++)

       {

              … …

       }

       中的常量100最好使用宏或const进行显式定名

       特殊情况:

       1)常量可出现在变量赋初值的地方,但要加注释进行说明

       2)0可以出现在for(int i=0; … ; …)

3)1可以出现在while(1)

4)null原则上仅用于赋初值,判断指针是否为空一般使用if(!pBuffer)

7.太大数组不要用静态方式

       函数内部的静态数组建立在浮动栈上,如果滥用大数组,对浮动栈的冲击会非常大,很多时候出现不可见的bug隐患

8.尽量避免使用递归

       递归基本上没有办法单步跟踪

       递归成本较高(任何一次函数的调用都会引发一系列的浮动栈建栈、返回点的记录过程,存在一定的内存开销,递归层数多了,很容易因内存溢出导致程序崩溃)

9.解决方案一套就够

       团队强行约定一种写法,不要标新立异,用标准化开发保证工作效率,提升程序的直观易读性,降低bug

抱歉!评论已关闭.