開啟主選單

求真百科

代碼揭秘

本書從程序設計角度出發,以C/C++為描述語言,以VisualC++為形式工具,將隱藏在代碼背後的關於計算機組成原理、計算機操作系統等方面的機制和知識娓娓道來,不僅讓讀者知其然,更要讓讀者知其所以然。並讓這些知識再反作用於編程實踐,從而幫助讀者寫出更適合機器優化的高質量代碼。

目錄

圖書信息

書 名:代碼揭秘

作 者:左飛

出 版 社: 電子工業出版社

出版時間: 2009-8-1

頁 數:432頁

開 本: 16開

I S B N :9787121093104

定價:56.00元

內 容 簡 介

本書從程序設計角度出發,以C/C++為描述語言,以VisualC++為形式工具,將隱藏在代碼背後的關於計算機組成原理、計算機操作系統等方面的機制和知識娓娓道來,不僅讓讀者知其然,更要讓讀者知其所以然。並讓這些知識再反作用於編程實踐,從而幫助讀者寫出更適合機器優化的高質量代碼。揭開代碼背後鮮為人知的秘密,具體說來,全書主要討論了包括計算機底層編碼、內存與指針、計算機指令與代碼系統、函數調用的機制、多級存儲系統、線程與進程的概念以及代碼優化等多個方面的話題。

本書既可作為大專院校相關專業師生的教學參考書,也可供計算機及其相關領域的工程技術人員查閱之用,對於普通計算機愛好者,本書也不失為幫助他們理解計算機底層機制的一本深入淺出的計算機讀物。

前 言

算下來這本書應該是我奉獻給讀者的第三本書了。一路寫下來,自己也感覺非常慶幸,慶幸有許多讀者如此地厚愛於我!更高興地看到廣大讀者能夠從我的書里汲取知識,獲得啟迪。在計算機圖書的創作過程中,我不禁感慨:寫一本好書不容易!更何況千里馬常有,而伯樂不常有,能夠讓一本書找到它真正的讀者同樣有難度。因此我寫下了後面的文字,希望這些介紹性的東西能夠幫助讀者理解本書要旨,明確所述內容。

本書緣起

我想有一個問題,很多讀者都非常關心,那就是如何成為一名編程高手。這是以往很多讀者向我寫信討教的話題。關於方法學上的問題本書附錄中談了很多,這裡不再贅述。但是這裡我想告訴讀者的是本書能夠幫助你做些什麼。

通常認為一個計算機程序設計高手應當具備的條件是熟練掌握至少一門計算機程序設計語言,然後有比較紮實的數據結構與算法功底。這樣,基本上他已經可以從一種比較高的視角來抽象現實問題並運用計算機來進行模擬和求解了。但是,這其實還不夠,一個高效的計算機程序需要「內外兼修」。內功就是程序所使用的數據結構和算法,這是決定程序效率的根本因素;而外功就是程序編碼是否符合計算機系統的口味,是否能夠最大程度地調動和運用系統的資源。

這一點的作用是不容忽視的。但是由於目前很多程序員都是半路出家,沒有接受過系統的計算機科學理論教育,因為他們不知道有這麼回事,所以無法給予足夠的重視就無可厚非了。就像古代人們不知道有細菌和病毒的存在,所以那時也就沒有消毒的概念一樣。

另外,我需要指出的是,很多計算機專業科班出身的學生也未必能夠領悟這項「外功」的奧義。就目前中國的計算機教育來說,學校的課程設置僅僅是將各項知識獨立地對待,這樣對於悟性不是非常高的學生來說,在沒有被點化的情況下就沒有辦法有機地將這麼多課程串接起來。一個不能形成完整系統性的知識結構是空洞和脆弱的結構。

國外先進的計算機教育已經注意到了這一點,很多國外的大學都開設了這樣一門從程序設計角度來讓學生真切感受計算機組織機制和原理的課程。慶幸的是,國內很多人也已經意識到了這個問題,所以相關的課程和有關的書籍也在被逐步引入到國內。但是目前存在的一個問題是,原封不動地將國外的課程和教材搬到國內明顯讓這洋學問顯得有點「水土不服」。

這種水土不服主要表現在三個方面。首先,這些書籍往往都是國外大學的教材,這些教材面向專業學生,這無疑將廣大非專業學生和讀者拒之門外了。其次,這些書是以國外大學的情況為參照而寫作的,沒有充分考慮中國的情況——當然,人家幹嘛要考慮呀?這就讓中國讀者學起來非常不順手。比如,某些例子可能是以UNIX或者Linux下的編程為基礎設計的,中國絕大多數使用Windows的讀者就很難完成這些實驗。這極大地打擊了他們繼續學習的積極性和後勁。最後,引進版的書明顯要比實際技術的發展老幾代。現在都是多核時代了,書里可能還在講奔騰2,這就讓中國的讀者只能在後面跟着人家跑,卻永遠沒辦法超越。

核心內容

基於上面的考慮我寫了這樣一本《代碼揭秘》。或許很多人對這個名字感到困惑並充滿疑問,因為直觀上好像不能確定這本書的具體內容是什麼。接下來我就要告訴讀者這本書到底是寫什麼的。本書從程序設計角度出發(因為這是廣大讀者最熟悉、最容易接受的出發點),以C/C++為描述語言(因為這是目前最廣為使用的計算機語言,另外,C/C++中像指針這樣的底層特性也非常適合用來揭示系統深處的東西),以VisualC++為形式工具(因為它也是中國程序員所習慣使用的開發環境),將隱藏在代碼背後的關於計算機組成原理、計算機操作系統等方面的原理和知識娓娓道來,不僅讓讀者知其然,更要讓讀者知其所以然。並讓這些知識再反作用於編程實踐,從而幫助讀者寫出更適合機器優化的高質量代碼。揭開代碼背後鮮為人知的秘密,讓代碼開口說話,告訴你一個真實的計算機,從而讓你能夠寫出適合與計算機交流的優秀代碼,這就是本書所能為你做到的。

讀者對象

接下來我要回答的問題是本書為誰而寫。

如果你是一名渴望在編程技藝上有所精進的程序設計愛好者,那麼這本書就是助你成為編程高手的制勝法寶;

如果你是一名正苦於無法突破編程瓶頸的程序員,那麼這本書就是幫你打通任督二脈的武林秘籍;

如果你是一名感覺書本知識仍然無法內化的計算機專業學生,那麼本書就是替你撥雲開霧、指點迷津的通天燈塔。

閱讀建議

最後,我還希望和讀者談談閱讀及學習本書的建議。

第一,從整體上看全書共分9章,章節之間相關關聯、層層遞進,本着循序漸進的原則逐漸展開,因此閱讀本書時切不可跳躍式地選讀,這樣非但不能領悟整個體系間的精髓,更會為進一步的閱讀帶來困難。特別是第2~7章尤不可拆分閱讀,務必按其順序來學習。

第二,為了幫助讀者理解,書中繪製了大量圖表。這些圖表的作用不可小視,如果在文字理解上遇到困難,可以參照圖表來學習。為了幫助讀者加深理解,書中還設計了大量的實驗,儘管書中給出了實驗結果,但也請讀者務必親自動手實踐一下這些例子,這樣才能讓知識凝固在你的腦中。

第三,本書所涉及的知識面比較廣,在某些時候限於篇幅的考慮而未能把所有問題都展開來深入探究。對於那些並不是非常深入的知識點,如果讀者有興趣,建議讀者多多查閱有關方面的資料,這樣學習才能更加博文通識。

關於本書

排除前期構思和素材準備的時間,本書的寫作時長也將近有一年之久。在這個過程中,筆者力求精益求精,對很多知識點再三推敲,並翻閱了大量資料和文獻。這些工作和努力無非是希望能夠寫一本對得起讀者的書。

在早先的兩本書出版之後,我也收到了許多熱心讀者的來信,一部分人表達了對我作品的充分肯定,這當然是我所樂於見到的,能夠獲得來自讀者的認可對於一個負責任的作者來說無疑是莫大的榮耀。而更多的人則向我問詢了書中的一些問題,主要是他們在閱讀過程中遇到的困難。這也是我非常高興見到的事情,因為這讓我真切地感知到確實有很多人在讀我寫的書。很多讀者同問的一個問題是如何能夠學好編程。為了回答這個問題,我特別撰寫了一篇題為《淺談編程能力的培養與提高》的文章附在本書正文之後,希望對那些仍處在迷茫之中的讀者能夠起到一定的幫助作用。

寫一本好書真的很難,寫一本沒有錯誤的好書更是難如登天。我聞聽計算機科學大師Knuth在《計算機程序設計藝術》叢書出版後也提出如果誰能夠從他書中找到一個錯誤,就能夠獲得256美分的獎勵,事實證明獲得這項獎勵的人還是大有人在的。這也客觀地說明了即使作者很牛,即使作者很用心,書中出現紕漏和欠缺也的確是在所難免的事情,所以我也真心地希望廣大讀者能夠不吝賜教和批評。不過以往的經驗着實有點讓我失望。給我寫信的讀者大有人在,但是指出我書中錯誤的讀者卻寥寥無幾。我想這其中的一個非常重要的原因在於中國的教育更多地是讓我們學會一味接受,而非大膽地思辨!我們太過盲從而迷信權威,只會聆聽高人教誨,卻不想自己思考。這對於學習來說不是一個好現象。古人云:盡信書則不如無書。我也希望廣大讀者能夠以思辨的態度來看書,這樣你將會獲得更多。如果在這個過程中,讀者有什麼感想或者問題希望和作者交流的。

最後誠摯地祝願每位讀者都能夠真正感受到編程的快樂,並在編程的路上行得更穩健,走得更長遠!

目 錄

第1章 緒論 1

1.1 計算機系統初探 2

1.1.1 換個角度看計算機 2

1.1.2 CPU很好很強大 4

1.2 計算機語言與編譯技術 ¬8

1.2.1 如何讓機器理解你 8

1.2.2 編譯技術與開發環境 14

1.2.3 程序開發流程 20

1.3 C語言神話 22

1.3.1 C語言的歷史 22

1.3.2 簡單說說C語言的特點 23

1.4 奇蹟的延續 25

1.4.1 C++的產生與發展 25

1.4.2 C++與面向對象思想 27

1.5 本章小結 31

第2章 揭開數據表示的面紗 32

2.1 進制系統 33

2.1.1 最簡單的計數方式 33

2.1.2 計算機里只有黑白 34

2.1.3 壓縮表示的二進制 36

2.2 位與位操作 38

2.2.1 計算機存儲的單位 38

2.2.2 位操作和位段 39

2.3 計算機中的數值 48

2.3.1 一種最簡單的數 48

2.3.2 現實世界需要負數 49

2.3.3 只有整數還不夠 51

2.4 讓計算機學會寫字 56

2.4.1 ASCII碼 57

2.4.2 漢字編碼 59

2.4.3 更強大的編碼 60

2.5 C語言基本數據類型 62

2.5.1 整型 63

2.5.2 字符型 66

2.5.3 注意浮點數陷阱 67

2.6 本章小結 71

第3章 變量與地址 72

3.1 程序都在內存中 73

3.2 很多初學者都怕指針 77

3.3 睜大眼睛看內存 81

3.4 數組與指針是近親 84

3.5 再談指針 93

3.6 本章小結 97

第4章 動態內存管理 98

4.1 malloc和free 99

4.2 sizeof並不複雜 101

4.3 內存操作函數 105

4.3.1 memset 105

4.3.2 memcpy和memmove 107

4.4 new和delete 109

4.5 內存錯誤面面觀 113

4.5.1 最怕內存泄漏 113

4.5.2 小心重複釋放 115

4.5.3 指針是個壞東西 117

4.5.4 超量寫內存 118

4.6 使用Visual C++檢查內存泄漏 120

4.7 本章小結 124

第5章 代碼與指令系統 125

5.1 還原代碼的本來面目 126

5.1.1 內存中的代碼 126

5.1.2 指向函數的指針 131

5.1.3 CPU的存儲器 136

5.1.4 寄存器變量 143

5.1.5 寄存器組舉例 145

5.2 指令——簡單or複雜 149

5.2.1 指令格式 149

5.2.2 操作類型 154

5.2.3 操作數類型 155

5.3 如何找到地址 156

5.3.1 下一步該做什麼 156

5.3.2 計算機知道自己需要什麼 165

5.4 本章小結 172

第6章 函數與函數調用 173

6.1 函數與參數 174

6.1.1 C/C++中的函數 174

6.1.2 參數傳遞 174

6.1.3 作用域 180

6.2 函數的遞歸調用 184

6.2.1 到處都是遞歸 184

6.2.2 小心使用遞歸 188

6.2.3 遞歸與非遞歸 194

6.2.4 內、外部變量分配原理 198

6.3 內存的使用 200

6.3.1 活動記錄與棧 200

6.3.2 靜態分配 203

6.3.3 有靜就有動 205

6.4 程序在內存中的模樣 217

6.5 本章小結 219

第7章 多級存儲系統 221

7.1 存儲系統及層級結構 222

7.1.1 存儲器分類 222

7.1.2 存儲器的層級結構 225

7.1.3 訪問的局部性原理 227

7.1.4 再談存儲器的層級 231

7.2 高速緩存 235

7.2.1 緩存設計策略 235

7.2.2 多級緩存原理 245

7.2.3 實際編碼指導 250

7.3 虛擬內存 258

7.3.1 何為虛擬內存 259

7.3.2 虛擬地址 262

7.3.3 頁面請求與磁盤緩衝 269

7.3.4 工作集合與系統顛簸 274

7.3.5 虛擬內存與性能影響 276

7.4 本章小結 278

第8章 操作系統交互 279

8.1 多任務 280

8.1.1 串行與並行 280

8.1.2 多任務的實現 282

8.1.3 並發程序設計 283

8.2 進程 284

8.2.1 進程的概念 284

8.2.2 進程的狀態 285

8.2.3 進程控制塊 288

8.3 Win32進程編程 289

8.3.1 創建進程 289

8.3.2 環境變量 299

8.4 線程 301

8.4.1 線程的概念 301

8.4.2 多線程 302

8.4.3 超線程 303

8.4.4 線程池 304

8.5 調度 305

8.5.1 處理器的調度 305

8.5.2 調度算法準則 306

8.5.3 常見的調度算法 308

8.6 Win32線程編程 313

8.6.1 創建和退出線程 313

8.6.2 掛起和恢複線程 317

8.6.3 遠程線程的注入 320

8.7 本章小結 329

第9章 瓶頸與優化 330

9.1 優化還是不優化 331

9.2 測量與分析的內容 333

9.3 測量與分析的方法 334

9.3.1 使用計時器 334

9.3.2 使用Profile 341

9.3.3 使用性能監視器 349

9.4 基本規律 350

9.4.1 二八法則 350

9.4.2 安達爾定律 351

9.5 程序優化路線 354

9.5.1 優化實踐的經典案例 354

9.5.2 優化案例的啟示 355

9.6 編譯器不是萬能的 357

9.7 實際優化建議 360

9.7.1 循環條件中的低效 361

9.7.2 注意字符串的操作 363

9.7.3 權衡函數調用需求 364

9.7.4 轉換指針形式代碼 366

9.7.5 檢查存儲器的訪問 367

9.7.6 使用循環展開技術 372

9.7.7 查表替換複雜運算 375

9.7.8 耗時計算移出循環 377

9.8 本章小結 378

附錄A 淺談編程能力的培養與提高 379

附錄B 程序人生 397

參考文獻 414[1]

參考文獻