命名应该是面向问题而不是面向解决问题。应该说明的是”什么“而不是”怎么“。变量名称是否完全而又准确地描述了变量所代表的实体
类名、文件名都应该是以名词的组合 tradelist tradeedit tradeview tradesave
方法名应该是动词+名词的组合 createDate() removeTrade()
a、 限定词 如 data,total average 应该放在名词的后面
b、循环变量命名
i、j、k、 如果在循环体内的变量要在循环外被使用,则要使用比i、j、k 更能说明问题的名词
eg: recordCount: 已经读取了多少记录。
c、状态变量命名
d、临时变量
temp,少用temp这样没有意义的临时变量。
e、逻辑变量
isDone 某项工作已经完成
isError 某个操作发生了错误
isFond 找到了某个值
(2)、命名规约
标示全局变量 以g_作为前缀来解决 g_runTotal
-
使用标准的缩写(常用缩写,如列在字典缩写表中的)。
-
去掉所有的非大写元音字母(如Computer写成 Cmptr, Screen写成 Scrn, Integer写成Inter 等)。
-
使用每个单词的头一个或头几个字母。
-
截掉每个单词头一至三个字母后面的其余字母。
-
使用变量名中每一个有典型意义的单词,最多可用三个单词。
-
每个单词的第一个和最后一个字母。
-
去掉无用的后缀——ing,ed等等。
-
保留每个音节中最易引起注意的发音。
-
反复交替地使用上述技术,直到变量名长度缩短至8到 20个字母为止,或者到你所用语言规定的长度为止。
(二)、变量
1、变量的作用域
模块作用域、函数作用域、全局作用域
eg: initA(int a)
initB(int b)
intC(int c)
accountA(int a)
accountB(int b)
accountC(int c)
平均跨度:(2+2+2)/3=2
改进:
initA(int a)
accountA(int a)
initB(int b)
accountB(int b)
initC(int c)
account(int c)
平均跨度:(0+0+0)/3=0 可读性强
2、变量得赋值时间
把变量和变量的值联系在一起是在写程序时把它们联系在一起?还是在编译、加载或者程序运行时把它们联系在一起?
private static final int X_C=20;
x=MaxID;或者 x=getMaxID() 都是在运行时把变量和变量值联系在一起。
(四)、基本数据类型
1、浮点数 : (1)、不要在数量级相差太大的数之间进行加减运算。
(2)、避免相等运算
float x=5.5;
float sum=0;
for(int i=0;i<10;i++){
sum=i+0.5;
if(sum==x) then ....
else .......
}
if(x-y<0.0001) return true; //说明他们是相等的
else return false;
}
if(element<0||element>100||element==80){
then ...
}
//改进
boolean finished=element<0||element>100||element==80;
if(finished){
then .....
}
(五)、条件语句
if.. else.... switch() case default
(1)、 简单的if...else...语句的几个原则:
a、现写正常的语句后写异常的语句。
(六)、循环语句
(1)、 do-while while-do for
其中 for 循环是用于知道了循环条件要执行多少次,而 while不知道要执行多少次,而是每次重复之前检查是否满足循环条件。循环的初始化工作最好放在一起且在循环的开始部分。
while(not eof(File)) doread( Record, File )if( Record.type<>TargetType ) thencontinue{process record of TargetType}...end while
1、代码调整策略
代码调整只是提高程序性能的一种方法,它是对正确代码进行调整的实践,它可以使代码的运行更高效,调整指的是小规模的修改,可以影响单个类,单个子程序。
一些代码调整的错误说法:
- 在高级语言中,减少代码的行数可以提升所生成的机器代码的运行速度。
- 应当随时随地的优化,容易使程序员陷入一叶障目,而忽视了整个系统全局的优化。
- 程序的运行速度同其它正确性同等重要,在程序无法运行的情况下,不可能要求程序更小巧,更快,所
- 有需要先让程序能运行,再调整。
何时调整:
程序员应当使用高质量的设计,把程序编写正确。使模块化并易于修改,将让后期的维护工作边的很容易。在程序已经完成并正确之后,再去检查系统的性能。
2、代码调整方法
- 用高度模块化设计开发软件,这样易于理解,修改。
- 如果性能很差,测量系统,找出频繁执行位置。
- 判断性能的弱点是否是由不合格的设计数据结构算法引起的,判断代码调整是否合 适;如果代码调整不合适,返回步骤1。
- 调整步骤3中识别出来的系统中的薄弱环节,测量每一个改进,如果它不能提高系统性能就放弃重来。
- 重复步骤2。
3、代码调整技术
循环体内有开关的例子:
for (int i = 0; i < count; i++) {
if (SumType == Net) {
NetSum = NetSum + Amount[i];
} else {
GrossSum = GrossSum + Amount[i];
}
}
if(SumType==Net){
for(i=0,i<Count,i++){
NetSum=NetSum+Amount[i];
}
}else {
for(i=0;i<Count;i++){
GrossSum=GrossSum+Amount[i];
}
}
Basic 把会冲突的循环分离:
for i=1 to Num
EmployeeName(i)=" "
next i
for i=1 to Num
EmployeeEarnings(i)=0
Next i
如果你的程序有冲突竞争,你得将之合二为一。这通常意味着,循环计数器只能有一个。本例中两个循环用到 1 to Num,可能有冲突争先的危险,可以改成:
Basic 有冲突的循环:
for i=1 to Num
EmploreeName(i)=" "
EmployeeEarnings(i)=0
写出有效率的程序段的关键在于,使循环内的工作量最小。如果你能估计出全部或部分结果语句,并仅将结果用在循环内,这么做是有理由的。通常这是一种编程的好方法,有时还会增可加可读性。
假如你有如下程序,循环内有一复杂的指针表达式:
C 循环内带有复杂的指针表达式:
for(i=0,i<Num;i++)
{
NetRate[i]=BaseRate[i]*Rates->Discounts->Factors->Net
}
此处将合适的名字赋给变量,并另配给复杂的指针表达式可以提高性能和可读性。
C 简化复杂指针表达式:
QuantityDiscounts=Rates->Discounts->Factors->Net;
for(i=0;i<Num;i++)
{
NetRate[i]=BaseRate[i]*QuantityDiscount
}
特殊变量 QuantityDiscount,很清楚地使得数组 BaseRate 乘上一个数量因数,从而计算出网络比率,从循环中表达式看并不是那么清楚。若把复杂的指针表达式赋给循环外的变量,可防止每次运算循环时,指针都被三次引用。
除了 C 编译器外,这种方法提高的效率是微不足道的,这提醒你们,开始设计代码时不必过多考虑执行速度,而应从可读性人手。
如果循环判断比较复杂的话,你可以简化判断句提高效率。如果循环是为了找数,一种方法就是使用标记值,把它安插在找数程序的末尾,并且保证终止找数检索。关于使用标记值从而改善复杂测试,这里有一个典型例子,循环的检索部分检查是否找到标志值,判断是否偏离标志值。
C 检索循环内的复杂判断:
Found=FALSE
i=0
while( (!found)&&(i<ElementCount))
{
if(Item[i]==TestValue)
i++;
}
InitialValue=Item[ElementCount];
Item[ElementCount]=TestValue;
i=0;
while(Item[i]!=TestValue)
{
i++;
Item[ElementCount]=Initialvalue;
/* check if value was found */
if(i<ElementCount) {
For Column:=1 to 100 do
begin
for Now:=1 do 5 do
begin
sum:=sumTable[1000,column]
end
end
begin
for Now:=1 do 100 do
begin
sum:=sumTable[1000,column]
end
end
System.out.println("begin:" + new Date().getTime());
for (int i = 0; i < 1000000; i++) {
for (int j = 0; j < 100; j++) {
}
}
System.out.println("end:" + new Date().getTime());
System.out.println("begin:" + new Date().getTime());
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 1000000; j++) {
}
}
System.out.println("end:" + new Date().getTime());
-
使用所有数据建立假设
-
求精产生错误的测试用例
-
通过不同的方法再生错误
-
产生更多的数据以生成更多的假设
-
使用否定测试结果
-
提出尽可能多的假设
-
缩小可疑代码区
-
检查最近作过修改的代码
-
扩展可疑代码区
-
逐步集成
-
怀疑以前出过错的子程序
-
耐心检查
-
为迅速的草率的调试设定最大时间
-
检查一般错误
-
使用交谈调试法
-
中断对问题的思考
-
改正错误的方法:
-
理解问题的实质
-
理解整个程序
-
确诊错误
-
放松情绪
-
保存初始源代码
-
修改错误而不是修改症状
-
仅为某种原因修改代码
-
一次作一个修改
-
检查你的工作,验证修改
-
寻找相似错误
-
调试的一般方法
-
你是否将调试作为学习有关程序、错误、代码质量及解决问题方法的一次机会?
-
你是否避免使用试错法,或避免采用迷信的方法?
-
你是否认为错误是由于你的过错?
-
你是否使用科学方法以固定间歇性错误?
-
你是否使用科学方法发现错误?
-
你是否每次使用不同的方法,而不是只用一种方法发现错误?
-
你是否验证了修改信息是正确的?
-
你是否利用了警告信息、执行剖析程序、建立脚手架方法、交互式调试等?