C编程风格
所谓良好的编程风格在很大程度上属于一种个人品味,从比较客观合理的角度看,编程风格的好坏在于程序员是否具有良好的判断力。如果有什么是优良编程风格的关键的话,那就是必须让你编写出来的程序适合其他人阅读,这具体体现在两个方面:
1、 把你的思路用一些简明的语句表达出来;
2、 为那些语句选择一种适当的代码结构。
下面的例子给出一些常见的不良的编程风格,给出的改良也许是一种更好的选择。
1、 选用正确的条件
While(A){
If(B) continue;
C;
}
Continue语句通常可以通过改变测试条件来实现,而这种改变有时会显著改善程序代码的可读性。此处只需把if语句的条件测试反过来(求非)就可以提高代码的可读性。
While(A)
If(!B) C;
-------------------------
Do{
If(!A) continue;
Else B;
C;
}while(A);
对C程序里的“Do…while”结构进行等效替换往往也可以改善程序代码的可读性。在 “do…while”和 while语句都可以使用时,while总是首选。
此处的if和“do…while”都有些多余,它们相当于一条while语句。
先消除”多余的”continue语句:
Do{
If(A) {B; C;}
}while(A);
再把“Do…while”和if语句替换为while语句:
While(A){
B; C;
}
--------------------------
If(A)
If(B)
If(C) D;
Else;
Else;
Else
If(B)
If(C) E;
Else F;
Else;
多层嵌套的if语句是最容易出问题的:在到达最内层的条件时,外层的条件已经被忘记或模糊不清了。解决办法之一是一开始就把每个条件都完整地写清楚,但这往往会导致条件表达式既冗长又不容易看懂。在遇到这种情况的时候,良好的判断力是最重要的!
下面是这一问题的两种解决方案。第一种是从一开始就把每个条件都写得很完整:
If( A&&B&&C ) D;
Else if( !A&&B&&C ) E;
Else if( !A&&B&&!C ) F;
第二种解决方案不那么容易看明白,但执行效率更高:
If(B){
If(A){
If(C) D;
}else{
If(C) E;
Else F;
}
}
--------------------------------
While( (c=getchar())!=‘/n’ ){
If( c==‘ ’ ) continue;
If( c==‘/t’ ) continue;
If( c<‘ 0’ ) return(OTHER);
If( c<=‘ 9’ ) return(DIGIT);
If( c<‘a’ ) return(OTHER);
If( c<=‘z’ ) return(ALPHA);
Return (OTHER);
}return(EOL);
可以看出,该程序当输入行里还有字符需要处理的时候,根据字符类型执行不同的分支:
While( (c==getchar()) !=‘/n’ ){
If( c<=‘a’ && c<=‘z’ ) return ALPHA;
Else if( c>=‘ 0’ && c<=‘ 9’ ) return DIGIT;
Else if( c!=‘ ’&& c!=‘/t’ ) return OTHER;
}return (EOL);
2、 选用正确的结构
Done=i=0;
While( i<MAXI && !done ){
If( (x/=2)>1 ) {i++; continue;}
Done++;
}
改点:
1、“if…continue”与“if…else”效果一致;
2、关于循环条件:循环条件之一是done等于FALSE;
只要if条件是TRUE,done就将是FALSE;
因此,这个循环条件其实就是“( x/2 )> 1 ” 。
3、While循环可以用for循环代替,整合其他语句,改良后的代码如下:
For( i=0; i<MAXI && (x/=2)>1; i++ );
-----------------------
If( A ) { B; return; }
If( C ) { D; return; }
If( E ) { F; return; }
G; return;
在C语言里,一种想法往往会有多种表达方式,而程序员的任务是把各有关细节组织成一些条理清晰的语句块。C语言提供了以下元素来帮助程序员组织各有关细节:
1、 把最基本的想法写成表达式;
2、 把表达式组织为语句;
3、 把语句组织为语句块和函数。
这里可以分两步来解决:表达式B、D、F和G是几个最基本的元素,它们是同一个多重分支里彼此互不相关的几种分支情况。我们可以用“if…else if”语句把它们组织到一起:
If( A ) B;
Else if( C ) D;
Else if( E ) F;
Else G;
Return;
--------------------------
Plusflg=zeroflg=negflg=0;
If( a>0 ) ++plusflg;
If( a==0 ) ++zeroflg;
Else if( !plusflg ) ++negflg;
该题关键是如何写出一个有三种互斥分支情况的多重分支:
Plusflg=zeroflg=negflg=0;
If( a>0 ) ++plusflg;
Else if( a==0 ) ++zeroflg;
Else ++negflg;
--------------------------
I=0;
While( (c=getchar())!=EOF ){
If( c!=‘/n’ && c!=‘/t’ ) { s[i++]=c; continue; }
If( c==‘/n’ ) break;
If( c==‘/t’ ) c=‘ ’;
S[i++]=c;
}
改点:
1、检查break和continue语句是否比不可少。我们只需在while语句的条件里增加一个对break条件进行求非的子表达式就可以省略掉break语句;
2、Continue语句在效果上相当于“if…else”;
3、While语句可以整合成for语句。
改良后的语句如下:
For( i=0; ( c=getchar() ) !=EOF && c!=‘/n’; i++ )
If( c!=‘/t’ ) s[i]=c;
Else s[i]=‘ ’;
或
For( i=0;( c=getchar() )!=EOF && c!=‘/n’; i++ )
S[i]= c!=‘/t’ ? c : ‘ ’;
-------------------------
If( x!=0 )
If( j>k ) y=j/x;
Else y=k/x;
Else
If( j>k ) y=j/NEARZERO;
Else y=k/NEARZERO;
注意这里x!=0并不是重点:
If( j>k ) y = j / ( x != 0 ? x : NEARZERO );
Else y = k / ( x != 0 ? x : NEARZERO );
或
Y = MAX ( j , k ) / ( x != 0 ? x : NEARZERO );