<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    ivaneeo's blog

    自由的力量,自由的生活。

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

    這篇短小的文檔用于描述linux內(nèi)核編程中推薦的編程風(fēng)格。編程風(fēng)格是很個人
    化的東西,我不想把我的觀點_強加_給任何人,但這是我必須維護(hù)的代碼中所遵守
    的,我也建議其他部分的代碼也能遵守它。請至少給這里的觀點一些考慮。

    首先,我建議你打印一份GNU代碼風(fēng)格,不是去讀它,而是把它燒了,這是個很
    不錯的姿態(tài)。

    不廢話了,下面就是Linux內(nèi)核編程風(fēng)格:

                    第一章:縮進(jìn)

    制表符(tabs)占8個字符,所以縮進(jìn)也是8個字符。有些異端運動想使用4個字符
    (甚至是2個字符)的縮進(jìn),這和把PI(圓周率)定為3沒什么兩樣。

    原因:縮進(jìn)的根本目的是用來清晰地標(biāo)識一個控制塊的起始。特別是當(dāng)你連續(xù)盯
    著屏幕看了20
    個小時后,你就會體會到更長的縮進(jìn)的好處了。

    現(xiàn)在,有些人提出8字符縮進(jìn)會使得代碼太偏向右邊,當(dāng)使用80字符的終端
    時很難閱讀。答案是如果你需要三層以上的縮進(jìn),那么你已經(jīng)完蛋了,應(yīng)該改改
    你的程序了。

    簡而言之,8字符縮進(jìn)使得閱讀代碼更為容易,并且在你的縮進(jìn)層次過深時提出
    警告。應(yīng)該留心這樣的警告。

                    第二章:括號的位置

    括號位置的問題在C編程風(fēng)格中經(jīng)常被提出。和縮進(jìn)大小不同,括號位置的選擇
    并沒有太多技術(shù)上的原因,而更多的是個人的喜好。比如Kernighan和Ritchie的
    弟子們把左括號放在一行的最后,把右括號放在一行的開始,象這樣:

            if (x is true) {

                    we do y

            }

    但是,函數(shù)是一種特殊的情況,函數(shù)的左括號放在下一行的開始,象這樣:

            int function(int x)

            {

                    body of function

            }

    全世界的異端人士指出這種不一致的做法 ...嗯...
    不太一致,但是所有思維正
    確的人知道 (a) K&R是_對_的 (b)
    K&R是對的。而且,函數(shù)確實是特殊的(你在C
    中無法對函數(shù)進(jìn)行嵌套)。

    注意到右括號完全占有單獨的一行,_除非_當(dāng)它后面還有未完成的語句,比如do
    語句中的“while”或者if語句中的“else”,想這樣:

            do {

                    body of do-loop

            } while (condition);


            if (x == y) {

                    ..

            } else if (x > y) {

                    ...

            } else {

                    ....

            }

    原因:K&R。

    還有,注意到這種括號的布局方法還減少了空行(或者說是幾乎是空行)的數(shù)目,
    而且沒有減小可讀性。因為你屏幕上的空行是不可回收資源(這里想一下25行的
    終端屏幕),這樣你會有更多的空行用于加注釋。

                    第三章:命名

    C是個斯巴達(dá)式(崇尚簡潔風(fēng)格的)語言,所以你的命名方法也應(yīng)該如此。與
    Modula-2和Pascal程序員不同,C程序員不使用
    ThisVariableIsATemporaryCounter這樣可愛的名字。一個C程序員會把一個變量
    叫做“tmp”,這樣的變量名更容易寫,而且理解起來也不算太難。

    _但是_,盡管人人都會對大小寫混雜的名字皺眉頭,全局變量名則必須如此。管
    一個全局函數(shù)叫“foo”是故意找岔。

    _全局_變量(只有在_真正_需要時才使用)需要有個描述性強的名字,這點和全
    局函數(shù)一樣。如果你有個函數(shù)用于對活躍用戶進(jìn)行計數(shù),你嬰兒叫它
    “count_active_users()”,而不是“cntusr()”。

    把函數(shù)的類型加入到名字中(所謂的匈牙利命名法)是腦損傷的表現(xiàn)
    - 編譯器
    知道類型,能夠?qū)λM(jìn)行檢查,這種命名法只會把程序員自己搞暈。難怪微軟做
    了那么多充滿bug的程序。

    _局部_變量應(yīng)該短小扼要。如果你有個隨機的整數(shù)循環(huán)變量,可能最好叫它“i”。
    把它叫做“l(fā)oop_counter”是效率低下的,在不會發(fā)生混淆的情況下。類型地,
    “tmp”可以被用于任何類型的存儲臨時值的變量。

    如果你擔(dān)心混淆你的局部變量,那么你就會有另一個問題,所謂的函數(shù)膨脹荷爾
    蒙失衡綜合癥,請看下一章。

                    第四章:函數(shù)

    函數(shù)應(yīng)該短小而甜美,而且只能做一件事。他們應(yīng)該只用一兩屏幕(我們都知道,
    ISO/ANSI標(biāo)準(zhǔn)屏幕大小是80x24)就能裝下,只做并且做好一件事。

    函數(shù)的最大長度應(yīng)該與函數(shù)的復(fù)雜性和縮進(jìn)層次成反比。所以,如果你有個只有
    一個很長(但很簡單)的case語句的函數(shù),對許多case做一些很少的操作,那么
    這個函數(shù)長點也沒有關(guān)系。

    但是,如果你有一個復(fù)雜的函數(shù),你擔(dān)心一個中等智力的高一學(xué)生可能無法理解,
    那么你應(yīng)該更嚴(yán)格地遵守最大長度限制。使用有描述性名字的幫助函數(shù)(你可以
    讓編譯器in-line這些幫助函數(shù),如果你認(rèn)為性能很重要的話,而且編譯器恐怕
    會比你做的要好)。

    函數(shù)的另一個指標(biāo)是局部變量的數(shù)目,局部變量的數(shù)目不應(yīng)超過5-10個,否則一
    定是哪里有問題了。再設(shè)計一下這個函數(shù),把它分解得更小一些。人的大腦一般
    可以同時跟蹤7個不同的東西,超過了7個就會暈菜。雖然你很聰明,不過可能你
    有時會想理解一下兩星期前所寫的代碼。

                    第五章:注釋

    注釋是好東西,不過存在過分注釋的危險。_永遠(yuǎn)_不要在注釋中解釋你的代碼是
    如何工作的:更好的做法是寫出工作方式顯而易見的代碼,解釋糟糕的代碼是浪
    費時間。

    一般來說,注釋應(yīng)該說明代碼在做什么,而不是怎么做。并且,不要把注釋加在
    函數(shù)主體中:如果函數(shù)太復(fù)雜以至于必須對各個部分進(jìn)行注釋,那么你可能要再
    去讀讀第四章。你可以加入一些短小的注釋來提醒或警告一些聰明(或難看)的
    做法,但不要太過度。更好的選擇是,把注釋放在函數(shù)頭,說明函數(shù)在做什么,
    可能還包括它為什么做。

                    第六章:你的代碼亂七八糟

    沒什么,我們都遇到過。你可能從老Unix用戶那里聽說過“GNU
    emacs”會自動
    對齊C源代碼,但缺省的設(shè)置不是很好(事實上,缺省設(shè)置比胡亂敲打還糟糕
    -
    一群使用GNU emacs猴子永遠(yuǎn)不會做出漂亮的程序)。

    所以,你或者徹底仍掉GNU
    emacs,或者采用更理智的設(shè)置。如果選擇后者,你
    可一把下面的代碼加到你的.emacs文件中:

    (defun linux-c-mode ()

      "C mode with adjusted defaults for use with the Linux kernel."

      (interactive)

      (c-mode)

      (c-set-style "K&R")

      (setq c-basic-offset 8))

    這會定義 M-x linux-c-mode
    命令。當(dāng)編寫Linux模塊時,如果你把字符串“-*-
    linux-c
    -*-”放在文件的頭兩行中,這個模式就會被自動激活。還有,如果你
    想在編輯/usr/src/linux目錄下的源文件時linux-c-mode被自動激活,你在你的.
    emacs文件中需要加入

    (setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" .
    linux-c-mode)
    auto-mode-alist))

    但是即使你用不了emacs,并不是世界末日:你還可以使用“indent”。

    又一次,GNU indent使用了和GNU
    emacs一樣的腦死亡設(shè)置,所以你需要給它一
    些命令行選項。但是,這不算太壞,因為即使是GNU
    indent的作者們也意識到了
    K&R的權(quán)威性(GNU的人也不是魔鬼,他們只是在這件事上被誤導(dǎo)了),所以你可
    以使用選項“-kr
    -i8”(表示“K&R,8字符縮進(jìn)”)運行indent。

    “indent”有很多選項,特別是注釋布局部分,你可能想看看它的man手冊。但
    是請記住:“indent”不能修改糟糕的程序。

                    第七章:配置文件

    配置選項
    (arch/xxx/config.in,以及所有Config.in文件)使用了有些不同的
    縮進(jìn)方式。

    代碼中使用的是3字符縮進(jìn),config-選項中應(yīng)該使用2字符縮進(jìn)標(biāo)識依賴關(guān)系。
    后者只應(yīng)用于bool/tristat選項。對于其他選項,采用你認(rèn)為最合適的縮進(jìn)方式
    就可以了。例如:

    if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then

       tristate 'Apply nitroglycerine inside the keyboard (DANGEROUS)'
    CONFIG_BOOM

       if [ "$CONFIG_BOOM" != "n" ]; then

          bool '  Output nice messages when you explode' CONFIG_CHEER

       fi

    fi

    一般來說,所有不穩(wěn)定的選項應(yīng)該標(biāo)為CONFIG_EXPERIMENTAL。所有可能損壞數(shù)
    據(jù)的的選項應(yīng)該標(biāo)為(DANGEROUS),其他的試驗選項應(yīng)該標(biāo)為(EXPERIMENTAL)。

                    第八章:數(shù)據(jù)結(jié)構(gòu)

    供多線程使用的數(shù)據(jù)結(jié)構(gòu)應(yīng)該采用引用計數(shù)(reference
    counts)。在內(nèi)核中,
    垃圾回收(garbage
    collection)是不存在的(內(nèi)核之外的垃圾回收效率不高),
    這意味著你_必須_使用引用計數(shù)。

    引用計數(shù)的使用能避免鎖的使用,使不同的用戶能夠并行使用數(shù)據(jù)結(jié)構(gòu)
    - 不需
    要擔(dān)心結(jié)構(gòu)會因為睡眠而突然消失。

    注意到加鎖_不是_引用計數(shù)的替代物。加鎖用于保證數(shù)據(jù)結(jié)構(gòu)的完整性,而引用
    計數(shù)是一個內(nèi)存管理技術(shù)。通常你兩個都需要,不應(yīng)該有任何混淆不清的地方。

    一些數(shù)據(jù)結(jié)構(gòu)可能使用兩層的引用計數(shù),當(dāng)對不同的“類”都有使用的時候。子
    類的計數(shù)統(tǒng)計所有子類用戶的數(shù)目,當(dāng)子類的計數(shù)為零時只對總計數(shù)減一。

    這種“多層引用計數(shù)”的例子可以在內(nèi)存管理代碼(“struct
    mm_struct”:
    mm_users和mm_cout)和文件系統(tǒng)代碼(“struct
    super_block”:s_count和
    s_active)中找到。

    記住:如果另一個線程能夠看見你的數(shù)據(jù)結(jié)構(gòu),而你卻沒有對它使用引用計數(shù),
    那么幾乎可以肯定會有bug存在。

    posted on 2005-12-02 13:14 ivaneeo 閱讀(605) 評論(0)  編輯  收藏 所屬分類: GNU牛力
    主站蜘蛛池模板: 亚洲第一中文字幕| 好爽又高潮了毛片免费下载| 亚洲日韩精品A∨片无码加勒比| 久久久久国色AV免费看图片| 亚洲一区日韩高清中文字幕亚洲| 日本免费电影一区| 天天干在线免费视频| 成年女人18级毛片毛片免费观看| 无码永久免费AV网站| 精品久久久久久久久免费影院| 可以免费看黄视频的网站| 国产成人免费爽爽爽视频| 毛片网站免费在线观看| 最近中文字幕mv手机免费高清| 久久精品女人天堂AV免费观看| 久久精品无码一区二区三区免费| 成人免费福利电影| 国产免费久久精品| 亚洲精品在线视频| 亚洲综合精品香蕉久久网| 久久综合日韩亚洲精品色| 亚洲人成在线电影| 亚洲无砖砖区免费| 亚洲欧美日韩综合久久久| 免费人成视频在线播放| 久久99精品免费一区二区| 日本卡1卡2卡三卡免费| 免费A级毛片无码无遮挡内射| 国产精品成人免费视频网站京东| 国产美女无遮挡免费视频网站| 亚洲AV成人潮喷综合网| 精品国产综合成人亚洲区| 久久综合亚洲鲁鲁五月天| 亚洲最大的黄色网| 猫咪免费人成网站在线观看入口 | 亚洲精品tv久久久久| 中文字幕无码精品亚洲资源网| 亚洲va久久久噜噜噜久久天堂| 亚洲专区一路线二| 青青草国产免费国产是公开| 日韩电影免费观看|