《程式設計實踐》第一章編碼風格的不完全總結

来源:https://www.cnblogs.com/gental/archive/2018/04/19/8871280.html
-Advertisement-
Play Games

名字 全局變數使用描述性的名字,局部變數則使用簡潔的名字。根據定義,全局變數可以出現在整個程式中的任何地方,因此他們需要一個足夠長並且詳細描述的名字讓讀者想起它們的意義。給每個全局變數聲明附加一個簡短註釋也非常有幫助: 全局函數、類和結構應該也要有描述性的名字,以表明它們在程式里扮演的角色。對於局部 ...


名字

全局變數使用描述性的名字,局部變數則使用簡潔的名字。根據定義,全局變數可以出現在整個程式中的任何地方,因此他們需要一個足夠長並且詳細描述的名字讓讀者想起它們的意義。給每個全局變數聲明附加一個簡短註釋也非常有幫助:

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

全局函數、類和結構應該也要有描述性的名字,以表明它們在程式里扮演的角色。
對於局部變數使用簡短的名字就夠了。在函數里,n 可能就足夠了,npoints 也還可以,用 numberOfPoints 就太過分了。
按常規方式使用的局部變數可以採用極短的名字。例如用 i、j 作為迴圈變數,p、q 作為指針,s、t 表示字元串等。比較:

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

to

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

對返回布爾值的函數命名,應該清楚地反映其返回值情況。因此

    if (checkoctal(c)) ...

沒有表明哪一個返回值是真,哪一個是假,而:

     if (isoctal(c)) ...

說清楚瞭如果參數是八進位數字則該函數返回真,否則為假。

表達式和語句

使用自然的表達式。含有否定運算的條件表達式比較難以理解:

    if (!(block_id < actblks) || !(block_id >= unblocks))

在兩個測試中都用到了否定運算,有點多餘。應該改變關係運算符的方向:

    if ((block_id >= actblks) || !(block_id < unblocks))

現在代碼讀起來就自然多了。

用括弧解決歧義

    leap_year = y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
    leap_year = ((y%4 == 0) && (y%100 != O)) || (y%400 == 0);

去掉了一些空格:將高優先順序運算符的操作數聚合在一起,幫助讀者更快地看清表達式的結構。

要清晰。程式員有時把自己無盡的創造力用到了儘可能地寫最簡短的代碼,或者尋求巧妙方法去得到一個結果。有時這種技能被誤用了,因為我們的目標是寫出清晰的代碼,而不是巧妙的代碼。

運算符 ?: 適用於簡短的表達式,這時它可以把4行的 if-else 程式變成1行。例如這樣:

    max = (a > b) ? a : b;

當心副作用。 I/O 操作有時會帶來難以發現的問題。下麵的例子希望從標準輸入讀入兩個相關聯的數:

    scanf("%d %d", &yr, &profit[yr]);

你可能認為答案依賴於參數的求值順序,但是實際上傳入 scanf 的所有參數在函數被調用前就已經計算好了,所以 &profit[yr] 實際使用的是舊的 yr 。解決辦法是把語句分解為兩個:

    scanf("%d", &yr);
    scanf("%d", &profit[yr]);

一致性和習慣用法

如果你在一個之前不是你寫的程式上開發,應該保留程式原有的風格。即使你更喜歡你自己的風格,當你需要做修改時,也不要使用。程式的一致性比你個人的習慣更重要,對於後續跟進的人來說更方便。

函數巨集

函數巨集最常見的一個嚴重問題是:如果一個參數在定義中出現多次,它就可能被多次求值。如果調用時的實際參數帶有副作用,結果就會產生一個難以捉摸的錯誤。
下麵的代碼段來自<ctype.h>,其意圖是實現對一個字元的測試:

    #define isupper(c) ((c) >= 'A' && (c) <= 'Z')

如果 isupper 被這樣子中調用:

    while (isupper(c = getchar()))

getchar()函數會被調用兩次,那麼,每當遇到一個大於等於 A 的字元,程式就會將它丟掉,而下一個字元將被讀入並去與 Z 做比較,從而導致難以預料的後果。

既然巨集的缺點在很大程度上蓋過了它的優點,使用過程一不小心還會引入問題,那麼我們該在何時使用巨集呢?答案如下:

    //計算出數組的元素個數
    #define NELEMS(array) sizeof(array)/sizeof(array[0])

    double dbuf[100];
    for (i = 0; i < NELEMS(dbuf); i++)
       ...

在這裡,數組大小隻在一個地方設置。如果數組的大小改變,其餘代碼都不必改動。對函數參數的多次求值在這裡也不會出問題,因為它不會出現任何副作用.事實上,這個計算在程式編譯時就已經做完了。這是巨集的一個恰當使用,因為它做了某種函數無法完成的工作,從數組聲明計算出它的大小。

魔術數字

給魔術數字命名。魔術數字包括各種常數、數組的大小、字元位置等等。除了 0 和 1 之外,程式里出現的任何數大概都可以算是魔術數字,它們應該有自己的名字。

把數字定義為常數,不要定義為巨集。C 程式員的傳統方式是用 #define 行來對付神秘的數值。使用巨集進行編程是一種危險的方式,因為巨集會在背地裡改變程式的詞法結構,我們應該讓語言去做正確的工作 。在 C 和 C++ 里,整數常數可以用枚舉語句定義。在 C++ 里任何類型都可使用 const 聲明的常數:

    const int MACROW = 24, MAXCOL = 80;

在 Java 中可以用 final 聲明:

    static final int MACROW = 24, MAXCOL = 80;

C 語言里也有 const 值,但它們不能用作數組的邊界。所以 enum 語句仍然是在 C 裡面可選用的方法。

與此類似的還有另一個問題,那就是程式里許多上下文中經常出現的 0。雖然編譯系統會把它轉換為適當類型,但是,如果我們把每個 0 的類型寫得更明確更清楚,對讀程式的人理解其作用是很有幫助的。例如,用 (v o i d \*) 0 或 NULL 表示 C 里的空指針值,用 ‘\0’ 而不是 0 表示字元串結尾的空位元組。也就是說不要寫成:

    str = 0;
    name[i] = 0;
    x = 0;

應該寫成:

    str = NULL;
    name[i] = "\n";
    x = 0;

註釋

當你改變代碼的時候,一定要註意保證對應的註釋是準確的。

 



以上就是我在閱讀完《程式設計實踐》第一章後做的一些筆記和總結,也算是個人博客的開篇,歡迎交流。




您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 關於java傳值的一點小細節:java語言中對象傳遞地址,而不是引用。 例如:假設對象Test有name的屬性。 public void call(Test){ Test t2 = new Test(); t2.setName("cba"); t.setName("abc"); t=12; } pu ...
  • Pycharm強大的功能總是讓我很是著迷,比如它的makemigrations 和 migrate。 然而某一次,當我再次敲下這熟悉的命令時,它報錯了。。。。 不想看上邊的朋友我還截了個大圖。 錯誤是:django.db.migrations.exceptions.InconsistentMigra ...
  • 在spring中採用tx方式配置 <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="synch*" propagation="REQUIRED" re ...
  • 簡單地總結就一句話: Python2的mysql庫為:mysqldb,而Python3的為:pymysql。 當我們使用Pycharm開發項目時,首先需要下載安裝相對應的資料庫,以及在項目根目錄下的setting.py文件中連接資料庫,代碼如下: (我用的框架是Django) 值得註意的是:如果你是 ...
  • 前言 在 "上一篇" 中回顧了Java的三大特性:封裝、繼承和多態。本篇則來介紹下集合。 集合介紹 我們在進行Java程式開發的時候,除了最常用的基礎數據類型和String對象外,也經常會用到集合相關類。 集合類存放的都是對象的引用,而非對象本身,出於表達上的便利,我們稱集合中的對象就是指集合中對象 ...
  • 章節:enote筆記語言(3) what&why(why not)&how&when&where&which:紫色,象徵著神秘而又潛蘊著強大的力量,故取紫色。 key&keyword:“2k”和以上的“5w1h”合稱為“5w1h2k分析法”。棕色,大地泥土的顏色,給人一種朴實無華而又穩重可靠的感覺, ...
  • 模塊初始 sys模塊 import sys sys.path #列印環境變數 sys.argv#列印該文件路徑 #註意:該文件名字不能跟導入模塊名字相同 os模塊 import os cmd_res = os.system("dir")#只執行system命令,不保存結果,返回一個值0代表執行成功, ...
  • 上一篇我們已經創建好了一個Xadmin的基礎項目,現在我們將在此基礎上構建一個同樣很基礎的學生信息管理系統。 一、創建模型 模型是表示我們的資料庫表或集合類,並且其中所述類的每個屬性是表或集合的欄位,在 app/models.py 中定義。 1、首先,導入models模塊 接下來創建個學生信息類,其 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...