一、程序真谛
1.程序就是“搬数”
动作:读取——技术——写出(输入——处理——输出)
数据结构决定数据如何组织,搬动起来效率较高
算法语言决定了如何搬效率较高
2.程序就是“写文章”
双可读性:程序员阅读无障碍、计算机阅读无错误
3.程序就是“复制”
建立自己常用工程程序库,将常用算法和程序经过多年总结和归纳,使之具有高可用性和高正确性,在后期工作时可直接“复制”,缓解工作压力
二、定名
1.函数命名原则
1)首字母大写
2)函数名可很长,要表意清晰
3)无参数的函数在括号内使用void
2.变量命名原则
1)以小写的缩写前缀显示说明该变量的类型,如nCount,pBuffer
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)保护二元动作的正确性,如:
内存申请动作malloc与free
C++中的new与delete操作
加锁和解锁动作
文件句柄的打开与关闭,如文件、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率