青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

程序設計風格(1)


人們看到最好的作家有時并不理會修辭學的規則。還好,當他們這樣做雖然付
出了違反常規的代價,讀者還經常能從句子中發現某些具有補償性的價值。除非作
者自己也明確其做法的意思,否則最好還是按規矩做。
                                                             William Strunk和E. B. White,《風格的要素》


下面這段代碼取自一個許多年前寫的大程序:

i f ( (country == SING) I I (country == BRNI) I I
       (country == POL) I I (country == ITALY) )
{
/*
* I f the country is Singapore, Brunei or Poland
* then the current time is the answer time
* rather than the off hook time.
* Reset answer time and s e t day of week.
* /

...

這段代碼寫得很仔細,具有很好的格式。它所在的程序也工作得很好。寫這個系統的程序員會
對他們的工作感到驕傲。但是這段摘錄卻會把細心的讀者搞糊涂:新加坡、文萊、波蘭和意大
利之間有什么關系?為什么在注釋里沒有提到意大利?由于注釋與代碼不同,其中必然有一個
有錯,也可能兩個都不對。這段代碼經過了執行和測試,所以它可能沒有問題。注釋中對提到
的三個國家間的關系沒有講清楚,如果你要維護這些代碼,就必須知道更多的東西。


上面這幾行實際代碼是非常典型的:大致上寫得不錯,但也還存在許多應該改進的地方。
本書關心的是程序設計實踐,關心怎樣寫出實際的程序。我們的目的是幫助讀者寫出這
樣的軟件,它至少像上面的代碼所在的程序那樣工作得非常好,而同時又能避免那些污點和
弱點。我們將討論如何從一開始就寫出更好的代碼,以及如何在代碼的發展過程中進一步改
進它。


我們將從一個很平凡的地方入手,首先討論程序設計的風格問題。風格的作用主要就是
使代碼容易讀,無論是對程序員本人,還是對其他人。好的風格對于好的程序設計具有關鍵
性作用。我們希望最先談論風格,也是為了使讀者在閱讀本書其余部分時能特別注意這個問
題。


寫好一個程序,當然需要使它符合語法規則、修正其中的錯誤和使它運行得足夠快,但
是實際應該做的遠比這多得多。程序不僅需要給計算機讀,也要給程序員讀。一個寫得好的
程序比那些寫得差的程序更容易讀、更容易修改。經過了如何寫好程序的訓練,生產的代碼
更可能是正確的。幸運的是,這種訓練并不太困難。


程序設計風格的原則根源于由實際經驗中得到的常識,它不是隨意的規則或者處方。代
碼應該是清楚的和簡單的—具有直截了當的邏輯、自然的表達式、通行的語言使用方式、

有意義的名字和有幫助作用的注釋等,應該避免耍小聰明的花招,不使用非正規的結構。一
致性是非常重要的東西,如果大家都堅持同樣的風格,其他人就會發現你的代碼很容易讀,
你也容易讀懂其他人的。風格的細節可以通過一些局部規定,或管理性的公告,或者通過程
序來處理。如果沒有這類東西,那么最好就是遵循大眾廣泛采納的規矩。我們在這里將遵循
《C程序設計語言》(The C Programming Language)一書中所使用的風格,在處理J a v a和C++ 程
序時做一些小的調整。


我們一般將用一些好的和不好的小程序設計例子來說明與風格有關的規則,因為對處理
同樣事物的兩種方式做比較常常很有啟發性。這些例子不是人為臆造的,不好的一個都來自
實際代碼,由那些在太多工作負擔和太少時間的壓力下工作的普通程序員(偶然就是我們自己)
寫出來。為了簡單,這里對有些代碼做了些精練,但并沒有對它們做任何錯誤的解釋。在看
到這些代碼之后,我們將重寫它們,說明如何對它們做些改進。由于這里使用的都是真實代
碼,所以代碼中可能存在多方面問題。要指出代碼里的所有缺點,有時可能會使我們遠離討
論的主題。因此,在有的好代碼例子里也會遺留下一些未加指明的缺陷。


為了指明一段代碼是不好的,在本書中,我們將在有問題的代碼段的前面標出一些問號,
就像下面這段:

? #define ONE 1
? #define TEN 10
? #define TWENTY 20

為什么這些# d e f i n e有問題?請想一想,如果某個具有T W E N T Y個元素的數組需要修改得更大
一點,情況將會怎么樣。至少這里的每個名字都應該換一下,改成能說明這些特殊值在程序
中所起作用的東西。

#def i ne INPUT-MODE 1
#define INPUT-BUFSIZE 10
#def i ne OUTPUT-BUFSIZE 20

 

1.1 名字


什么是名字?一個變量或函數的名字標識這個對象,帶著說明其用途的一些信息。一個名
字應該是非形式的、簡練的、容易記憶的,如果可能的話,最好是能夠拼讀的。許多信息來
自上下文和作用范圍(作用域)。一個變量的作用域越大,它的名字所攜帶的信息就應該越多。
全局變量使用具有說明性的名字,局部變量用短名字。根據定義,全局變量可以出現在整個
程序中的任何地方,因此它們的名字應該足夠長,具有足夠的說明性,以便使讀者能夠記得
它們是干什么用的。給每個全局變量聲明附一個簡短注釋也非常有幫助:

int npending = 0; // current length of input queue

全局函數、類和結構也都應該有說明性的名字,以表明它們在程序里扮演的角色。
相反,對局部變量使用短名字就夠了。在函數里, n可能就足夠了, n p o i n t s也還可以,
用n u m b e r O f P o i n t s就太過分了。


按常規方式使用的局部變量可以采用極短的名字。例如用i、j作為循環變量,p、q作為
指針,s、t表示字符串等。這些東西使用得如此普遍,采用更長的名字不會有什么益處或收
獲,可能反而有害。比較:

for (theElementIndex = 0; theElementIndex < number0fElements; theElementIndex++)
         elementArray[theElementIndex] = theElementIndex;


for (i = 0; i < nelems; i++)
         elem[i] = i ;


人們常常鼓勵程序員使用長的變量名,而不管用在什么地方。這種認識完全是錯誤的,清晰
性經常是隨著簡潔而來的。


現實中存在許多命名約定或者本地習慣。常見的比如:指針采用以p結尾的變量名,例如
n o d e p;全局變量用大寫開頭的變量名,例如G l o b a l;常量用完全由大寫字母拼寫的變量
名,如C O N S T A N T S等。有些程序設計工場采用的規則更加徹底,他們要求把變量的類型和用
途等都編排進變量名字中。例如用p c h說明這是一個字符指針,用s t r T o和s t r F r o m表示它
們分別是將要被讀或者被寫的字符串等。至于名字本身的拼寫形式,是使用n p e n d i n g或
n u m P e n d i n g還是n u m _ p e n d i n g,這些不過是個人的喜好問題,與始終如一地堅持一種切
合實際的約定相比,這些特殊規矩并不那么重要。


命名約定能使自己的代碼更容易理解,對別人寫的代碼也是一樣。這些約定也使人在寫
代碼時更容易決定事物的命名。對于長的程序,選擇那些好的、具有說明性的、系統化的名
字就更加重要。


C++ 的名字空間和J a v a的包為管理各種名字的作用域提供了方法,能幫助我們保持名字
的意義清晰,又能避免過長的名字。


保持一致性。相關的東西應給以相關的名字,以說明它們的關系和差異。
除了太長之外,下面這個J a v a類中各成員的名字一致性也很差:

class UserQueue {
        i n t noOfIternsInQ, frontOiTheQueue, queuecapacity;
        public i n t noOfUsersInQueue() {... }

這里同一個詞“隊列( q u e u e )”在名字里被分別寫為Q、Q u e u e或q u e u e。由于只能在類型
U s e r Q u e u e里訪問,類成員的名字中完全不必提到隊列,因為存在上下文。所以:

queue.queuecapacity

完全是多余的。下面的寫法更好:

class UserQueue {
   int ni terns, front, capacity;
   public i n t nusers() {. . .}

}

因為這時可以如此寫:

quue.capacity++;

n = queue.nusers();

這樣做在清晰性方面沒有任何損失。在這里還有可做的事情。例如i t e m s和u s e r s實際是同一種
東西,同樣東西應該使用一個概念。


函數采用動作性的名字。函數名應當用動作性的動詞,后面可以跟著名詞:

now = date .getTirne() ;
putchar('\nl) ;

對返回布爾類型值(真或者假)的函數命名,應該清楚地反映其返回值情況。下面這樣的語句

if(checkoctal(c)) ...

是不好的,因為它沒有指明什么時候返回真,什么時候返回假。而:

i f (i soctal (c)) . . .

就把事情說清楚了:如果參數是八進制數字則返回真,否則為假。
要準確。名字不僅是個標記,它還攜帶著給讀程序人的信息。誤用的名字可能引起奇怪的程
序錯誤。


本書作者之一寫過一個名為i s o c t a l的宏,并且發布使用多年,而實際上它的實現是錯誤的:

#define isoctal(c) ((c) >= '0' && (c) <= '8')

正確的應該是:

#define isoctal(c) ((c) >= '0' && (c) <= '7')

這是另外一種情況:名字具有正確的含義,而對應的實現卻是錯的,一個合情合理的名字掩
蓋了一個害人的實現。


下面是另一個例子,其中的名字和實現完全是矛盾的:

public boolean inTable(0bject obj) {
  i n t j = t h i s .getIndex(obj) ;
 return (j == nTable);
}

函數g e t I n d e x如果找到了有關對象,就返回0到n T a b l e-1之間的一個值;否則返回
n T a b l e值。而這里i n T a b l e返回的布爾值卻正好與它名字所說的相反。在寫這段代碼時,
這種寫法未必會引起什么問題。但如果后來修改這個程序,很可能是由別的程序員來做,這
個名字肯定會把人弄糊涂。

 

posted on 2007-11-02 02:45 lovedday 閱讀(580) 評論(0)  編輯 收藏 引用 所屬分類: ▲ Software Program

公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美国产成人精品| 午夜精品免费| 国产精品第一页第二页第三页| 久久综合九色综合欧美狠狠| 欧美一区午夜视频在线观看| 亚洲综合电影一区二区三区| 亚洲在线成人| 久久精品国产99国产精品澳门| 久久天天狠狠| 欧美成人精品一区二区| 欧美人成在线视频| 国产精品久久久久久久免费软件| 国产精品久久久一区麻豆最新章节 | 欧美人牲a欧美精品| 欧美日韩视频一区二区| 国产精品欧美风情| 亚洲国产精品一区二区www| 亚洲人成网站影音先锋播放| 中国av一区| 久久精品色图| 亚洲清纯自拍| 日韩一区二区电影网| 久久aⅴ国产紧身牛仔裤| 欧美激情欧美狂野欧美精品| 欧美日韩一二三四五区| 激情成人综合网| 欧美与黑人午夜性猛交久久久| 久久精品亚洲精品国产欧美kt∨| 欧美精品久久久久久久免费观看| 国产乱码精品| 一区二区高清视频| 欧美1区2区3区| 亚洲无线观看| 欧美.日韩.国产.一区.二区| 国产精品久久97| 亚洲人成精品久久久久| 欧美一区二区成人6969| 亚洲精品乱码视频| 久久精品亚洲热| 国产精品久久午夜| 午夜精品久久久久| 亚洲精品久久视频| 欧美在线电影| 国产精品中文字幕欧美| 亚洲精品久久久蜜桃| 久久手机精品视频| 亚洲男女自偷自拍| 国产精品第十页| 一区二区日韩伦理片| 欧美激情bt| 久久久无码精品亚洲日韩按摩| 国产精品一区免费观看| 一区二区三区四区国产精品| 亚洲国产日韩欧美一区二区三区| 久久久久久亚洲综合影院红桃| 国产日产精品一区二区三区四区的观看方式| 亚洲国产综合在线看不卡| 久久综合色88| 久久精品卡一| 亚洲成色777777在线观看影院| 久久久国产视频91| 久久精品理论片| 亚洲二区在线| 91久久综合| 欧美成人自拍视频| 一区二区三区免费在线观看| 亚洲精品一级| 欧美日韩ab片| 亚洲摸下面视频| 午夜精品免费在线| 国产午夜精品久久| 裸体素人女欧美日韩| 久久人人看视频| 亚洲国产精品综合| 亚洲精品极品| 国产精品毛片va一区二区三区 | 久久狠狠久久综合桃花| 亚洲一区二区三区在线| 国产日韩专区| 久久亚洲影院| 欧美成年人视频| 亚洲视频一区在线| av不卡免费看| 亚洲欧美在线另类| 亚洲福利av| 99在线|亚洲一区二区| 国产九九精品视频| 欧美成人综合| 欧美午夜寂寞影院| 久久女同互慰一区二区三区| 欧美aa在线视频| 欧美亚洲综合在线| 免费国产自线拍一欧美视频| 亚洲自拍偷拍色片视频| 久久久九九九九| 亚洲神马久久| 麻豆精品精华液| 欧美一区二区大片| 欧美老女人xx| 国产在线播放一区二区三区| 亚洲欧美激情视频| 久久久久99精品国产片| 亚洲深夜福利网站| 猛男gaygay欧美视频| 亚洲欧美视频一区二区三区| 久久亚洲国产精品一区二区 | 欧美紧缚bdsm在线视频| 久久精品亚洲一区二区三区浴池| 欧美电影电视剧在线观看| 欧美一区二视频在线免费观看| 欧美顶级艳妇交换群宴| 久久亚洲图片| 国产日韩欧美夫妻视频在线观看| 亚洲电影免费观看高清完整版| 国产精品入口麻豆原神| 亚洲精品乱码久久久久久蜜桃91 | 一区二区三区精密机械公司| 亚洲国产一区二区视频| 欧美在线视频观看免费网站| 亚洲欧美第一页| 欧美日韩精品伦理作品在线免费观看| 美乳少妇欧美精品| 国内成人在线| 羞羞色国产精品| 亚洲一区二区三区精品动漫| 米奇777在线欧美播放| 美女视频网站黄色亚洲| 国产最新精品精品你懂的| 宅男66日本亚洲欧美视频| 野花国产精品入口| 欧美激情第8页| 亚洲日本免费| 夜夜狂射影院欧美极品| 欧美好吊妞视频| 亚洲盗摄视频| 亚洲美女色禁图| 欧美高清视频在线播放| 亚洲高清免费视频| 亚洲精品视频在线| 免费美女久久99| 亚洲欧洲在线免费| 在线视频一区观看| 亚洲国产中文字幕在线观看| 亚洲东热激情| 免费观看日韩| 91久久在线观看| 一区二区三区你懂的| 欧美日韩中文字幕在线视频| 一区二区三区久久精品| 亚洲欧美日韩中文播放| 国产视频欧美视频| 久久精品国产99| 欧美激情第10页| 一二三区精品福利视频| 欧美三级电影大全| 亚洲女人天堂成人av在线| 久久国产婷婷国产香蕉| 在线精品视频一区二区| 欧美岛国激情| 亚洲在线日韩| 麻豆av一区二区三区| 久热爱精品视频线路一| 一区二区免费看| 国产乱码精品一区二区三区忘忧草| 亚洲欧美日本伦理| 牛人盗摄一区二区三区视频| 一区二区精品在线| 国产午夜精品全部视频播放| 快she精品国产999| 亚洲一品av免费观看| 农夫在线精品视频免费观看| 亚洲影视中文字幕| 激情视频亚洲| 欧美精品在线观看91| 午夜日韩电影| 亚洲毛片av在线| 麻豆精品传媒视频| 一本色道久久88精品综合| 国产毛片一区二区| 欧美精品在线观看播放| 欧美影院一区| 99国产精品99久久久久久| 久久综合网色—综合色88| 亚洲天堂av高清| 亚洲高清免费在线| 国产视频在线观看一区二区| 欧美日韩一级大片网址| 久色成人在线| 久久精品理论片| 亚洲香蕉视频| 日韩视频在线免费观看| 欧美xxx在线观看| 欧美在线视频一区二区| 亚洲一区欧美激情| 一区二区三区视频免费在线观看| 在线日韩欧美| 狠狠色狠狠色综合日日小说| 国产精品网红福利| 国产精品久久久999| 欧美日韩一二区|