高質量編程規(guī)范PPT參考課件_第1頁
高質量編程規(guī)范PPT參考課件_第2頁
高質量編程規(guī)范PPT參考課件_第3頁
高質量編程規(guī)范PPT參考課件_第4頁
高質量編程規(guī)范PPT參考課件_第5頁
已閱讀5頁,還剩57頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、上章回顧上章回顧哈希函數(shù)的構造方法有那些哈希表中處理沖突的方法有那些高質量編程規(guī)范高質量編程規(guī)范第八章第八章預習檢查預習檢查c語言要經(jīng)歷哪幾個編譯過程如何申請鏈表單元,及釋放鏈表單元實現(xiàn)單鏈表插入的基本語法簡述一下快速排序基本理論要點課程目標課程目標本章概述本章概述闡述如何進行高質量的編程,以及注意事項本章目標本章目標了解高質量編程注意的方方面面從代碼風格,算法,方便調試,性能等。重點重點內存分配與釋放,懸掛指針本章結構本章結構程序員的態(tài)度程序員的態(tài)度高質量編程規(guī)范高質量編程規(guī)范微觀上高質量微觀上高質量宏觀上高質量宏觀上高質量8.1 程序員的態(tài)度程序員的態(tài)度程序員的弱點不太愿意測試自己的代碼

2、不愿意review團隊隊員的代碼程序員重點保證自己的代碼沒有 bug 來 8.1 程序員的態(tài)度程序員的態(tài)度程序員自身可以在程序生成的流程 詳細設計 編寫代碼單元測試 功能測試 代碼 review 8.1.1 編碼的風格編碼的風格版權和版本的申明頭文件的結構定義文件的結構頭文件的作用目錄結構命名規(guī)則注釋規(guī)則/* copyright (c) 2001,上海貝爾有限公司網(wǎng)絡應用事業(yè)部上海貝爾有限公司網(wǎng)絡應用事業(yè)部* all rights reserved.* * 文件名稱:文件名稱:filename.h* 文件標識:文件標識:見配置管理計劃書見配置管理計劃書* 摘摘 要:要:簡要描述本文件的內容簡要

3、描述本文件的內容* * 當前版本:當前版本:1.1* 作作 者:者:輸入作者(或修改者)名字輸入作者(或修改者)名字* 完成日期:完成日期:2001年年7月月20日日* 取代版本:取代版本:1.0 * 原作者原作者 :輸入原作者(或修改者)名字輸入原作者(或修改者)名字* 完成日期:完成日期:2001年年5月月10日日8.1.1.1 版權和版本的申明版權和版本的申明版權和版本的聲明位于頭文件和定義文件的開頭,主要內容有:(1)版權信息。(2)文件名稱,標識符,摘要。(3)當前版本號,作者/修改者,完成日期。(4)版本歷史信息。范例8.1.1.2頭文件的結構頭文件的結構頭文件由三部分內容組成:頭

4、文件開頭處的版權和版本聲明。預處理塊。函數(shù)和類結構聲明等。范例為了防止頭文件被重復引用,應當用ifndef/define/endif結構產(chǎn)生預處理塊。用 #include 格式來引用標準庫的頭文件(編譯器將從標準庫目錄開始搜索)。用 #include “filename.h” 格式來引用非標準庫的頭文件(編譯器將從用戶的工作目錄開始搜索)。頭文件中只存放“聲明”而不存放“定義”不提倡使用全局變量,盡量不要在頭文件中出現(xiàn)象extern int value 這類聲明。8.1.1.3定義文件的結構定義文件的結構定義文件有三部分內容:定義文件開頭處的版權和版本聲明對一些頭文件的引用程序的實現(xiàn)體(包括數(shù)

5、據(jù)和代碼)范例/ 版權和版本聲明版權和版本聲明#include “graphics.h” / 引用頭文件引用頭文件/ 全局函數(shù)的實現(xiàn)體全局函數(shù)的實現(xiàn)體void function1()8.1.1.4 頭文件的作用頭文件的作用通過頭文件來調用庫功能頭文件能加強類型安全檢查8.1.1.5 目錄結構目錄結構特點:便于維護通常應將頭文件和定義文件分別保存于不同的目錄加強信息隱藏:如果某些頭文件是私有的,它不會被用戶的程序直接引用,則沒有必要公開其“聲明”范例: network 工程建立三個目錄 source:存放工程源文件,如:server.c client.c include:存放工程頭文件,如:se

6、rver.h client.h lib:存放工程庫文件,如:tipr.so stdio.so8.1.1.6 命名規(guī)則命名規(guī)則主要思想:在變量和函數(shù)名中加入前綴以增進人們對程序的理解具體規(guī)則:標識符應當直觀且可以拼讀,可望文知意,不必進行“解碼”。標識符的長度應當符合“min-length & max-information”原則命名規(guī)則盡量與所采用的操作系統(tǒng)或開發(fā)工具的風格保持一致程序中不要出現(xiàn)僅靠大小寫區(qū)分的相似的標識符程序中不要出現(xiàn)標識符完全相同的局部變量和全局變量變量的名字應當使用“名詞”或者“形容詞名詞”用正確的反義詞組命名具有互斥意義的變量或相反動作的函數(shù)等8.1.2 程序的

7、版式程序的版式空行代碼行代碼行內的空格代碼對齊長行拆分修飾符的位置注釋8.1.2.1 空行空行空行起著分隔程序段落的作用??招械皿w(不過多也不過少)將使程序的布局更加清晰。空行不會浪費內存空行規(guī)則每個函數(shù)定義結束之后都要加空行在一個函數(shù)體內,邏揖上密切相關的語句之間不加空行,其它地方應加空行分隔。8.1.2.2 代碼行規(guī)則代碼行規(guī)則一行代碼只做一件事情如只定義一個變量,或只寫一條語句。這樣的代碼容易閱讀,并且方便于寫注釋。if、for、while、do等語句自占一行,執(zhí)行語句不得緊跟其后。不論執(zhí)行語句有多少都要加。盡可能在定義變量的同時初始化該變量(就近原則)8.1.2.3 代碼行內的空格代碼

8、行內的空格 關鍵字之后要留空格函數(shù)名之后不要留空格,緊跟左括號(,以與關鍵字區(qū)別(向后緊跟,)、,、;向前緊跟,緊跟處不留空格,之后要留空格二元操作符的前后應當加空格。一元操作符前后不加空格。象“”、“.”、“-”這類操作符前后不加空格。8.1.2.4 對齊和拆分規(guī)則對齊和拆分規(guī)則對齊規(guī)則程序的分界符和應獨占一行并且位于同一列,同時與引用它們的語句左對齊 之內的代碼塊在右邊數(shù)格處左對齊。長行拆分規(guī)則代碼行最大長度宜控制在70至80個字符以內長表達式要在低優(yōu)先級操作符處拆分成新行,操作符放在新行之首(以便突出操作符)。拆分出的新行要進行適當?shù)目s進,使排版整齊,語句可讀8.1.2.5 長行拆分規(guī)則

9、長行拆分規(guī)則 代碼行最大長度宜控制在70至80個字符以內 長表達式要在低優(yōu)先級操作符處拆分成新行,操作符放在新行之首(以便突出操作符) 例:if (very_longer_variable1 = very_longer_variable12)& (very_longer_variable3 = very_longer_variable14)& (very_longer_variable5 = b & c d & c + f = g + h ; 不要有多用途的復合表達式 d = (a = b + c) + r ; 不要把程序中的復合表達式與“真正的數(shù)學表達式”混淆

10、 if (a b c) 與 if (ab) & (b=”或“=-epsinon) & (x=epsinon) 其中epsinon是允許的誤差(即精度)。 8.2.1.3 if語句語句指針變量與零值比較指針變量與零值比較 指針變量用“=”或“!=”與null比較 例子:與零值比較的標準與零值比較的標準if語句如下:語句如下:if (p = null)/ p與與null顯式比較,強調顯式比較,強調p是指針變量是指針變量if (p != null)不要寫成不要寫成if (p = 0) / 容易讓人誤解容易讓人誤解p是整型變量是整型變量if (p != 0) 或者或者 if (p)/

11、容易讓人誤解容易讓人誤解p是布爾變量是布爾變量if (!p)8.2.1.4 使用使用const提高函數(shù)的健壯性提高函數(shù)的健壯性 const 用法:定義常量 修飾函數(shù)的參數(shù) 修飾函數(shù)的返回值 修飾函數(shù)的定義體 8.2.1.4.1 用用const修飾函數(shù)的參數(shù)修飾函數(shù)的參數(shù)const只能修飾輸入?yún)?shù) 特點如果輸入?yún)?shù)采用“指針傳遞”,那么加const修飾可以防止意外地改動該指針,起到保護作用 例:void stringcopy(char *strdestination, const char *strsource); 如果輸入?yún)?shù)采用“引用傳遞 ”, 可以避免修改參數(shù)值的值傳遞void func(

12、const a &a) 8.2.1.4.2 用用const修飾函數(shù)的返回值修飾函數(shù)的返回值 如果給以“指針傳遞”方式的函數(shù)返回值加const修飾,那么函數(shù)返回值(即指針)內容不能被修改例如函數(shù)const char * getstring(void);如下語句將出現(xiàn)編譯錯誤:char *str = getstring();正確的用法是const char *str = getstring();8.3.1 防止內存泄漏防止內存泄漏 內存分配方式 malloc/free 的使用要點 常見的內存錯誤及其對策 引用與指針的比較 指針與數(shù)組的對比 指針參數(shù)是如何傳遞內存的動態(tài)內存自動釋放 杜絕“野

13、指針” 8.3.1.1內存分配方式內存分配方式 內存分配方式有三種:從靜態(tài)存儲區(qū)域分配 在棧上創(chuàng)建 從堆上分配,亦稱動態(tài)內存分配 malloc或new free或delete 8.3.1.2 malloc/free 的使用要點的使用要點 malloc語法:void * malloc(size_t size); 作用:申請一塊長度為length的整數(shù)類型的內存 例子:int *p = (int *) malloc(sizeof(int) * length) free語法:void free( void * memblock ) 作用:釋放內存 例子:free(p)如果p是null指針,那么fre

14、e對p無論操作多少次都不會出問題如果p不是null指針,那么free對p連續(xù)操作兩次就會導致程序運行錯誤。8.3.1.3 常見的內存錯誤及其對策常見的內存錯誤及其對策 常見的內存錯誤 內存分配未成功,卻使用了它 內存分配雖然成功,但是尚未初始化就引用它 內存分配成功并且已經(jīng)初始化,但操作越過了內存的邊界 忘記了釋放內存,造成內存泄露 釋放了內存卻繼續(xù)使用它 8.3.1.3 常見的內存錯誤及其對策常見的內存錯誤及其對策 內存管理的規(guī)則 用malloc之后,應該立即檢查指針值是否為null。防止使用指針值為null的內存。不要忘記為數(shù)組和動態(tài)內存賦初值。防止將未被初始化的內存作為右值使用。避免數(shù)組

15、或指針的下標越界,特別要當心發(fā)生“多1”或者“少1”操作。動態(tài)內存的申請與釋放必須配對,防止內存泄漏。用free釋放了內存之后,立即將指針設置為null,防止產(chǎn)生“野指針”。8.3.1.5 指針與數(shù)組的對比指針與數(shù)組的對比 差別數(shù)組:要么在靜態(tài)存儲區(qū)被創(chuàng)建(如全局數(shù)組),要么在棧上被創(chuàng)建 數(shù)組名對應著(而不是指向)一塊內存其地址與容量在生命期內保持不變只有數(shù)組的內容可以改變 指針:隨時指向任意類型的內存塊 動態(tài)生存在數(shù)據(jù)堆8.3.1.5 指針與數(shù)組的對比指針與數(shù)組的對比 差別內存的容量大小例:1例2char a = hello world; char *p = a; sizeof(a) ?/

16、12字節(jié)字節(jié) sizeof(p) ?/ 4字節(jié)字節(jié) void func(char a100) sizeof(a) ? / 4字節(jié)而不是字節(jié)而不是100字節(jié)字節(jié) 8.3.1.5 指針與數(shù)組的對比指針與數(shù)組的對比 動態(tài)內存會自動釋放 不會自動釋放例:指針應該注意的特性指針消亡了,并不表示它所指的內存會被自動釋放。內存被釋放了,并不表示指針會消亡或者成了null指針。void func(void) char *p = (char *) malloc(100); / 動態(tài)內存會自動釋放嗎?動態(tài)內存會自動釋放嗎? 8.3.1.6 指針參數(shù)是如何傳遞內存的指針參數(shù)是如何傳遞內存的*如果函數(shù)的參數(shù)是一個指針

17、,不要指望用該指針去申請動態(tài)內存如果函數(shù)的參數(shù)是一個指針,不要指望用該指針去申請動態(tài)內存 void getmemory(char *p, int num) p = (char *)malloc(sizeof(char) * num); void test(void) char *str = null; getmemory(str, 100); / str 仍然為仍然為 null strcpy(str, hello);/ 運行錯誤運行錯誤 8.3.1.6 指針參數(shù)是如何傳遞內存的指針參數(shù)是如何傳遞內存的*如果函數(shù)的參數(shù)是一個指針,不要指望用該指針去申請動態(tài)內存如果函數(shù)的參數(shù)是一個指針,不要指望用

18、該指針去申請動態(tài)內存 void getmemory2(char *p, int num) *p = (char *)malloc(sizeof(char) * num); void test(void) char *str = null; getmemory(&str, 100); / str 仍然為仍然為 null strcpy(str, hello);/ 運行錯誤運行錯誤 8.3.1.6 指針參數(shù)是如何傳遞內存的指針參數(shù)是如何傳遞內存的* * * * 不要用不要用returnreturn語句返回指向語句返回指向“棧內存棧內存”的指針的指針 char *getstring(void)

19、 char p = hello world; return p; / 編譯器將提出警告編譯器將提出警告 void test4(void) char *str = null; str = getstring(); / str 的內容是垃圾的內容是垃圾 printf(“%sn”,str ); 8.3.1.7動態(tài)內存自動釋放動態(tài)內存自動釋放 free函數(shù)特點釋放指針所指的內存沒有銷毀指針,故指針地址仍然不變(非null)例: char *p = (char *) malloc(100);strcpy(p, “hello”);free(p); / p 所指的內存被釋放,但是所指的內存被釋放,但是p所指

20、的地址仍然不變所指的地址仍然不變if(p != null) strcpy(p, “world”);/ 出錯出錯 沒有起到?jīng)]有起到防錯作用防錯作用8.3.1.8 杜絕杜絕“野指針野指針” 什么是“野指針”不是null指針是指向“垃圾”內存的指針 if(p!=null)不能起到作用野指針的成因指針變量沒有被初始化 指針初始化:char *p = null;char *str = (char *) malloc(100);指針p被free或者delete之后,沒有置為null 8.3.2 編程的優(yōu)化編程的優(yōu)化為什么需要常量const與#define的比較常量定義規(guī)則循環(huán)語句的效率for語句的循環(huán)控制

21、變量8.3.2.1 為什么用常量為什么用常量常量是一種標識符,它的值在運行期間恒定不變。用 #define來定義常量(稱為宏常量),還可以用const來定義常量為什么要常量程序的可讀性在程序的很多地方輸入同樣的數(shù)字或字符串,難保不發(fā)生書寫錯誤。如果要修改數(shù)字或字符串,則會在很多地方改動,既麻煩又容易出錯。盡量使用含義直觀的常量來表示那些將在程序中多次出現(xiàn)的數(shù)字或字符串。例如:#define max 100/* c語言的宏常量 */ const int max = 100;/ c 語言的const常量const float pi = 3.14159;/ c 語言的const常量8.3.2.2 c

22、onst 與與 #define的比較的比較兩種區(qū)別比較const常量有數(shù)據(jù)類型,而宏常量沒有數(shù)據(jù)類型。編譯器可以對前者進行類型安全檢查。而對后者只進行字符替換,沒有類型安全檢查有些集成化的調試工具可以對const常量進行調試,但是不能對宏常量進行調試。常量定義規(guī)則需要對外公開的常量放在頭文件中,不需要對外公開的常量放在定義文件的頭部為便于管理,可以把不同模塊的常量集中存放在一個公共的頭文件中。如果某一常量與其它常量密切相關,應在定義中包含這種關系,而不應給出一些孤立的值。例如:const float radius = 100;const float diameter = radius * 2;

23、8.3.2.3循環(huán)語句的效率循環(huán)語句的效率在多重循環(huán)中,如果有可能,應當將最長的循環(huán)放在最內層,最短的循環(huán)放在最外層,以減少cpu跨切循環(huán)層的次數(shù)。如果循環(huán)體內存在邏輯判斷,并且循環(huán)次數(shù)很大,宜將邏輯判斷移到循環(huán)體的外面。for (row=0; row100; row+)for ( col=0; col5; col+ )sum = sum + arowcol;if (condition) for (i=0; in; i+) dosomething();else for (i=0; in; i+) dootherthing();8.3.2.4 for語句的循環(huán)控制變量語句的循環(huán)控制變量循環(huán)控制變

24、量規(guī)則不可在for 循環(huán)體內修改循環(huán)變量,防止for 循環(huán)失去控制 建議for語句的循環(huán)控制變量的取值采用“半開半閉區(qū)間”寫法 例子:半開半閉區(qū)間 閉區(qū)間 for (x=0; xn; x+) for (x=0; x=n; x+) ;8.3.2.5 pragma預處理預處理其格式一般為: #pragma para 其中para 為參數(shù),下面來看一些常用的參數(shù)。 #pragma message編譯信息輸出窗口中輸出相應的信息,這對于源代碼信息的控制是非常重要的。其使用方法為:#pragma message(“消息文本”) #pragma once只要在頭文件的最開始加入這條指令就能夠保證頭文件被編譯一次,這條指令實際上在vc6中就已經(jīng)有了,但是考慮到兼容性并沒有太多的使用它。pragma comment(.) 該指令將一個注釋記錄放入一個對象文件或可執(zhí)行文件中。 常用的lib關鍵字,可以幫我們連入一個庫文件。8.3.2.5 pragma預處理預處理#pragma pack() 對

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論