本節書摘來自異步社群《c語言程式設計初學者指南》一書中的第2章,第2.7節,作者【美】keith davenport(達文波特) , m1ichael vine(維恩),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
你的程式就是你本人的一種反射,并且,源代碼應該顯示出一種流暢且一緻的風格,進而引導閱讀者檢視整個算法和程式流程。就像是提供交通功能的橋梁一樣,風格可以讓結構工程師和遊客都感受到其美學價值。
你應該堅持一種讓自己和其他人能夠很容易地閱讀代碼的風格和慣例。一旦你選擇了一種程式設計風格并且習慣了它,重要的是要保持一緻性。換句話說,要堅持它,在同一個程式之中,不要為變量交叉使用命名慣例或者混合使用縮進風格。
在學習如何程式設計的時候,你至少應該專門考慮兩個領域,以開發出一種一緻的程式設計慣例和風格:
空白;
變量命名慣例。
在程式設計的圈子裡,并不經常讨論空白,因為它并不提供計算上的好處。實際上,編譯器會忽略空白,是以,你可以按照自己的意願來處理它。到底什麼是空白呢?打個比方,空白就是你程式設計的畫布。使用不當,它會耗費代碼閱讀者的眼力;使用得當,它能夠變成程式的優點。舉幾個如何控制空白的幾個例子,它們和使用花括号和縮進有關。
縮進是必不可少的,它引導你的視線進入或跳出程式控制。例如,看一下如下這個示例的main()函數,視線會很快告訴你,函數中的代碼從邏輯上就屬于該函數:
關于縮進,經常遇到的一個問題就是制表符和空格之間的争論。這個争論最終以支援空格而很容易地得到了解決。支援空格的背後理論是因為,實際上制表符可以設定為占據不同的列數。當另外一位程式員打開你的代碼的時候,他可能給自己的制表符設定了不同的列數,最終,這會導緻格式不一緻。
對于程式員初學者來說,另一個常見的問題是縮進多遠。我喜歡2個到4個空格的縮進。4個空格以上的縮進,最終可能會導緻一行代碼太長了。這裡的目标是保持一緻的縮進風格,進而使得代碼能夠在計算機螢幕上對齊。
關于空格,還有一件事情需要考慮,這就是花括号的風格,這和縮進的風格密切相關。就像縮進一樣,也有多種不同的花括号風格,盡管你很可能會喜歡如下這種:
又或者是另外一種:
和任何的風格一樣,選擇權在你的手裡,但是,我建議綜合考慮,選擇一種你所習慣的并且能夠和團隊的其他人所使用的風格一緻的風格。在本書中,我針對每個級别的縮進使用4個空格。
如下列出了在聲明和命名變量的時候至少應該遵守的規則:
用一個字首辨別資料類型;
使用合适的大寫字母或小寫字母;
給變量一個有意義的名字。
針對變量名采用一種命名法,這并沒有一種對的方法,盡管有的方法比另一些方法要好。在确定你的命名标準之後,最重要的過程就是,在每一個程式中都要保持一緻的做法。
在後面的幾個小節中,我将向你介紹幾種不同的方法,對我和很多其他采用了上述的規則的程式員來說,這些方法都很有效。
陷阱
除了遵從一緻的變量命名慣例,還要注意,不要在變量名中使用保留字元。作為一條一般性的規則,請遵從如下的建議:
總是以一個小寫字母開始變量名;
在變量名中不要使用空格;
在變量名中,隻使用字母、數字和下劃線(-);
確定變量名少于31個字母,以遵從ansi c标準。
在使用變量的時候,我傾向于選擇3種類型的字首之一,如下所示:
對于每種變量資料類型,我都選擇一個單字元的字首,i(integer的縮寫)、f(float的縮寫)或者c(character的縮寫)。當我在自己的程式代碼中看到如下這3個變量的時候,我立刻知道它們的資料類型是什麼:
即便這些變量并沒有表露出它們的資料類型,當試圖判斷變量的内容類型的時候,你還是可以很容易地從字首中看出來。此外,當和相應的大寫和小寫字母組合使用的時候,這些單字元的字首工作得很好,下一小節将會介紹這一點。
變量中的每個單詞的第一個字母大寫(如下面的代碼所示),這是最常用也是最受歡迎的變量命名慣例:
在每個單詞中使用大寫字母,這使得更容易閱讀變量名并識别其作用。現在來看一下相同名稱的變量,隻不過這一次沒有使用大寫字母:
哪種變量名稱更容易閱讀呢?
除了使用大寫字母增加可讀性,一些程式員喜歡使用下劃線字元來分隔單詞,如下所示:
使用下劃線字元肯定會使得變量名更加可讀,但是,我感覺這有點難看。
常量資料類型為建立标準命名慣例提出了另一個挑戰。我喜歡如下的命名慣例:
在第1個常量聲明中,我使用了const字首表明constweeks是一個常量。然而,注意,我還在常量名中将首字母大寫以保持可讀性。
在第2個聲明中,我直接将常量名中的每一個字母都大寫了。這種命名風格真的很突出。
給變量一個有意義的名稱,這可能是變量命名慣例中最重要的原則。堅持這麼做,可以編寫出自文檔化的代碼。考慮如下的代碼,它使用注釋來描述變量的作用:
上面的變量聲明并沒有使用有意義的名稱,是以,它需要某種形式的文檔(如注釋)來使得代碼的作用更加易于了解。相反,看一下如下的自文檔化的變量名稱:
到目前為止,我們已經學習了如何使用printf()函數将輸出發送到計算機的螢幕。在本節中,我們将學習如何使用scanf()函數從使用者那裡接受輸入。
scanf()是标準輸入輸出庫所提供的另一個内建函數,它從鍵盤讀取标準輸入,并且将其存儲到之前聲明的變量中。它接受兩個參數:
轉換修飾符參數告訴scanf()如何轉化輸入的資料。可以使用和表2.3給出的相同的轉換修飾符。表2.4再次給出和scanf()函數相關的轉換修飾符。
如下的代碼給出了一個完整的c程式,這是一個加法器(adder)程式,它使用scanf()函數讀入兩個整數并且将它們相加。其輸出如圖2.3所示。
圖2.3 使用scanf()接受來自使用者的輸入
第1個printf()函數調用,提示使用者輸入一個數字:
你可能注意到了,上面的printf()函數既沒有在末尾包含一個變量,也沒有在語句的末尾包含一個轉義序列n。當在printf語句的末尾漏掉換行轉義序列的時候,程式控制會在适當的位置暫停,等待使用者輸入。
下面這行代碼使用scanf()函數接受來自使用者的輸入:
scanf()的第1個參數是一個整數轉換修飾符("%d"),它告訴程式将輸入值轉換為一個整數。第2個運算符是一個取址運算符(&),後面跟着變量的名稱。
實際上,這個取址運算符包含了一個指針,指向了變量在記憶體中的位置。我們将在第7章學習關于取址運算符(&)的更多知識,當然也會讨論指針。現在,你隻需要知道在使用scanf()函數的時候,必須在取址運算符之後加上一個變量名。
在一個scanf()函數中,忘記在變量前放置取址運算符(&)并不總是會産生編譯器錯誤,但是,在程式執行的過程中,這總是會導緻記憶體通路的問題。
在從使用者那裡接收到兩個數字(運算數)之後,可以使用一條列印語句來顯示如下的結果。
在這條列印語句中,我包含了一個單個的轉換修飾符(%d),它告訴程式顯示一個單個的整數值。在printf()函數的第2個參數中,我使用加号(+)把使用者輸入的兩個數字加了起來。