|
-- 會員 / 註冊 --
|
|
|
|
編寫高質量代碼:改善C程序代碼的125個建議 ( 簡體 字) |
作者:馬偉 | 類別:1. -> 程式設計 -> C -> C |
譯者: |
出版社:機械工業出版社 | 3dWoo書號: 43236 詢問書籍請說出此書號!【缺書】 【不接受訂購】 |
出版日:1/1/2016 |
頁數:449 |
光碟數:0 |
|
站長推薦: |
印刷:黑白印刷 | 語系: ( 簡體 版 ) |
|
【不接受訂購】 | ISBN:9787111524342 |
作者序 | 譯者序 | 前言 | 內容簡介 | 目錄 | 序 |
(簡體書上所述之下載連結耗時費功, 恕不適用在台灣, 若讀者需要請自行嘗試, 恕不保證) |
作者序: |
譯者序: |
前言: |
內容簡介:本書是一本關于C最佳實踐的集大成之作,它從C語言本身、C程序的架構設計和思想、C程序的編碼規范和習慣等三大方面對125個經典的問題給出了解決方案,為C開發者提高開發效率和編寫高質量的C代碼提供了寶貴的建議。對于每一個建議,作者不僅給出了被實踐證明為比較優秀的解決方案,而且還給出了被誤用或被錯誤理解的不好的解決方案,形成了鮮明對比。
|
目錄:第1章 數據,程序設計之根本 1 建議1:認識ANSI C 1 建議2:防止整數類型產生回繞與溢出 6 建議2-1:char類型變量的值應該限制在signed char與unsigned char的交集范圍內 11 建議2-2:使用顯式聲明為signed char或unsigned char的類型來執行算術運算 11 建議2-3:使用rsize_t或size_t類型來表示一個對象所占用空間的整數值單位 13 建議2-4:禁止把size_t類型和它所代表的真實類型混用 16 建議2-5:小心使用無符號類型帶來的陷阱 16 建議2-6:防止無符號整數回繞 19 建議2-7:防止有符號整數溢出 24 建議3:盡量少使用浮點類型 28 建議3-1:了解IEEE 754浮點數 29 建議3-2:避免使用浮點數進行精確計算 39 建議3-3:使用分數來精確表達浮點數 43 建議3-4:避免直接在浮點數中使用“==”操作符做相等判斷 47 建議3-5:避免使用浮點數作為循環計數器 50 建議3-6:盡量將浮點運算中的整數轉換為浮點數 51 建議4:數據類型轉換必須做范圍檢查 52 建議4-1:整數轉換為新類型時必須做范圍檢查 53 建議4-2:浮點數轉換為新類型時必須做范圍檢查 56 建議5:使用有嚴格定義的數據類型 57 建議6:使用typedef來定義類型的新別名 61 建議6-1:掌握typedef的4種應用形式 61 建議6-2:小心使用typedef帶來的陷阱 65 建議6-3:typedef不同于#define 65 建議7:變量聲明應該力求簡潔 66 建議7-1:盡量不要在一個聲明中聲明超過一個的變量 67 建議7-2:避免在嵌套的代碼塊之間使用相同的變量名 68 建議8:正確地選擇變量的存儲類型 68 建議8-1:定義局部變量時應該省略auto關鍵字 69 建議8-2:慎用extern聲明外部變量 70 建議8-3:不要混淆static變量的作用 72 建議8-4:盡量少使用register變量 75 建議9:盡量不要在可重入函數中使用靜態(或全局)變量 76 建議10:盡量少使用全局變量 78 建議11:盡量使用const聲明值不會改變的變量 78 第2章 保持嚴謹的程序設計,一切從表達式開始做起 81 建議12:盡量減少使用除法運算與求模運算 81 建議12-1:用倒數相乘來實現除法運算 82 建議12-2:使用牛頓迭代法求除數的倒數 84 建議12-3:用減法運算來實現整數除法運算 86 建議12-4:用移位運算實現乘除法運算 86 建議12-5:盡量將浮點除法轉化為相應的整數除法運算 87 建議13:保證除法和求模運算不會導致除零錯誤 87 建議14:適當地使用位操作來提高計算效率 88 建議14-1:盡量避免對未知的有符號數執行位操作 89 建議14-2:在右移中合理地選擇0或符號位來填充空出的位 90 建議14-3:移位的數量必須大于等于0且小于操作數的位數 90 建議14-4:盡量避免在同一個數據上執行位操作與算術運算 91 建議15:避免操作符混淆 92 建議15-1:避免“=”與“==”混淆 92 建議15-2:避免“|”與“||”混淆 94 建議15-3:避免“&”與“&&”混淆 95 建議16:表達式的設計應該兼顧效率與可讀性 95 建議16-1:盡量使用復合賦值運算符 95 建議16-2:盡量避免編寫多用途的、太復雜的復合表達式 97 建議16-3:盡量避免在表達式中使用默認的優先級 98 第3章 程序控制語句應該保持簡潔高效 101 建議17:if語句應該盡量保持簡潔,減少嵌套的層數 101 建議17-1:先處理正常情況,再處理異常情況 101 建議17-2:避免“懸掛”的else 102 建議17-3:避免在if/else語句后面添加分號“;” 105 建議17-4:對深層嵌套的if語句進行重構 106 建議18:謹慎0值比較 108 建議18-1:避免布爾型與0或1進行比較 108 建議18-2:整型變量應該直接與0進行比較 109 建議18-3:避免浮點變量用“==”或“!=”與0進行比較 109 建議18-4:指針變量應該用“==”或“!=”與NULL進行比較 111 建議19:避免使用嵌套的“?:” 111 建議20:正確使用for循環 114 建議20-1:盡量使循環控制變量的取值采用半開半閉區間寫法 114 建議20-2:盡量使循環體內工作量達到最小化 115 建議20-3:避免在循環體內修改循環變量 115 建議20-4:盡量使邏輯判斷語句置于循環語句外層 116 建議20-5:盡量將多重循環中最長的循環放在最內層,最短的循環放在最外層 117 建議20-6:盡量將循環嵌套控制在3 層以內 117 建議21:適當地使用并行代碼來優化for循環 117 建議22:謹慎使用do/while與while循環 118 建議22-1:無限循環優先選用for( ; ; ),而不是while(1) 118 建議22-2:優先使用for循環替代do/while與while循環 119 建議23:正確地使用switch語句 120 建議23-1:不要忘記在case 語句的結尾添加break語句 120 建議23-2:不要忘記在switch語句的結尾添加default語句 122 建議23-3:不要為了使用case 語句而刻意構造一個變量 122 建議23-4:盡量將長的switch語句轉換為嵌套的switch語句 123 建議24:選擇合理的case語句排序方法 124 建議24-1:盡量按照字母或數字順序來排列各條case 語句 124 建議24-2:盡量將情況正常的case 語句排在最前面 125 建議24-3:盡量根據發生頻率來排列各條case 語句 125 建議25:盡量避免使用goto語句 125 建議26:區別continue與break語句 127 第4章 函數同樣需要保持簡潔高效 129 建議27:理解函數聲明 129 建議28:理解函數原型 131 建議29:盡量使函數的功能單一 132 建議30:避免把沒有關聯的語句放在一個函數中 135 建議31:函數的抽象級別應該在同一層次 136 建議32:盡可能為簡單功能編寫函數 137 建議33:避免多段代碼重復做同一件事情 138 建議34:盡量避免編寫不可重入函數 140 建議34-1:避免在函數中使用static 局部變量 140 建議34-2:避免函數返回指向靜態數據的指針 140 建議34-3:避免調用任何不可重入函數 142 建議34-4:對于全局變量,應通過互斥信號量(即P、V操作)或者中斷機制等方法來保證函數的線程安全 143 建議34-5:理解可重入函數與線程安全函數之間的關系 144 建議35:盡量避免設計多參數函數 145 建議35-1:沒有參數的函數必須使用void填充 145 建議35-2:盡量避免在非調度函數中使用控制參數 147 建議35-3:避免將函數的參數作為工作變量 148 建議35-4:使用const防止指針類型的輸入參數在函數體內被意外修改 149 建議36:沒有返回值的函數應聲明為void類型 149 建議37:確保函數體的“入口”與“出口”安全性 150 建議37-1:盡量在函數體入口處對參數做有效性檢查 150 建議37-2:盡量在函數體出口處對return語句做安全性檢查 151 建議38:在調用函數時,必須對返回值進行判斷,同時對錯誤的返回值還要有相應的錯誤處理 152 建議39:盡量減少函數本身或者函數間的遞歸調用 153 建議40:盡量使用inline內聯函數來替代#define宏 154 第5章 不會使用指針的程序員是不合格的 157 建議41:理解指針變量的存儲實質 157 建議42:指針變量必須初始化 162 建議43:區別“int *p = NULL” 和“*p = NULL” 163 建議44:理解空(null)指針與NULL指針 164 建議44-1:區別空(null)指針與NULL指針的概念 164 建議44-2:用NULL指針終止對遞歸數據結構的間接引用 166 建議44-3:用NULL指針作函數調用失敗時的返回值 169 建議44-4:用NULL指針作警戒值 170 建議44-5:避免對NULL指針進行解引用 170 建議45:謹慎使用void指針 171 建議45-1:避免對void指針進行算術操作 172 建議45-2:如果函數的參數可以是任意類型指針,應該將其參數聲明為void * 173 建議46:避免使用指針的長度確定它所指向類型的長度 175 建議47:避免把指針轉換為對齊要求更嚴格的指針類型 176 建議48:避免將一種類型的操作符應用于另一種不兼容的類型 177 建議49:謹慎指針與整數之間的轉換 180 建議50:區別“const int *p”與“int *const p” 180 建議51:深入理解函數參數的傳遞方式 183 建議51-1:理解函數參數的傳遞過程 183 建議51-2:掌握函數的參數傳遞方式 188 建議51-3:如果函數的參數是指針,避免用該指針去申請動態內存 191 建議51-4:盡量避免使用可變參數 195 第6章 數組并非指針 199 建議52:理解數組的存儲實質 199 建議52-1:理解數組的存儲布局 199 建議52-2:理解&a[0]和&a的區別 203 建議52-3:理解數組名a作為右值和左值的區別 203 建議53:避免數組越界 204 建議53-1:盡量顯式地指定數組的邊界 207 建議53-2:對數組做越界檢查,確保索引值位于合法的范圍之內 209 建議53-3:獲取數組的長度時不要對指針應用sizeof操作符 210 建議54:數組并非指針 213 建議55:理解數組與指針的可交換性 217 建議56:禁止將一個指向非數組對象的指針加上或減去一個整數 219 建議57:禁止對兩個并不指向同一個數組的指針進行相減或比較 220 建議58:若結果值并不引用合法的數組元素,不要將指針加上或減去一個整數 220 建議59:細說緩沖區溢出 220 建議60:區別指針數組和數組指針 226 建議61:深入理解數組參數 227 第7章 結構、位域和枚舉 231 建議62:結構體的設計要遵循簡單、單一原則 231 建議62-1:盡量使結構體的功能單一 232 建議62-2:盡量減小結構體間關系的復雜度 234 建議62-3:盡量使結構體中元素的個數適中 235 建議62-4:合理劃分與改進結構體以提高空間效率 236 建議63:合理利用結構體內存對齊原理來提高程序效率 237 建議64:結構體的長度不一定等于各個成員的長度之和 249 建議65:避免在結構體之間執行逐字節比較 250 建議66:謹慎使用位域 251 建議67:謹慎使用枚舉 252 建議68:禁止在位域成員上調用offsetof宏 254 建議69:深入理解結構體數組和結構體指針 255 第8章 字符與字符串 260 建議70:不要忽視字符串的null(\0)結尾符 260 建議70-1:正確認識字符數組和字符串 261 建議70-2:字符數組必須能夠同時容納字符數據和null結尾符 262 建議70-3:謹慎字符數組的初始化 263 建議71:盡量使用const指針來引用字符串常量 264 建議72:區別strlen函數與sizeof運算符 264 建議73:在使用不受限制的字符串函數時,必須保證結果字符串不會溢出內存 265 建議73-1:避免字符串拷貝發生溢出 266 建議73-2:區別串拷貝strcpy與內存拷貝memcpy 270 建議73-3:避免strcpy與memcpy函數內存重疊 273 建議73-4:區別字符串比較與內存比較 278 建議73-5:避免strcat函數發生內存重疊與溢出 283 建議74:謹慎strtok函數的不可重入性 287 建議75:掌握字符串查找技術 292 建議75-1:使用strchr與strrchr函數查找單個字符 292 建議75-2:使用strpbrk函數查找多個字符 293 建議75-3:使用strstr函數查找一個子串 294 建議75-4:區別strspn與strcspn函數 295 第9章 文件系統 298 建議76:謹慎使用printf和scanf 函數 299 建議77:謹慎文件打開操作 308 建議77-1:正確指定fopen的mode參數 309 建議77-2:必須檢查fopen函數的返回值 310 建議77-3:盡量避免重復打開已經被打開的文件 311 建議77-4:區別fopen與fopen_s函數 312 建議77-5:區別fopen與freopen函數 313 建議78:文件操作完成后必須關閉 313 建議79:正確理解EOF宏 314 建議80:盡量使用feof和ferror檢測文件結束和錯誤 316 建議81:盡量使用fgets替換gets函數 319 建議82:盡量使用fputs替換puts函數 321 建議83:合理選擇單個字符讀寫函數 323 建議84:區別格式化讀寫函數 324 建議84-1:區別printf/scanf、fprintf/fscanf和sprintf/sscanf 325 建議84-2:盡量使用snprintf替代sprintf函數 327 建議84-3:區別vprintf/vscanf、vfprintf/vfscanf 、vsprintf/vsscanf和vsnprintf 328 建議85:盡量使用fread與fwrite函數來讀寫二進制文件 330 建議86:盡量使用fseek替換rewind函數 332 建議87:盡量使用setvbuf替換setbuf函數 334 建議88:謹慎remove函數刪除已打開的文件 336 建議89:謹慎rename函數重命名已經存在的文件 337 第10章 預處理器 338 建議90:謹慎宏定義 338 建議90-1:在使用宏定義表達式時必須使用完備的括號 339 建議90-2:盡量消除宏的副作用 340 建議90-3:避免使用宏創建一種“新語言” 342 建議91:合理地選擇函數與宏 343 建議92:盡量使用內聯函數代替宏 345 建議93:掌握預定義宏 350 建議94:謹慎使用“#include” 353 建議94-1:區別“#include ”與“#include "filename.h" ” 354 建議94-2:必須保證頭文件名稱的唯一性 355 建議95:掌握條件編譯指令 355 建議95-1:使用“#ifndef/#define/#endif”防止頭文件被重復引用 355 建議95-2:使用條件編譯指令實現源代碼的部分編譯 357 建議95-3:妙用“defined” 358 建議96:盡量避免在一個函數塊中單獨使用“#define”或“#undef” 359 第11章 斷言與異常處理 361 建議97:謹慎使用斷言 361 建議97-1:盡量利用斷言來提高代碼的可測試性 362 建議97-2:盡量在函數中使用斷言來檢查參數的合法性 367 建議97-3:避免在斷言表達式中使用改變環境的語句 368 建議97-4:避免使用斷言去檢查程序錯誤 369 建議97-5:盡量在防錯性程序設計中使用斷言來進行錯誤報警 370 建議97-6:用斷言保證沒有定義的特性或功能不被使用 372 建議97-7:謹慎使用斷言對程序開發環境中的假設進行檢查 373 建議98:謹慎使用errno 374 建議98-1:調用errno之前必須先將其清零 375 建議98-2:避免重定義errno 377 建議98-3:避免使用errno檢查文件流錯誤 379 建議99:謹慎使用函數的返回值來標志函數是否執行成功 380 建議100:盡量避免使用goto進行出錯跳轉 380 建議101:盡量避免使用setjmp與longjmp組合 381 第12章 內存管理 384 建議102:淺談程序的內存結構 384 建議103:淺談堆和棧 389 建議104:避免錯誤分配內存 396 建議104-1:對內存分配函數的返回值必須進行檢查 397 建議104-2:內存資源的分配與釋放應該限定在同一模塊或者同一抽象層內進行 398 建議104-3:必須對內存分配函數的返回指針進行強制類型轉換 400 建議104-4:確保指針指向一塊合法的內存 401 建議104-5:確保為對象分配足夠的內存空間 402 建議104-6:禁止執行零長度的內存分配 405 建議104-7:避免大型的堆棧分配 405 建議104-8:避免內存分配成功,但并未初始化 407 建議105:確保安全釋放內存 407 建議105-1:malloc等內存分配函數與free必須配對使用 407 建議105-2:在free之后必須為指針賦一個新值 409 建議106:避免內存越界 411 建議106-1:避免數組越界 412 建議106-2:避免sprintf、vsprintf、strcpy、strcat與gets越界 413 建議106-3:避免memcpy與memset函數長度越界 413 建議106-4:避免忽略字符串最后的\0字符而導致的越界 413 建議107:避免內存泄漏 415 建議108:避免calloc參數相乘的值超過size_t表示的范圍 417 第13章 信號處理 418 建議109:理解信號 418 建議110:盡量使用sigaction替代signal 423 建議111:避免在信號處理函數內部訪問或修改共享對象 428 建議112:避免以遞歸方式調用raise函數 429 第14章 了解C11標準 432 建議113:謹慎使用_Generic 433 建議114:盡量使用gets_s替換gets函數 436 建議115:盡量使用帶邊界檢查的字符串操作函數 436 建議116:了解C11多線程編程 438 建議117:使用靜態斷言_Static_assert執行編譯時檢查 442 建議118:使用_Noreturn標識不返回值的函數 442 第15章 保持良好的設計 443 建議119:避免錯誤地變量初始化 443 建議120:謹慎使用內聯函數 444 建議121:避免在函數內定義占用內存很大的局部變量 445 建議122:謹慎設計函數參數的順序和個數 446 建議123:謹慎使用標準函數庫 447 建議124:避免不必要的函數調用 447 建議125:謹慎程序中嵌入匯編代碼 448 |
序: |
|