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

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

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

    ivaneeo's blog

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

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      669 Posts :: 0 Stories :: 64 Comments :: 0 Trackbacks

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

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

    不廢話了,下面就是Linux內核編程風格:

                    第一章:縮進

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

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

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

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

                    第二章:括號的位置

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

            if (x is true) {

                    we do y

            }

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

            int function(int x)

            {

                    body of function

            }

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

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

            do {

                    body of do-loop

            } while (condition);


            if (x == y) {

                    ..

            } else if (x > y) {

                    ...

            } else {

                    ....

            }

    原因:K&R。

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

                    第三章:命名

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

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

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

    把函數的類型加入到名字中(所謂的匈牙利命名法)是腦損傷的表現
    - 編譯器
    知道類型,能夠對它進行檢查,這種命名法只會把程序員自己搞暈。難怪微軟做
    了那么多充滿bug的程序。

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

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

                    第四章:函數

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

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

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

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

                    第五章:注釋

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

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

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

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

    所以,你或者徹底仍掉GNU
    emacs,或者采用更理智的設置。如果選擇后者,你
    可一把下面的代碼加到你的.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
    命令。當編寫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一樣的腦死亡設置,所以你需要給它一
    些命令行選項。但是,這不算太壞,因為即使是GNU
    indent的作者們也意識到了
    K&R的權威性(GNU的人也不是魔鬼,他們只是在這件事上被誤導了),所以你可
    以使用選項“-kr
    -i8”(表示“K&R,8字符縮進”)運行indent。

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

                    第七章:配置文件

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

    代碼中使用的是3字符縮進,config-選項中應該使用2字符縮進標識依賴關系。
    后者只應用于bool/tristat選項。對于其他選項,采用你認為最合適的縮進方式
    就可以了。例如:

    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

    一般來說,所有不穩定的選項應該標為CONFIG_EXPERIMENTAL。所有可能損壞數
    據的的選項應該標為(DANGEROUS),其他的試驗選項應該標為(EXPERIMENTAL)。

                    第八章:數據結構

    供多線程使用的數據結構應該采用引用計數(reference
    counts)。在內核中,
    垃圾回收(garbage
    collection)是不存在的(內核之外的垃圾回收效率不高),
    這意味著你_必須_使用引用計數。

    引用計數的使用能避免鎖的使用,使不同的用戶能夠并行使用數據結構
    - 不需
    要擔心結構會因為睡眠而突然消失。

    注意到加鎖_不是_引用計數的替代物。加鎖用于保證數據結構的完整性,而引用
    計數是一個內存管理技術。通常你兩個都需要,不應該有任何混淆不清的地方。

    一些數據結構可能使用兩層的引用計數,當對不同的“類”都有使用的時候。子
    類的計數統計所有子類用戶的數目,當子類的計數為零時只對總計數減一。

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

    記?。喝绻硪粋€線程能夠看見你的數據結構,而你卻沒有對它使用引用計數,
    那么幾乎可以肯定會有bug存在。

    posted on 2005-12-02 13:14 ivaneeo 閱讀(606) 評論(0)  編輯  收藏 所屬分類: GNU牛力
    主站蜘蛛池模板: 四虎成年永久免费网站| 国产一级一毛免费黄片| 成人免费a级毛片| 亚洲日韩中文字幕天堂不卡| 色欲色香天天天综合网站免费| 亚洲乱码中文字幕综合 | 日本红怡院亚洲红怡院最新| 2022国内精品免费福利视频| 伊人久久精品亚洲午夜| 岛国精品一区免费视频在线观看| 亚洲中文字幕在线观看| a在线观看免费视频| 亚洲天堂中文字幕| 100部毛片免费全部播放完整| 亚洲影视自拍揄拍愉拍| 免费无码又爽又刺激高潮 | 成人激情免费视频| 亚洲AV女人18毛片水真多| 日本中文一区二区三区亚洲| 中文在线日本免费永久18近| 香蕉蕉亚亚洲aav综合| 真人做人试看60分钟免费视频| 亚洲熟女精品中文字幕| 亚洲VA综合VA国产产VA中| 大地资源网高清在线观看免费 | www.免费在线观看| 亚洲国产精品成人综合色在线| 亚洲AV无码专区日韩| 久久99免费视频| 国产亚洲精aa在线看| 三上悠亚亚洲一区高清| 久久美女网站免费| 亚洲一级视频在线观看| 免费a在线观看播放| 无码午夜成人1000部免费视频| 亚洲五月丁香综合视频| 亚洲一区二区三区在线视频| 亚洲精品免费在线视频| 高潮毛片无遮挡高清免费视频| 亚洲AV第一页国产精品| 国产一区二区三区在线观看免费|