全新修訂的《C 23高級編程》(第6版)延續(xù)經(jīng)典之作的深厚底蘊,由資深軟件工程師Marc Gregoire執(zhí)筆撰寫,再次為高階編程指南樹立新標桿。本書幾乎涵蓋代號為C 23的新標準的所有特性,并通過經(jīng)Windows與Linux平臺測試的大量實戰(zhàn)代碼案例,提供深入、透徹的解析。
C 的功能極其廣泛,是游戲和商業(yè)軟件中最流行的高級程序設計語言之一。然而,無法回避的事實是:C 十分復雜,難以掌握。《C 23高級編程(第6版)》將讓C 專業(yè)人員能跟上最新的發(fā)展潮流,保持技術領先。
高效進階C :
一本助你快速精通C 知識的權(quán)威指南
作為追求卓越的C 開發(fā)者的首選資源,本書助你實現(xiàn)以下目標。
● 精通C 23最新特性:精準掌握C 23新標準
● 最大化C 潛能:通過高效設計方案釋放性能
● 規(guī)避開發(fā)陷阱:揭示冷門知識點與常見反模式
● 測試與調(diào)試之道:學習行業(yè)最佳實踐
● 性能調(diào)優(yōu)秘籍:掌握提升效率的關鍵技巧
技術領袖力薦
李建忠、吳詠煒、高博、錢能、朱燕民、吳天明、楊文波、郭龍江、王雷聯(lián)袂推薦!C 頭部自媒體程序喵大人領銜翻譯 。
唯一全面覆蓋C 23新特性:
深入解析模塊(import std)、std::println格式化輸出、范圍庫、協(xié)程等新標準,代碼示例均基于C 23重構(gòu)。
現(xiàn)代C 實踐指南:
摒棄傳統(tǒng)C 風格代碼,倡導智能指針、范圍循環(huán)、結(jié)構(gòu)化綁定等現(xiàn)代范式,提供零歷史包袱的學習路徑。
案例驅(qū)動教學:
通過跨平臺(Windows/Linux)測試的實戰(zhàn)代碼,詳解高性能程序設計、內(nèi)存管理陷阱及并發(fā)編程技巧。
工程方法論全覆蓋:
獨有章節(jié)探討軟件生命周期管理(敏捷/瀑布模型)、單元測試、調(diào)試技術(內(nèi)存泄漏檢測)、設計模式(工廠/觀察者模式)。
??
性能優(yōu)化秘籍:
專章剖析性能瓶頸定位(gprof/Visual Studio剖析器)、高效緩存策略、對象池技術等工業(yè)級調(diào)優(yōu)方案。
配套AI編程資源:
附贈《Vibe Coding 浪潮下的 C 》文檔、源代碼、附錄(面試指南/UML圖解), 掃描封底二維碼獲取。
推 薦 序 一
給《C 20高級編程(第5版)》寫了推薦序后,時隔3年,我很高興看到更新版的《C 23高級編程》問世了。
本書延續(xù)之前版本備受贊譽的優(yōu)點,是一本真正從程序員視角出發(fā)、專為程序員量身打造的實用教材,能幫助初、中級C 程序員全面提升其C 專業(yè)技能。作者以深厚的專業(yè)功底和豐富的一線編程經(jīng)驗,精心打造了這本佳作,提供了完整的到C 23為止的C 語言介紹,從入門語法、高級技巧到軟件工程,做了全方位、無死角的介紹,每個知識點都講解得細致入微。無論你想系統(tǒng)學習C ,還是要找其中某些語法點的參考資料,都將收獲實實在在的幫助。
與某些C 教材不同,本書不是簡單地在以前的版本上打個小補丁出來賣錢,而是根據(jù)當前C 標準(C 23)進行了全面更新。從最基本的Hello World程序,讀者就能看到與傳統(tǒng)的C 程序的不同:代碼使用了import std和std::println這兩個新特性,而非使用#include和std::cout。而后面討論較新特性的時候,也莫不如此,比如,幾乎處處可以看到模塊和println。類似地,另外一些較新的C 特性(如C 17的string_view和結(jié)構(gòu)化綁定,C 20的三向比較運算符,等等),也較早得到介紹,并在書中多次出現(xiàn)。如果你新學C 的話,可不帶歷史包袱地看到一門現(xiàn)代的高性能編程語言。如果你之前學過一點C ,也可細細品味現(xiàn)代C 帶來的不同,特別是模塊引入后對代碼組織產(chǎn)生的巨大影響。
既然是個新版本,中文書名里又有C 23,本書當然要重點描述C 23的特性。除了標準庫模塊和print/println,C 23的主要新特性如顯式對象參數(shù)、mdspan和Unicode表示改進書里也都進行了介紹。在描述C 23特性時,書的側(cè)邊通常會出現(xiàn)特殊的帶圈C 23標記,非常清晰。
本書的英文主書名與上一版相同,都是Professional C ,自然,它希望你能專業(yè)地對待C 編程。本書的內(nèi)容編排也十分合理。
第I部分包括三章,以較短篇幅介紹了C 的主要語法和功能,讓你快速上手C 。
第II部分的三章不講語言了,轉(zhuǎn)而講軟件設計。畢竟,我們使用C 的目的是設計出好的軟件。寫程序不是工作目的。
第III部分是本書的重點,介紹C 編碼方法。該部分占了全書的大部分章節(jié)和篇幅,具體講解C 中的各個重要特性和庫。日常用到的絕大部分功能,都會在這一部分講到,如內(nèi)存管理、基本模板、泛型、錯誤處理、容器、時間工具等。
第IV部分較為簡短,有三章,描述了一些高級技巧,仍然是C 的技術內(nèi)容。
第V部分又超越了C 語言本身,用了整整7章的篇幅討論C 項目的軟件工程問題,從軟件生命周期、測試、調(diào)試、設計模式等各個角度進行探討。這一部分的廣度大于深度,對于項目經(jīng)驗不多的程序員來說,尤其有用。
要說我對這本書有什么意見的話,最主要就是作者對廣度的追求了。對于某些不推薦(如bind)或不常用的特性,作者仍有所著墨;而對另一些內(nèi)容(如協(xié)程),作者只是一帶而過。因為某些特性不常用,描述中也容易發(fā)生問題,如14.8.3節(jié)的function-try-blocks例子中包含錯誤行為,29.3.2節(jié)的launder例子也有更簡單的寫法。不過,這也是作者自己的定位選擇吧。此外,作者給出的建議里,至少有一項我持保留意見:作者建議把非final類的構(gòu)造函數(shù)以外的方法全部設為virtual這個建議,從我對C 的理解看,也許能適用于某些領域,但絕非放之四海皆準。事實上,標準庫的類沒有一個標成final,只有少數(shù)類中用到了virtual。
無論如何,作為一本中級教材,本書的表現(xiàn)堪稱出色。作者的絕大部分建議都極具實用性和可靠性。相信隨著學習程度的加深,讀者自會有能力去辨別和領悟其中的精妙之處。
好書要有好的翻譯。本書的譯者有兩位我打過交道,都是熱心于C 知識傳播的年輕才俊。初覽譯稿,便感受到內(nèi)容相當清晰曉暢,對于這么厚重的一本大塊頭教材,也是殊為不易了。在此衷心盼望廣大C 學習者都能從此書中受益,成長為更優(yōu)秀的C 程序員。
吳詠煒
Boolan首席技術咨詢師
《C 實戰(zhàn):核心技術與最佳實踐》作者
Marc Gregoire是一位軟件項目經(jīng)理/軟件架構(gòu)師,深耕C/C 開發(fā),尤精Microsoft VC 及MFC框架,擁有開發(fā)724小時運行于Windows和Linux平臺的C 程序的經(jīng)驗(如KNX/EIB家庭自動化軟件)。除了C/C ,Marc也擅長C#。
Marc是比利時C 用戶組創(chuàng)始人,暢銷技術圖書Professional C (第2~6版)的作者,C Standard Library Quick Reference(第1~2版)的共同作者,多家出版社多部技術書籍的特約編輯,CppCon C 大會常駐演講嘉賓,CodeGuru論壇成員(用戶名:Marc G)。自2007年以來,他憑借在Visual C 領域的技術影響力,連續(xù)十多年榮獲微軟MVP年度獎項。
Marc畢業(yè)于比利時魯汶大學,先后獲得計算機科學工程碩士學位和AI專業(yè)的高級碩士學位。職業(yè)生涯初期,Marc加入比利時軟件咨詢公司Ordina,擔任技術顧問,主導開發(fā)Siemens 和Nokia Siemens Networks面向電信運營商的關鍵2G/3G系統(tǒng) (基于Solaris平臺),項目團隊橫跨南美、美國、歐洲、中東、非洲及亞洲多地。Marc現(xiàn)任職于精密光學儀器與工業(yè)檢測技術領軍企業(yè)尼康計量(Nikon Metrology),負責X射線、CT及三維幾何檢測領域的軟件架構(gòu)設計與項目管理。
第I部分 專業(yè)的C 簡介
第1章 C 和標準庫速成 3
1.1 C 速成 3
1.1.1 小程序Hello World 4
1.1.2 命名空間 8
1.1.3 字面量 10
1.1.4 變量 11
1.1.5 運算符 15
1.1.6 枚舉 17
1.1.7 結(jié)構(gòu)體 19
1.1.8 條件語句 20
1.1.9 條件運算符 22
1.1.10 邏輯比較運算符 23
1.1.11 三向比較運算符 24
1.1.12 函數(shù) 25
1.1.13 屬性 27
1.1.14 C風格的數(shù)組 30
1.1.15 std::array 31
1.1.16 std::vector 32
1.1.17 std::pair 32
1.1.18 std::optional 33
1.1.19 結(jié)構(gòu)化綁定 34
1.1.20 循環(huán) 34
1.1.21 初始化列表 36
1.1.22 C 中的字符串 36
1.1.23 作為面向?qū)ο笳Z言的C 36
1.1.24 作用域解析 40
1.1.25 統(tǒng)一初始化 41
1.1.26 指針和動態(tài)內(nèi)存 44
1.1.27 const的用法 47
1.1.28 引用 50
1.1.29 const_cast() 58
1.1.30 異常 59
1.1.31 類型別名 60
1.1.32 類型定義 61
1.1.33 類型推斷 61
1.1.34 標準庫 64
1.2 第一個大型的C 程序 64
1.2.1 雇員記錄系統(tǒng) 64
1.2.2 Employee類 64
1.2.3 Database類 68
1.2.4 用戶界面 70
1.2.5 評估程序 72
1.3 本章小結(jié) 73
1.4 練習 73
第2章 使用字符串和字符串視圖 74
2.1 動態(tài)字符串 74
2.1.1 C風格字符串 74
2.1.2 字符串字面量 76
2.1.3 C std::string類 78
2.1.4 數(shù)值轉(zhuǎn)換 82
2.1.5 std::string_view類 85
2.1.6 非標準字符串 87
2.2 字符串格式化與打印 87
2.2.1 格式字符串 88
2.2.2 參數(shù)索引 89
2.2.3 打印到不同的目的地 89
2.2.4 格式字符串的編譯期驗證 90
2.2.5 格式說明符 91
2.2.6 格式化轉(zhuǎn)義字符和字符串 94
2.2.7 格式化范圍 94
2.2.8 支持自定義類型 96
2.3 本章小結(jié) 99
2.4 練習 99
第3章 編碼風格 101
3.1 良好外觀的重要性 101
3.1.1 事先考慮 101
3.1.2 良好風格的元素 102
3.2 為代碼編寫文檔 102
3.2.1 使用注釋的原因 102
3.2.2 注釋的風格 106
3.3 分解 109
3.3.1 通過重構(gòu)分解 110
3.3.2 通過設計分解 111
3.3.3 本書中的分解 111
3.4 命名 111
3.4.1 選擇恰當?shù)拿Q 111
3.4.2 命名約定 112
3.5 使用具有風格的語言特性 113
3.5.1 使用常量 114
3.5.2 使用引用代替指針 114
3.5.3 使用自定義異常 115
3.6 格式 115
3.6.1 關于大括號對齊的爭論 115
3.6.2 關于空格和圓括號的爭論 116
3.6.3 空格、制表符、換行符 117
3.7 風格的挑戰(zhàn) 117
3.8 本章小結(jié) 117
3.9 練習 118
第II部分 專業(yè)的C 軟件設計
第4章 設計專業(yè)的C 程序 123
4.1 程序設計概述 123
4.2 程序設計的重要性 124
4.3 C 設計 126
4.4 C 設計的兩個原則 126
4.4.1 抽象 126
4.4.2 重用 128
4.5 重用現(xiàn)有代碼 130
4.5.1 關于術語的說明 130
4.5.2 決定是否重用代碼 130
4.5.3 重用代碼的指導原則 132
4.6 設計一個國際象棋程序 137
4.6.1 需求 137
4.6.2 設計步驟 138
4.7 本章小結(jié) 143
4.8 練習 143
第5章 面向?qū)ο笤O計 145
5.1 過程化的思考方式 145
5.2 面向?qū)ο笏枷?146
5.2.1 類 146
5.2.2 組件 146
5.2.3 屬性 147
5.2.4 行為 147
5.2.5 綜合考慮 147
5.3 生活在類的世界里 148
5.3.1 過度使用類 148
5.3.2 過于通用的類 149
5.4 類之間的關系 150
5.4.1 有一個關系 150
5.4.2 是一個關系(繼承) 150
5.4.3 有一個與是一個的區(qū)別 152
5.4.4 not-a關系 155
5.4.5 層次結(jié)構(gòu) 155
5.4.6 多重繼承 156
5.4.7 混入類 157
5.5 本章小結(jié) 158
5.6 練習 158
第6章 設計可重用代碼 160
6.1 重用哲學 160
6.2 如何設計可重用代碼 161
6.2.1 使用抽象 161
6.2.2 構(gòu)建理想的重用代碼 162
6.2.3 設計有用的接口 168
6.2.4 設計成功的抽象 173
6.2.5 SOLID原則 174
6.3 本章小結(jié) 174
6.4 練習 175
第III部分 C 編碼方法
第7章 內(nèi)存管理 179
7.1 使用動態(tài)內(nèi)存 180
7.1.1 如何描繪內(nèi)存 180
7.1.2 分配和釋放 181
7.1.3 數(shù)組 183
7.1.4 使用指針 189
7.2 數(shù)組-指針的對偶性 190
7.2.1 數(shù)組退化為指針 190
7.2.2 并非所有指針都是數(shù)組 192
7.3 底層內(nèi)存操作 192
7.3.1 指針運算 192
7.3.2 自定義內(nèi)存管理 193
7.3.3 垃圾回收 194
7.3.4 對象池 194
7.4 常見的內(nèi)存陷阱 194
7.4.1 數(shù)據(jù)緩沖區(qū)分配不足以及內(nèi)存訪問越界 194
7.4.2 內(nèi)存泄漏 196
7.4.3 雙重釋放和無效指針 198
7.5 智能指針 199
7.5.1 unique_ptr 199
7.5.2 shared_ptr 202
7.5.3 weak_ptr 205
7.5.4 向函數(shù)傳遞參數(shù) 206
7.5.5 從函數(shù)中返回 206
7.5.6 enable_shared_from_this 207
7.5.7 智能指針與C風格函數(shù)的交互 207
7.5.8 過時的、移除的auto_ptr 208
7.6 本章小結(jié) 208
7.7 練習 208
第8章 熟悉類和對象 210
8.1 電子表格示例介紹 210
8.2 編寫類 211
8.2.1 類定義 211
8.2.2 定義方法 213
8.2.3 使用對象 215
8.2.4 this指針 217
8.2.5 顯式對象參數(shù) 218
8.3 對象的生命周期 218
8.3.1 創(chuàng)建對象 218
8.3.2 銷毀對象 233
8.3.3 對象賦值 234
8.3.4 編譯器生成的拷貝構(gòu)造函數(shù)和拷貝賦值運算符 237
8.3.5 復制和賦值的區(qū)別 237
8.4 本章小結(jié) 238
8.5 練習 239
第9章 精通類和對象 240
9.1 友元 240
9.2 對象中的動態(tài)內(nèi)存分配 241
9.2.1 Spreadsheet類 241
9.2.2 使用析構(gòu)函數(shù)釋放內(nèi)存 244
9.2.3 處理復制和賦值 245
9.2.4 使用移動語義處理移動 250
9.2.5 零規(guī)則 260
9.3 與成員函數(shù)有關的更多內(nèi)容 261
9.3.1 static成員函數(shù) 261
9.3.2 const成員函數(shù) 262
9.3.3 成員函數(shù)重載 263
9.3.4 內(nèi)聯(lián)成員函數(shù) 267
9.3.5 默認參數(shù) 268
9.4 constexpr與consteval 269
9.4.1 constexpr關鍵字 269
9.4.2 consteval關鍵字 270
9.4.3 constexpr 和 consteval 類 271
9.5 不同的數(shù)據(jù)成員類型 272
9.5.1 靜態(tài)數(shù)據(jù)成員 272
9.5.2 const static數(shù)據(jù)成員 274
9.5.3 引用數(shù)據(jù)成員 274
9.6 嵌套類 276
9.7 類內(nèi)的枚舉類型 277
9.8 運算符重載 277
9.8.1 示例:為SpreadsheetCell實現(xiàn)加法 278
9.8.2 重載算術運算符 281
9.8.3 重載比較運算符 282
9.9 創(chuàng)建穩(wěn)定的接口 286
9.10 本章小結(jié) 289
9.11 練習 290
第10章 揭秘繼承技術 291
10.1 使用繼承構(gòu)建類 291
10.1.1 擴展類 292
10.1.2 重寫成員函數(shù) 295
10.2 使用繼承重用代碼 302
10.2.1 WeatherPrediction類 302
10.2.2 在派生類中添加功能 303
10.2.3 在派生類中替換功能 304
10.3 利用父類 305
10.3.1 父類構(gòu)造函數(shù) 305
10.3.2 父類的析構(gòu)函數(shù) 306
10.3.3 構(gòu)造函數(shù)和析構(gòu)函數(shù)中的虛成員函數(shù)調(diào)用 307
10.3.4 使用父類成員函數(shù) 308
10.3.5 向上轉(zhuǎn)型和向下轉(zhuǎn)型 310
10.4 繼承與多態(tài)性 311
10.4.1 回到電子表格 311
10.4.2 設計多態(tài)性的電子表格單元格 311
10.4.3 SpreadsheetCell基類 312
10.4.4 獨立的派生類 313
10.4.5 利用多態(tài)性 315
10.4.6 考慮將來 316
10.4.7 提供純虛成員函數(shù)的實現(xiàn) 317
10.5 多重繼承 318
10.5.1 從多個類繼承 318
10.5.2 名稱沖突和歧義基類 319
10.6 有趣而晦澀的繼承問題 321
10.6.1 修改重寫成員函數(shù)的返回類型 322
10.6.2 派生類中添加虛基類成員函數(shù)的重載 324
10.6.3 繼承的構(gòu)造函數(shù) 325
10.6.4 重寫成員函數(shù)時的特殊情況 328
10.6.5 派生類中的拷貝構(gòu)造函數(shù)和賦值運算符 334
10.6.6 運行時類型工具 335
10.6.7 非public繼承 337
10.6.8 虛基類 337
10.7 類型轉(zhuǎn)換 340
10.7.1 static_cast() 340
10.7.2 reinterpret_cast() 341
10.7.3 dynamic_cast() 342
10.7.4 std::bit_cast() 343
10.7.5 類型轉(zhuǎn)換小結(jié) 343
10.8 本章小結(jié) 344
10.9 練習 344
第11章 模塊、頭文件和其他主題 345
11.1 模塊 345
11.1.1 非模塊化代碼 346
11.1.2 標準命名模塊 346
11.1.3 模塊接口文件 347
11.1.4 模塊實現(xiàn)文件 348
11.1.5 從實現(xiàn)中分離接口 349
11.1.6 可見性和可訪問性 350
11.1.7 子模塊 350
11.1.8 模塊劃分 351
11.1.9 私有模塊片段 353
11.1.10 頭文件單元 355
11.1.11 可導入的標準庫頭文件 355
11.2 預處理指令 357
11.3 鏈接 358
11.3.1 內(nèi)部鏈接 359
11.3.2 extern 關鍵字 360
11.4 頭文件 361
11.4.1 單一定義規(guī)則(ODR) 361
11.4.2 重復定義 361
11.4.3 循環(huán)依賴 362
11.4.4 查詢頭文件是否存在 363
11.4.5 模塊導入聲明 363
11.5 核心語言特性的特性測試宏 363
11.6 static關鍵字 364
11.6.1 靜態(tài)數(shù)據(jù)成員和成員函數(shù) 364
11.6.2 函數(shù)中的靜態(tài)變量 364
11.6.3 非局部變量的初始化順序 365
11.6.4 非局部變量的銷毀順序 365
11.7 C 風格的可變長度參數(shù)列表 365
11.7.1 訪問參數(shù) 366
11.7.2 為什么不應該使用C風格的變長參數(shù)列表 367
11.8 本章小結(jié) 367
11.9 練習 367
第12章 利用模板編寫泛型代碼 369
12.1 模板概述 370
12.2 類模板 370
12.2.1 編寫類模板 370
12.2.2 編譯器處理模板的原理 378
12.2.3 將模板代碼分布到多個文件中 379
12.2.4 模板參數(shù) 380
12.2.5 成員函數(shù)模板 383
12.2.6 類模板的特化 389
12.2.7 從類模板派生 391
12.2.8 繼承還是特化 392
12.2.9 模板別名 392
12.3 函數(shù)模板 393
12.3.1 函數(shù)重載與函數(shù)模板 394
12.3.2 函數(shù)模板的重載 394
12.3.3 類模板的友元函數(shù)模板 395
12.3.4 對模板參數(shù)推導的更多介紹 397
12.3.5 函數(shù)模板的返回類型 397
12.3.6 簡化函數(shù)模板的語法 399
12.4 變量模板 399
12.5 概念 400
12.5.1 語法 400
12.5.2 約束表達式 401
12.5.3 預定義的標準概念 403
12.5.4 類型約束的auto 404
12.5.5 類型約束和函數(shù)模板 404
12.5.6 類型約束和類模板 407
12.5.7 類型約束和類成員函數(shù) 407
12.5.8 基于約束的類模板特化和函數(shù)模板重載 408
12.5.9 最佳實踐 408
12.6 本章小結(jié) 409
12.7 練習 409
第13章 C I/O揭秘 410
13.1 使用流 411
13.1.1 流的含義 411
13.1.2 流的來源和目的地 412
13.1.3 流式輸出 412
13.1.4 流式輸入 417
13.1.5 對象的輸入輸出 423
13.1.6 自定義的操作算子 424
13.2 字符串流 425
13.3 基于span的流 426
13.4 文件流 427
13.4.1 文本模式與二進制模式 428
13.4.2 通過seek()和tell()在文件中轉(zhuǎn)移 428
13.4.3 將流鏈接在一起 430
13.4.4 讀取整個文件 431
13.5 雙向I/O 431
13.6 文件系統(tǒng)支持庫 432
13.6.1 路徑 432
13.6.2 目錄條目 434
13.6.3 輔助函數(shù) 434
13.6.4 目錄遍歷 434
13.7 本章小結(jié) 435
13.8 練習 436
第14章 錯誤處理 437
14.1 錯誤與異常 437
14.1.1 異常的含義 438
14.1.2 C 中異常的優(yōu)點 438
14.1.3 建議 439
14.2 異常機制 439
14.2.1 拋出和捕獲異常 440
14.2.2 異常類型 442
14.2.3 按const引用捕獲異常對象 443
14.2.4 拋出并捕獲多個異常 443
14.2.5 未捕獲的異常 446
14.2.6 noexcept說明符 447
14.2.7 noexcept(expression)說明符 448
14.2.8 noexcept(expression)運算符 448
14.2.9 拋出列表 448
14.3 異常與多態(tài)性 449
14.3.1 標準異常層次結(jié)構(gòu) 449
14.3.2 在類層次結(jié)構(gòu)中捕獲異常 450
14.3.3 編寫自己的異常類 451
14.3.4 嵌套異常 453
14.4 重新拋出異常 455
14.5 棧的釋放與清理 456
14.5.1 使用智能指針 458
14.5.2 捕獲、清理并重新拋出 458
14.6 源碼位置 459
14.6.1 日志記錄的源碼位置 459
14.6.2 在自定義異常中自動嵌入源位置 460
14.7 堆棧跟蹤 461
14.7.1 堆棧跟蹤庫 461
14.7.2 在自定義異常中自動嵌入堆棧跟蹤 462
14.8 常見的錯誤處理問題 464
14.8.1 內(nèi)存分配錯誤 464
14.8.2 構(gòu)造函數(shù)中的錯誤 466
14.8.3 構(gòu)造函數(shù)的function-try-blocks 468
14.8.4 析構(gòu)函數(shù)中的錯誤 470
14.9 異常安全保證 471
14.10 本章小結(jié) 471
14.11 練習 471
第15章 C 運算符重載 473
15.1 運算符重載概述 473
15.1.1 重載運算符的原因 474
15.1.2 運算符重載的限制 474
15.1.3 運算符重載的選擇 474
15.1.4 不應重載的運算符 476
15.1.5 可重載運算符小結(jié) 476
15.1.6 右值引用 479
15.1.7 優(yōu)先級和結(jié)合性 480
15.1.8 關系運算符 481
15.1.9 替代符號 481
15.2 重載算術運算符 482
15.2.1 重載一元負號和一元正號運算符 482
15.2.2 重載遞增和遞減運算符 482
15.3 重載按位運算符和二元邏輯運算符 483
15.4 重載插入運算符和提取運算符 483
15.5 重載下標運算符 485
15.5.1 通過operator[]提供只讀訪問 488
15.5.2 多維下標運算符 489
15.5.3 非整數(shù)數(shù)組索引 490
15.5.4 靜態(tài)下標運算符 490
15.6 重載函數(shù)調(diào)用運算符 491
15.7 重載解除引用運算符 492
15.7.1 實現(xiàn)operator* 494
15.7.2 實現(xiàn)operator-> 494
15.7.3 operator.*和operator ->*的含義 494
15.8 編寫轉(zhuǎn)換運算符 495
15.8.1 auto運算符 496
15.8.2 使用顯式轉(zhuǎn)換運算符解決多義性問題 496
15.8.3 用于布爾表達式的轉(zhuǎn)換 497
15.9 重載內(nèi)存分配和內(nèi)存釋放運算符 498
15.9.1 new和delete的工作原理 499
15.9.2 重載operator new和operator delete 500
15.9.3 顯式地刪除/默認化operator new和operator delete 502
15.9.4 重載帶有額外參數(shù)的operator new和operator delete 502
15.9.5 重載帶有內(nèi)存大小參數(shù)的operator delete 503
15.10 重載用戶定義的字面量運算符 504
15.10.1 標準庫定義的字面量 504
15.10.2 用戶自定義的字面量 504
15.11 本章小結(jié) 506
15.12 練習 506
第16章 C 標準庫概述 508
16.1 編碼原則 509
16.1.1 使用模板 509
16.1.2 使用運算符重載 509
16.2 C 標準庫概述 509
16.2.1 字符串 509
16.2.2 正則表達式 510
16.2.3 I/O流 510
16.2.4 智能指針 510
16.2.5 異常 510
16.2.6 標準整數(shù)類型 511
16.2.7 數(shù)學工具 511
16.2.8 整數(shù)比較 512
16.2.9 位操作 512
16.2.10 時間和日期工具 513
16.2.11 隨機數(shù) 513
16.2.12 初始化列表 513
16.2.13 Pair和Tuple 513
16.2.14 詞匯類型 513
16.2.15 函數(shù)對象 514
16.2.16 文件系統(tǒng) 514
16.2.17 多線程 514
16.2.18 類型萃取 514
16.2.19 標準庫特性測試宏 514
16.2.20 515
16.2.21 源位置 516
16.2.22 堆棧跟蹤 516
16.2.23 容器 516
16.2.24 算法 522
16.2.25 范圍庫 529
16.2.26 標準庫中還缺什么 530
16.3 本章小結(jié) 530
16.4 練習 530
第17章 理解迭代器與范圍庫 532
17.1 迭代器 532
17.1.1 獲取容器的迭代器 534
17.1.2 迭代器萃取 536
17.1.3 示例 536
17.1.4 使用迭代器特性進行函數(shù)分發(fā) 537
17.2 流迭代器 539
17.2.1 輸出流迭代器:ostream_iterator 539
17.2.2 輸入流迭代器:istream_iterator 540
17.2.3 輸入流迭代器:istreambuf_iterator 540
17.3 迭代器適配器 540
17.3.1 插入迭代器 541
17.3.2 逆向迭代器 542
17.3.3 移動迭代器 543
17.4 范圍 544
17.4.1 約束算法 545
17.4.2 視圖 547
17.4.3 范圍工廠 552
17.4.4 將范圍轉(zhuǎn)換為容器 554
17.5 本章小結(jié) 555
17.6 練習 556
第18章 標準庫容器 557
18.1 容器概述 557
18.1.1 對元素的要求 558
18.1.2 異常和錯誤檢查 559
18.2 順序容器 559
18.2.1 vector 560
18.2.2 vector特化 578
18.2.3 deque 578
18.2.4 list 579
18.2.5 forward_list 581
18.2.6 array 584
18.3 順序視圖 585
18.3.1 span 585
18.3.2 mdspan 587
18.4 容器適配器 588
18.4.1 queue 588
18.4.2 priority_queue 591
18.4.3 stack 593
18.5 關聯(lián)容器 593
18.5.1 有序關聯(lián)容器 594
18.5.2 無序關聯(lián)容器/哈希表 607
18.5.3 平坦集合和平坦映射關聯(lián)容器適配器 613
18.5.4 關聯(lián)容器的性能 614
18.6 其他容器 614
18.6.1 標準C風格數(shù)組 614
18.6.2 string 615
18.6.3 流 615
18.6.4 bitset 616
18.7 本章小結(jié) 620
18.8 練習 620
第19章 函數(shù)指針、函數(shù)對象、lambda表達式 622
19.1 函數(shù)指針 622
19.1.1 findMatches()?使用函數(shù)指針 623
19.1.2 findMatches()?函數(shù)模板 624
19.1.3 Windows DLL和函數(shù)指針 625
19.2 指向成員函數(shù)(和數(shù)據(jù)成員)的指針 626
19.3 函數(shù)對象 627
19.3.1 編寫第一個函數(shù)對象 627
19.3.2 標準庫中的函數(shù)對象 627
19.4 多態(tài)功能包裝器 634
19.4.1 std::function 634
19.4.2 std::move_only_function 635
19.5 lambda表達式 636
19.5.1 語法 636
19.5.2 lambda表達式作為參數(shù) 640
19.5.3 泛型lambda表達式 641
19.5.4 lambda捕獲表達式 641
19.5.5 模板化lambda表達式 642
19.5.6 lambda 表達式作為返回類型 643
19.5.7 未計算上下文中的lambda表達式 643
19.5.8 默認構(gòu)造、拷貝和賦值 643
19.5.9 遞歸lambda表達式 644
19.6 調(diào)用 644
19.7 本章小結(jié) 645
19.8 練習 645
第20章 掌握標準庫算法 647
20.1 算法概述 647
20.1.1 find() 和 find_if() 算法 648
20.1.2 accumulate() 算法 650
20.1.3 在算法中使用移動語義 651
20.1.4 算法回調(diào) 651
20.2 算法詳解 652
20.2.1 非修改序列算法 652
20.2.2 修改序列算法 657
20.2.3 操作算法 665
20.2.4 分區(qū)算法 667
20.2.5 排序算法 668
20.2.6 二分查找算法 669
20.2.7 集合算法 670
20.2.8 最小/最大算法 672
20.2.9 并行算法 673
20.2.10 數(shù)值處理算法 674
20.2.11 約束算法 676
20.3 本章小結(jié) 678
20.4 練習 678
第21章 字符串的本地化與正則表達式 680
21.1 本地化 680
21.1.1 寬字符 680
21.1.2 非西方字符集 681
21.1.3 本地化字符串字面量 683
21.1.4 locale和facet 683
21.2 正則表達式 688
21.2.1 ECMAScript語法 689
21.2.2 regex庫 693
21.2.3 regex_match() 694
21.2.4 regex_search() 696
21.2.5 regex_iterator 697
21.2.6 regex_token_iterator 698
21.2.7 regex_replace() 700
21.3 本章小結(jié) 702
21.4 練習 702
第22章 日期和時間工具 704
22.1 編譯期有理數(shù) 704
22.2 持續(xù)時間 706
22.2.1 示例與duration轉(zhuǎn)換 707
22.2.2 預定義的duration 709
22.2.3 標準字面量 710
22.2.4 hh_mm_ss 710
22.3 時鐘 710
22.3.1 打印當前時間 711
22.3.2 執(zhí)行時間 712
22.4 時間點 712
22.5 日期 714
22.5.1 創(chuàng)建日期 714
22.5.2 打印日期 716
22.5.3 日期運算 717
22.6 時區(qū) 717
22.7 本章小結(jié) 718
22.8 練習 719
第23章 隨機數(shù)工具 720
23.1 C風格隨機數(shù)生成器 720
23.2 隨機數(shù)引擎 721
23.3 隨機數(shù)引擎適配器 722
23.4 預定義的隨機數(shù)引擎和引擎適配器 723
23.5 生成隨機數(shù) 723
23.6 隨機數(shù)分布 725
23.7 本章小結(jié) 728
23.8 練習 728
第24章 其他詞匯類型 729
24.1 variant 729
24.2 any 731
24.3 元組 732
24.3.1 分解元組 734
24.3.2 串聯(lián) 735
24.3.3 比較 736
24.3.4 make_from_tuple() 737
24.3.5 apply() 737
24.4 optional:單子式操作 737
24.5 expected 738
24.6 本章小結(jié) 741
24.7 練習 741
第IV部分 掌握C 的高級特性
第25章 自定義和擴展標準庫 745
25.1 分配器 745
25.2 擴展標準庫 746
25.2.1 擴展標準庫的原因 747
25.2.2 編寫標準庫算法 747
25.2.3 編寫標準庫容器 749
25.3 本章小結(jié) 773
25.4 練習 774
第26章 高級模板 775
26.1 深入了解模板參數(shù) 775
26.1.1 深入了解模板類型參數(shù) 775
26.1.2 template template參數(shù)介紹 778
26.1.3 深入了解非類型模板參數(shù) 780
26.2 類模板部分特化 781
26.3 通過重載模擬函數(shù)部分特化 784
26.4 模板遞歸 785
26.4.1 N維網(wǎng)格:初次嘗試 786
26.4.2 真正的N維網(wǎng)格 786
26.5 變參模板 788
26.5.1 類型安全的變長參數(shù)列表 788
26.5.2 可變數(shù)目的混入類 791
26.5.3 折疊表達式 792
26.6 模板元編程 794
26.6.1 編譯期階乘 794
26.6.2 循環(huán)展開 795
26.6.3 打印元組 795
26.6.4 類型萃取 798
26.6.5 模板元編程總結(jié) 809
26.7 本章小結(jié) 809
26.8 練習 809
第27章 C 多線程編程 810
27.1 多線程編程概述 811
27.1.1 爭用條件 812
27.1.2 撕裂 813
27.1.3 死鎖 813
27.1.4 偽共享 814
27.2 線程 815
27.2.1 通過函數(shù)指針創(chuàng)建線程 815
27.2.2 通過函數(shù)對象創(chuàng)建線程 816
27.2.3 通過lambda創(chuàng)建線程 817
27.2.4 通過成員函數(shù)指針創(chuàng)建線程 818
27.2.5 線程本地存儲 818
27.2.6 取消線程 819
27.2.7 自動join線程 819
27.2.8 從線程獲得結(jié)果 820
27.2.9 復制和重新拋出異常 821
27.3 原子操作庫 823
27.3.1 原子操作 825
27.3.2 原子智能指針 826
27.3.3 原子引用 826
27.3.4 使用原子類型 826
27.3.5 等待原子變量 828
27.4 互斥 829
27.4.1 互斥量類 829
27.4.2 鎖 831
27.4.3 std::call_once 834
27.4.4 互斥量的用法示例 835
27.5 條件變量 838
27.5.1 虛假喚醒 839
27.5.2 使用條件變量 839
27.6 latch 840
27.7 barrier 841
27.8 semaphore 843
27.9 future 843
27.9.1 std::promise和std::future 844
27.9.2 std::packaged_task 845
27.9.3 std::async 845
27.9.4 異常處理 846
27.9.5 std::shared_future 847
27.10 示例:多線程的Logger類 848
27.11 線程池 852
27.12 協(xié)程 852
27.13 線程設計和最佳實踐 854
27.14 本章小結(jié) 855
27.15 練習 855
第V部分 C 軟件工程
第28章 充分利用軟件工程方法 859
28.1 過程的必要性 859
28.2 軟件生命周期模型 860
28.2.1 瀑布模型 860
28.2.2 生魚片模型 862
28.2.3 螺旋類模型 862
28.2.4 敏捷 864
28.3 軟件工程方法論 865
28.3.1 Scrum 865
28.3.2 UP 867
28.3.3 RUP 868
28.3.4 極限編程 869
28.3.5 軟件分流 872
28.4 構(gòu)建自己的過程和方法 873
28.4.1 對新思想采取開放態(tài)度 873
28.4.2 提出新想法 873
28.4.3 知道什么行得通、什么行不通 873
28.4.4 不要逃避 873
28.5 版本控制 873
28.6 本章小結(jié) 875
28.7 練習 875
第29章 編寫高效的C 程序 876
29.1 性能和效率概述 876
29.1.1 提升效率的兩種方式 877
29.1.2 兩種程序 877
29.1.3 C 是不是低效的語言 877
29.2 語言層次的效率 877
29.2.1 高效地操縱對象 878
29.2.2 預分配內(nèi)存 881
29.2.3 使用內(nèi)聯(lián)函數(shù) 881
29.2.4 標記無法訪問的代碼 881
29.3 設計層次的效率 882
29.3.1 盡可能多地緩存 882
29.3.2 使用對象池 883
29.4 剖析 888
29.4.1 使用gprof的剖析示例 888
29.4.2 使用Visual C 2022的剖析示例 895
29.5 本章小結(jié) 897
29.6 練習 897
第30章 熟練掌握測試技術 898
30.1 質(zhì)量控制 899
30.1.1 誰負責測試 899
30.1.2 bug的生命周期 899
30.1.3 bug跟蹤工具 900
30.2 單元測試 901
30.2.1 單元測試方法 902
30.2.2 單元測試過程 902
30.2.3 實際中的單元測試 905
30.3 模糊測試 912
30.4 高級測試 913
30.4.1 集成測試 913
30.4.2 系統(tǒng)測試 914
30.4.3 回歸測試 914
30.5 用于成功測試的建議 915
30.6 本章小結(jié) 915
30.7 練習 916
第31章 熟練掌握調(diào)試技術 917
31.1 調(diào)試的基本定律 917
31.2 bug分類學 918
31.3 避免bug 918
31.4 為bug做好規(guī)劃 919
31.4.1 錯誤日志 919
31.4.2 調(diào)試跟蹤 920
31.4.3 斷言 927
31.4.4 崩潰轉(zhuǎn)儲 928
31.5 調(diào)試技術 928
31.5.1 重現(xiàn)bug 928
31.5.2 調(diào)試可重復的bug 929
31.5.3 調(diào)試不可重現(xiàn)的bug 929
31.5.4 調(diào)試退化 930
31.5.5 調(diào)試內(nèi)存問題 930
31.5.6 調(diào)試多線程程序 934
31.5.7 調(diào)試示例:文章引用 934
31.5.8 從ArticleCitations示例中總結(jié)出的教訓 945
31.6 本章小結(jié) 946
31.7 練習 946
第32章 使用設計技術和框架 948
32.1 容易忘記的語法 949
32.1.1 編寫類 949
32.1.2 派生類 950
32.1.3 編寫lambda表達式 951
32.1.4 使用復制和交換慣用語法 951
32.1.5 拋出和捕獲異常 952
32.1.6 寫入類模板 953
32.1.7 約束模板參數(shù) 953
32.1.8 寫入文件 954
32.1.9 讀取文件 954
32.2 始終存在更好的方法 955
32.2.1 RAII 955
32.2.2 雙分派 958
32.2.3 混入類 961
32.3 面向?qū)ο蟮目蚣?965
32.3.1 使用框架 965
32.3.2 MVC范型 966
32.4 本章小結(jié) 967
32.5 練習 967
第33章 應用設計模式 968
33.1 策略模式 969
33.1.1 示例:日志機制 969
33.1.2 基于策略logger的實現(xiàn) 969
33.1.3 使用基于策略的Logger 970
33.2 抽象工廠模式 971
33.2.1 示例:模擬汽車工廠 971
33.2.2 實現(xiàn)抽象工廠 972
33.2.3 使用抽象工廠 973
33.3 工廠方法模式 974
33.3.1 示例:模擬第二個汽車工廠 974
33.3.2 實現(xiàn)工廠的方法 975
33.3.3 使用工廠方法 976
33.3.4 其他用法 978
33.4 其他工廠模式 978
33.5 適配器模式 979
33.5.1 示例:適配Logger類 979
33.5.2 實現(xiàn)適配器 980
33.5.3 使用適配器 981
33.6 代理模式 981
33.6.1 示例:隱藏網(wǎng)絡連接問題 981
33.6.2 實現(xiàn)代理 981
33.6.3 使用代理 982
33.7 迭代器模式 983
33.8 觀察者模式 983
33.8.1 示例:從主題中暴露事件 983
33.8.2 實現(xiàn)觀察者 984
33.8.3 使用觀察者 985
33.9 裝飾器模式 986
33.9.1 示例:在網(wǎng)頁中定義樣式 986
33.9.2 裝飾器的實現(xiàn) 987
33.9.3 使用裝飾器 988
33.10 責任鏈模式 988
33.10.1 示例:事件處理 989
33.10.2 實現(xiàn)責任鏈 989
33.10.3 使用責任鏈 990
33.11 單例模式 991
33.11.1 日志記錄機制 992
33.11.2 實現(xiàn)單例 992
33.11.3 使用單例 994
33.12 本章小結(jié) 994
33.13 練習 994
第34章 開發(fā)跨平臺和跨語言的應用程序 996
34.1 跨平臺開發(fā) 996
34.1.1 架構(gòu)問題 997
34.1.2 實現(xiàn)問題 999
34.1.3 平臺專用功能 1001
34.2 跨語言開發(fā) 1002
34.2.1 混用C和C 1002
34.2.2 改變范型 1002
34.2.3 鏈接C代碼 1005
34.2.4 從C#調(diào)用C 代碼 1006
34.2.5 在C 中使用C#代碼及在C#中使用C 代碼 1008
34.2.6 在Java中使02用JNI調(diào)用C 代碼 1009
34.2.7 從C 代碼調(diào)用腳本 1011
34.2.8 從腳本調(diào)用C 代碼 1011
34.2.9 從C 調(diào)用匯編代碼 1013
34.3 本章小結(jié) 1014
34.4 練習 1014
以下內(nèi)容可掃封底二維碼下載
第VI部分 附錄
附錄A C 面試 1019
附錄B 參考文獻及相關介紹 1039
附錄C 標準庫頭文件 1048
附錄D UML簡介 1054