內容簡介
本書循序漸進、由淺入深地講解了C語言開發的技術。全書共25章。本書不僅介紹了C語言的基礎和核心知識(如開發工具、語法、運算符、表達式、輸入/輸出、流程控制、數組、字元串、函式),還講解了C語言中的重點和難點(如指針、結構體、共用體和枚舉、鍊表、位運算、預編譯、檔案操作、調試、記憶體管理、高級編程技術、算法、數據結構、網路編程技術等)。此外,臘探套匪本書還通過4個綜合實例,介紹了C語言在綜合項目中的套用。全書內容以“技術解惑”和“範例演練”貫穿全書,引領讀者全面掌握C語言。
本書不但適用C語言的初學者,也適合有一定C語言基礎的讀者學習,還可以作為大專院校相關專業的師生用書和培訓學校的教材。
圖書目錄
第1章 C語言之定位 1
1.1 計算機套用基礎 2
1.1.2 位和位元組 去請頸2
1.1.3 二進制 2
1.1.4 編碼格式 3
1.2 C語言的誕生 4
1.3 第一印象的建立 5
1.4 理解編譯系統—學習的第一步 6
1.5 技術解惑 7
1.5.1 學習C語言還有用嗎 7
1.5.2 怎樣學好C語言 8
1.5.3 學好C語言的建議 8
1.6 課後練習 8
第2章 C語言開發工具詳解 9
2.1 用DOS開發C程式 10
2.1.1 安裝Turbo C 3.0 10
2.1.2 使用Turbo C 3.0 10
2.2 在Windows環境下使用
Visual Studio 2017 紋設11
2.2.1 安裝Visual Studio 2017 11
2.2.2 使用Visual Studio 2017開發一個C程式 15
2.3 使用輕量級開發工具DEV C++ 18
2.3.1 安裝DEV C++ 18
2.3.2 使用DEV C++運行一個C程式 20
2.4 使用Vsiual C++ 6.0開發C程式 20
2.6 技術解惑 23
2.6.1 安裝Visual Studio 2017時遇到的常見問題 23
2.6.2 在Windows 7中安裝Visual Studio時遇到的常見問題 24
2.7 課後練習 24
第3章 程式設計師基本素質的培養 25
3.1 養成好海良愉的命名習慣 26
3.2 C程式檔案結構 26
3.2.1 C程式的組成部分 26
3.2.2 C程式的格式總結 27
3.3 養成好的C語言編程風格 28
3.3.1 隨時陵整凶使用縮進格式 28
3.3.2 注意大括弧的位置 28
3.3.3 函式的規則 29
3.3.4 注意注釋 29
3.4 如何成為一名優秀的程式設計師 29
3.5 技術解惑 31
3.6 課試戒講遷後練習 31
第4章 C語言語法 32
4.1 標識符和關鍵字 33
4.2 最基本的數據類型 33
4.3 常量和變數 34
4.3.1 常量 35
4.3.2 變數 36
4.4 整型數據 37
4.4.1 整型常量 38
4.4.2 整型變數 39
4.5 實型數據 41
4.5.1 實型常量 41
4.5.2 實型變數 42
4.5.3 實型常量的類型 43
4.6 字元型數據 43
4.6.1 字元常量 43
4.6.3 字元變數 46
4.7 初始化變數 47
4.8 整型、實型和字元型數據間的運算總結 47
4.8.1 自動轉換 47
4.8.2 強制轉換 49
4.9 技術解惑 49
4.9.1 在C語言中無符號整型變數和有符號整型變數
的定義 49
4.9.2 在C語言中字元變數的含義 50
4.9.3 如何理解字元型數據的取值範圍 50
4.9.4 怎樣將帶小數點的字元型數據轉換成浮點型 50
4.10 課後練習 51
第5章 運算符和表達式 52
5.1 運算符和表達式的概述 53
5.1.1 運算符的種類 53
5.1.2 運算符的優先權 54
5.2.2 雙目運算符 56
5.3.1 基本賦值運算符 56
5.3.3 賦值喇狼組表達式 58
5.5.1 邏輯運算符 60
5.5.2 邏輯表達式 60
5.6.1 逗號運算符 62
5.6.2 逗號表達式 62
5.7 求位元組數的運算符 63
5.8 技術解惑 64
5.8.1 C語言運算符優先權的詳情 64
5.8.2 少數運算符在規定表達式中的求值順序 65
5.8.3 在C語言中是否可以進行混合運算 66
5.8.4 在一個邏輯條件語句中常數項永遠在左側 66
5.9 課後練習 67
第6章 輸入和輸出 68
6.1 C語句的初步知識 69
6.1.1 C語句簡介 69
6.1.2 賦值語句 70
6.2.1 putchar函式 71
6.2.2 getchar函式 72
6.2.3 printf函式 73
6.2.4 scanf函式 76
6.2.5 puts函式 79
6.2.6 C11標準函式gets_s 80
6.3 技術解惑 80
6.3.1 gets_s函式和scanf函式的區別 80
6.3.2 克服gets_s函式的缺陷 81
6.3.3 C語言的輸入和輸出問題 82
6.4 課後練習 83
第7章 流程控制 84
7.1 最常見的順序結構 85
7.2 選擇結構 85
7.2.1 單分支結構語句 86
7.2.2 雙分支結構語句 87
7.2.3 多分支結構語句 90
7.3 循環結構 92
7.3.1 for語句 93
7.3.2 while語句 94
7.3.3 do…while語句 96
7.3.5 break/continue跳躍 98
7.3.6 死循環/退出程式 99
7.4 技術解惑 100
7.4.1 循環中的低效問題 100
7.4.2 分析C語言循環語句的效率 101
7.4.3 使用for循環語句的注意事項 102
7.5 課後練習 102
第8章 數組和字元串—數據的存在形式 104
8.1 一維數組 105
8.1.1 定義一維數組 105
8.1.2 引用一維數組的元素 105
8.1.3 初始化一維數組 106
8.2 多維數組 107
8.2.1 二維數組的用法 107
8.2.2 多維數組的用法 110
8.3 字元數組與字元串 112
8.3.1 字元數組 112
8.3.2 字元串與字元數組 113
8.3.3 字元數組的輸入和輸出 113
8.4 字元串處理函式 115
8.4.1 測試字元串長度的函式 115
8.4.2 字元串大小寫轉換函式 115
8.4.3 字元串複製函式 116
8.4.4 字元串比較函式 117
8.4.5 字元串連線函式 119
8.4.6 其他的字元串函式 119
8.4.7 將字元串轉換成數值的函式 120
8.5 字元處理函式 121
8.5.1 字元檢測函式 121
8.5.2 字元大小寫轉換函式 122
8.6 技術解惑 123
8.6.1 數組的下標總是從0開始嗎 123
8.6.2 C語言對數組的處理非常有效嗎 124
8.6.3 初始化一維數組的注意事項 124
8.6.4 冒泡排序 125
8.7 課後練習 125
第9章 函式 126
9.1 C函式的基礎知識 127
9.1.1 函式的分類 127
9.1.2 函式的定義 128
9.2 函式聲明和函式原型 129
9.3 函式的參數 131
9.3.1 形參和實參 131
9.3.2 以數組名作為函式的參數 132
9.3.3 以數組作為函式的參數 133
9.4 函式的返回值 135
9.5 函式的調用 136
9.5.1 函式調用的格式 136
9.5.2 函式的調用方式 137
9.5.3 被調函式的聲明方式 138
9.5.4 對調用函式的方式進行深入分析 139
9.6 函式的嵌套調用和遞歸調用 140
9.6.1 函式的嵌套調用 140
9.6.2 函式的遞歸調用 142
9.7 變數的作用域和生存期 145
9.7.1 變數作用域 145
9.7.2 靜態存儲變數和動態存儲變數 147
9.8 C的內部函式和外部函式 153
9.8.1 內部函式 153
9.8.2 外部函式 153
9.9 庫函式 154
9.10 技術解惑 156
9.10.1 通過Turbo C深入分析 項目檔案 156
9.10.2 要儘量避免不必要的函式調用 157
9.10.3 請確保函式的聲明和定義是靜態的 158
9.10.4 避免過長的main()函式 158
9.10.5 函式的地址也是數據 160
9.10.6 說明函式的時機 160
9.10.7 一個函式可以有多少個參數 161
9.10.8 如果一個函式沒有返回值,是否需要加入return
語句 162
9.10.9 在程式退出
main函式之後還有可能執行一部分代碼 162
9.10.10 exit()函式和return語句的差異 162
9.11 課後練習 162
第10章 指針 164
10.1 基本概念 165
10.2 變數的指針和指向變數的指針變數 165
10.2.1 聲明指針變數 166
10.2.2 指針變數的初始化 166
10.2.3 指針變數的引用 167
10.2.5 指針變數的運算 169
10.2.6 以指針變數作為函式參數 170
10.2.7 void類型的指針 173
10.3 指針和數組 174
10.3.1 數組元素的指針 174
10.3.2 指向一維數組元素的指針變數 175
10.3.3 通過指針引用數組元素 176
10.3.4 以數組名作為函式參數 179
10.4 指針和多維數組 180
10.4.1 多維數組的地址 180
10.4.2 指向多維數組的指針變數 182
10.5 指針和字元串 185
10.5.1 指針訪問字元串 185
10.5.2 以字元串指針作為函式參數 186
10.5.3 字元串指針變數與字元數組的區別 187
10.6 指針數組和多級指針 188
10.6.1 指針數組 188
10.6.2 多級指針的定義和套用 189
10.6.3 指向指針的指針 191
10.7 指針函式和函式指針 192
10.7.1 指針函式 193
10.7.2 函式指針 193
10.8 技術解惑 195
10.8.1 初始化指針時的注意事項 195
10.8.2 為指針賦值時的注意事項 196
10.8.3 當指針用於數組時的注意事項 197
10.8.4 在結構中使用指針時的注意事項 197
10.8.5 避免不必要的記憶體引用 198
10.8.6 避免懸空指針和野指針 198
10.8.7 數組下標與指針的效率解析 199
10.8.8 使用指針時的常見錯誤 199
10.9 課後練習 200
第11章 數據的熔爐—結構體、共用體和枚舉 202
11.1 結構體 203
11.1.2 定義結構體類型變數 203
11.1.3 引用結構體變數 205
11.1.4 初始化結構體變數 206
11.2 結構體數組 207
11.2.1 定義結構體數組 208
11.2.2 初始化結構體數組 209
11.2.3 引用結構體數組 210
11.3 結構體指針 211
11.3.1 定義結構體指針變數 212
11.3.2 初始化結構體指針變數 212
11.3.3 引用結構體指針變數 212
11.3.4 指向結構變數的指針 213
11.3.5 指向結構體數組的指針 214
11.4 在函式中使用結構體 214
11.4.1 結構體變數和結構體指針可以作為函式參數 215
11.4.2 函式可以返回結構體類型的值 215
11.5 共用體(聯合) 217
11.5.1 定義共用體和共用體變數 217
11.5.2 引用和初始化共用體變數 218
11.6 枚舉 219
11.6.1 定義枚舉類型 219
11.6.2 定義枚舉變數 220
11.6.3 引用枚舉變數 220
11.7 typedef定義類型的作用 222
11.7.1 類型定義符typedef的基礎 222
11.7.2 使用typedef 223
11.8 技術解惑 224
11.8.1 可以省略結構名嗎 224
11.8.2 是否可以定義一種通用數據類型以存儲任意類型的數據 224
11.8.3 結構和共用體的區別 224
11.8.4 定義C結構體的問題 225
11.9 課後練習 225
第12章 鍊表 226
12.1 動態記憶體分配 227
12.1.1 動態記憶體分配的作用 227
12.1.2 實現動態記憶體分配及管理的方法 227
12.2 鍊表詳解 230
12.2.1 鍊表簡介 230
12.2.2 單向鍊表 231
12.2.3 創建一個鍊表 233
12.2.4 刪除整個鍊表 234
12.2.5 在鍊表中插入節點 234
12.2.6 在鍊表中刪除節點 235
12.2.7 雙向鍊表 236
12.2.8 循環鍊表 237
12.3 技術解惑 238
12.3.1 鍊表的總結 238
12.3.2 面試題—判斷單鍊表是否有環 242
12.3.3 面試題—實現單鍊表逆置 243
12.4 課後練習 244
第13章 位運算 245
13.1 位運算符和位運算 246
13.1.1 按位與運算 246
13.1.2 按位或運算 247
13.1.3 按位異或運算 247
13.1.4 取反運算 248
13.1.5 左移運算 248
13.1.6 右移運算 249
13.1.7 位運算的套用實例 249
13.2 位域 251
13.2.1 位域的定義和位域變數的說明 251
13.2.2 位域的使用 252
13.3 技術解惑 252
13.3.2 面試題—從某個數中取出指定的某些位 252
13.3.3 位域的記憶體對齊原則 253
13.4 課後練習 253
第14章 預編譯處理 255
14.1 預編譯的基礎 256
14.2 宏定義 256
14.2.1 不帶參數的宏定義 256
14.2.2 帶參數的宏定義 258
14.2.3 字元串化運算符 260
14.2.4 並接運算符 260
14.3 檔案包含 260
14.4 條件編譯 262
14.4.1 #ifdef… #else…#endif命令 262
14.4.2 #if defined… #else…#endif 263
14.4.3 #ifndef… #else…#endif 263
14.4.4 #if !defined… #else…#endif 264
14.4.5 #ifdef…#elif… #elif…#else… #endif 264
14.5 技術解惑 265
14.5.1 還有其他預編譯指令嗎 265
14.5.2 帶參的宏定義和函式不同 266
14.5.3 C語言中預處理指令的總結 266
14.5.4 預編譯指令的本質 267
14.5.5 sizeof(int)在預編譯階段是不會求值的 267
14.5.6 多行預處理指令的寫法 267
14.6 課後練習 267
第15章 檔案操作 268
15.1 檔案 269
15.1.1 文本檔案 269
15.1.2 檔案分類 270
15.2 檔案指針 270
15.3 檔案的打開與關閉 271
15.3.1 打開檔案 271
15.3.2 關閉檔案 273
15.4 檔案讀寫 274
15.4.1 字元讀寫函式 274
15.4.2 字元串讀寫函式 276
15.4.3 格式化讀寫函式 278
15.4.4 數據塊讀寫函式 279
15.4.5 其他讀寫函式 280
15.5 檔案的隨機讀寫 281
15.5.1 fseek函式 281
15.5.2 rewind函式 283
15.5.3 ftell函式 283
15.6 檔案管理函式 284
15.6.1 刪除檔案 284
15.6.2 重命名檔案 285
15.6.3 複製檔案 285
15.7 檔案狀態檢測函式 286
15.7.1 feof函式 287
15.7.2 ferror函式 287
15.7.3 clearerr函式 287
15.8 Win32 API中的檔案操作函式 288
15.8.1 創建和打開檔案 288
15.8.2 讀取、寫入和刪除檔案 289
15.9 技術解惑 289
15.9.1 檔案指針是檔案內部的位置指針嗎 289
15.9.2 fseek函式的換行問題 290
15.9.3 怎樣解決gets函式的溢出問題 290
15.9.4 feof函式會多讀一個數據嗎 290
15.9.5 流和檔案的關係 290
15.10 課後練習 291
第16章 錯誤和程式調試 292
16.1 常見錯誤分析 293
16.1.1 語法錯誤 293
16.1.2 邏輯錯誤(語義錯誤) 294
16.1.3 記憶體錯誤 297
16.2 錯誤的檢出與分離 302
16.3 調試時的注意事項 303
16.3.1 上機前要先熟悉程式的運行環境 303
16.3.2 在編程時要為調試做好準備 304
16.4 技術解惑 304
16.4.1 編譯通過並不代表運行正確 304
16.4.2 兩段代碼的編譯差別 305
16.4.3 調試程式的方法與技巧 305
16.5 課後練習 307
第17章 記憶體管理 308
17.1 C語言中的記憶體模型 309
17.2 棧和堆 309
17.2.1 棧操作 309
17.2.2 堆操作 310
17.3 動態管理 311
17.3.2 使用函式calloc分配記憶體空間並初始化 312
17.3.3 使用函式realloc重新分配記憶體 313
17.3.4 使用函式free釋放記憶體空間 314
17.4 課後練習 315
第18章 C語言高級編程技術 316
18.1 C語言的高級編程技術 317
18.2 分析文本的螢幕輸出和鍵盤輸入 317
18.2.1 實現文本的螢幕輸出 317
18.2.2 實現鍵盤輸入 322
18.2.3 套用實例 323
18.3 分析圖形顯示方式和滑鼠輸入 324
18.3.1 初始化圖形模式 325
18.3.2 清屏和恢復顯示函式 326
18.3.3 建立獨立圖形程式 327
18.3.4 基本繪圖函式 327
18.3.5 線性函式 330
18.3.6 顏色控制函式 331
18.3.7 填色函式和畫圖函式 334
18.3.8 圖形視窗函式 336
18.3.9 分析圖形方式下的文本輸出函式 337
18.4 選單設計 340
18.5 課後練習 343
第19章 算法—抓住程式的靈魂 344
19.1 我們對算法的理解 345
19.1.1 算法是程式的靈魂 345
19.1.2 何謂算法 345
19.1.3 算法的特性 346
19.2 算法表示法—流程圖 347
19.3 枚舉算法 348
19.3.1 枚舉算法的基礎 348
19.3.2 實戰演練—百錢買百雞 348
19.3.3 實戰演練—填寫運算符 349
19.4 遞推算法 351
19.4.1 遞推算法的基礎 351
19.4.3 實戰演練—銀行存款 353
19.5 遞歸算法 354
19.5.1 遞歸算法的基礎 354
19.5.2 實戰演練—漢諾塔 355
19.5.3 實戰演練—階乘 357
19.6 分治算法 358
19.6.1 分治算法的基礎 358
19.6.2 實戰演練—大數相乘 358
19.6.3 實戰演練—歐洲冠軍杯
比賽日程安排 360
19.7 貪心算法 362
19.7.1 貪心算法的基礎 363
19.7.2 實戰演練—裝箱 363
19.7.3 實戰演練—找零方案 365
19.8 試探法算法 366
19.8.1 試探法算法的基礎 366
19.8.2 實戰演練—八皇后 367
19.8.3 實戰演練—體彩29選7的組合 368
19.9 疊代算法 370
19.9.1 疊代算法的基礎 370
19.9.2 實戰演練—求平方根 370
19.10 模擬算法 371
19.10.1 模擬算法的思路 371
19.10.2 實戰演練—猜數字遊戲 372
19.10.3 實戰演練—擲骰子 遊戲 372
19.11 技術解惑 374
19.11.1 衡量算法的標準 374
19.11.2 選擇使用枚舉法的時機 375
19.11.3 遞推和遞歸的差異 376
19.11.4 分治法解決問題的類型 376
19.11.5 分治算法的機理 376
19.11.6 貪婪算法並不是解決問題最優方案的原因 376
19.11.7 回溯算法是否會影響算法效率 377
19.11.8 遞歸算法與疊代算法的區別 377
19.12 課後練習 377
第20章 數據結構 379
20.1 使用線性表 380
20.1.1 線性表的特性 380
20.1.2 順序表操作 381
20.1.3 實戰演練—使用順序表操作函式 385
20.2 佇列 386
20.2.1 佇列的定義 386
20.2.2 實戰演練—實現一個排號程式 387
20.3 棧 390
20.3.1 棧的定義 390
20.3.2 實戰演練—實現棧操作 390
20.4 技術解惑 392
20.4.1 線性表插入操作的時間複雜度 392
20.4.2 線性表刪除操作的時間複雜度 392
20.4.3 線性表按值查找操作的時間複雜度 392
20.4.4 線性表連結存儲操作的11種算法 393
20.4.5 堆和棧的區別 397
20.5 課後練習 397
第21章 網路編程技術 398
21.1 OSI 7層網路模型 399
21.2 TCP/IP 400
21.2.1 IP 401
21.2.2 TCP 402
21.2.3 UDP 403
21.2.4 ICMP 403
21.3 使用C語言開發網路項目 404
21.3.1 網路編程方式 404
21.3.2 網路通信的基本流程 404
21.3.3 搭建開發環境 405
21.3.4 兩個常用的數據結構 405
21.3.5 Windows套接字的基礎 406
21.4 常用的Winsock函式 406
21.4.1 WSAStartup函式 406
21.4.3 inet_addr函式 407
21.4.4 gethostbyname函式 407
21.4.5 bind函式 407
21.4.6 connect函式 407
21.4.8 recv函式 408
21.4.9 sendto函式 408
21.5 MAC地址 408
21.6 NetBIOS編程 409
21.6.1 處理過程 409
21.6.2 NetBIOS命令 410
21.6.3 NetBIOS名字解析 410
21.6.4 NetBEUI 413
21.6.5 NetBIOS的範圍 413
21.6.6 NetBIOS控制塊 413
21.7 實戰演練—獲取當前機器的MAC地址 413
21.7.1 選擇開發工具 413
21.7.2 設計MFC窗體 414
21.7.3 具體編碼 414
第22章 初入江湖—設計遊戲項目 421
22.1 遊戲功能描述 422
22.2 遊戲總體設計 422
22.2.1 功能模組設計 422
22.2.2 數據結構設計 424
22.2.3 構成函式介紹 425
22.3 遊戲的具體實現 426
22.3.1 預處理 426
22.3.2 主函式 429
22.3.3 初始化界面處理 430
22.3.4 時鐘中斷處理 431
22.3.5 成績、速度和幫助處理 431
22.3.6 滿行處理 432
22.3.7 方塊顯示和消除處理 434
22.3.8 方塊判斷處理 435
第23章 風雲再起—設計網路項目 438
23.1 系統功能描述 439
23.2 系統總體設計 439
23.2.1 功能模組設計 439
23.2.2 數據結構設計 441
23.2.3 構成函式介紹 442
23.3 系統的具體實現 442
23.3.1 預處理 442
23.3.2 初始化處理 444
23.3.3 控制模組 444
23.3.4 數據報解讀處理 446
23.3.5 Ping測試處理 447
23.3.6 主函式 449
第24章 爐火純青—學生成績管理系統 451
24.1 系統總體描述 452
24.1.1 項目開發的目標 452
24.1.2 項目的意義 452
24.1.3 系統功能描述 452
24.2 系統總體設計 453
24.2.1 功能模組設計 453
24.2.2 數據結構設計 454
24.2.3 構成函式介紹 455
24.3 系統的具體實現 456
24.3.1 預處理 456
24.3.2 主函式 457
24.3.3 系統主選單函式 458
24.3.4 表格顯示信息 458
24.3.5 信息查找定位 459
24.3.6 格式化輸入數據 459
24.3.7 增加學生記錄 460
24.3.8 查詢學生記錄 461
24.3.9 刪除學生記錄 462
24.3.10 修改學生記錄 463
24.3.11 插入學生記錄 463
24.3.12 統計學生記錄 464
24.3.13 排序處理 465
24.3.14 存儲學生信息 466
第25章 笑傲江湖—使用C51實現跑馬燈程式 471
25.1 單片機C語言基礎 472
25.1.1 單片機C語言的優越性 472
25.1.2 C51的數據類型 472
25.1.3 C51數據的存儲結構 473
25.1.4 C51運算符和表達式 474
25.1.5 C51的中斷函式 475
25.2 跑馬燈設計實例 476
25.2.1 基本跑馬燈的實現 476
25.2.2 矩形波發生器 479
25.2.3 用定時器/計數器產生矩形波 480
25.3 一個完整的跑馬燈程式 481
25.3.1 電路設計 481
25.3.2 程式設計 484
第4章 C語言語法 32
4.1 標識符和關鍵字 33
4.2 最基本的數據類型 33
4.3 常量和變數 34
4.3.1 常量 35
4.3.2 變數 36
4.4 整型數據 37
4.4.1 整型常量 38
4.4.2 整型變數 39
4.5 實型數據 41
4.5.1 實型常量 41
4.5.2 實型變數 42
4.5.3 實型常量的類型 43
4.6 字元型數據 43
4.6.1 字元常量 43
4.6.3 字元變數 46
4.7 初始化變數 47
4.8 整型、實型和字元型數據間的運算總結 47
4.8.1 自動轉換 47
4.8.2 強制轉換 49
4.9 技術解惑 49
4.9.1 在C語言中無符號整型變數和有符號整型變數
的定義 49
4.9.2 在C語言中字元變數的含義 50
4.9.3 如何理解字元型數據的取值範圍 50
4.9.4 怎樣將帶小數點的字元型數據轉換成浮點型 50
4.10 課後練習 51
第5章 運算符和表達式 52
5.1 運算符和表達式的概述 53
5.1.1 運算符的種類 53
5.1.2 運算符的優先權 54
5.2.2 雙目運算符 56
5.3.1 基本賦值運算符 56
5.3.3 賦值表達式 58
5.5.1 邏輯運算符 60
5.5.2 邏輯表達式 60
5.6.1 逗號運算符 62
5.6.2 逗號表達式 62
5.7 求位元組數的運算符 63
5.8 技術解惑 64
5.8.1 C語言運算符優先權的詳情 64
5.8.2 少數運算符在規定表達式中的求值順序 65
5.8.3 在C語言中是否可以進行混合運算 66
5.8.4 在一個邏輯條件語句中常數項永遠在左側 66
5.9 課後練習 67
第6章 輸入和輸出 68
6.1 C語句的初步知識 69
6.1.1 C語句簡介 69
6.1.2 賦值語句 70
6.2.1 putchar函式 71
6.2.2 getchar函式 72
6.2.3 printf函式 73
6.2.4 scanf函式 76
6.2.5 puts函式 79
6.2.6 C11標準函式gets_s 80
6.3 技術解惑 80
6.3.1 gets_s函式和scanf函式的區別 80
6.3.2 克服gets_s函式的缺陷 81
6.3.3 C語言的輸入和輸出問題 82
6.4 課後練習 83
第7章 流程控制 84
7.1 最常見的順序結構 85
7.2 選擇結構 85
7.2.1 單分支結構語句 86
7.2.2 雙分支結構語句 87
7.2.3 多分支結構語句 90
7.3 循環結構 92
7.3.1 for語句 93
7.3.2 while語句 94
7.3.3 do…while語句 96
7.3.5 break/continue跳躍 98
7.3.6 死循環/退出程式 99
7.4 技術解惑 100
7.4.1 循環中的低效問題 100
7.4.2 分析C語言循環語句的效率 101
7.4.3 使用for循環語句的注意事項 102
7.5 課後練習 102
第8章 數組和字元串—數據的存在形式 104
8.1 一維數組 105
8.1.1 定義一維數組 105
8.1.2 引用一維數組的元素 105
8.1.3 初始化一維數組 106
8.2 多維數組 107
8.2.1 二維數組的用法 107
8.2.2 多維數組的用法 110
8.3 字元數組與字元串 112
8.3.1 字元數組 112
8.3.2 字元串與字元數組 113
8.3.3 字元數組的輸入和輸出 113
8.4 字元串處理函式 115
8.4.1 測試字元串長度的函式 115
8.4.2 字元串大小寫轉換函式 115
8.4.3 字元串複製函式 116
8.4.4 字元串比較函式 117
8.4.5 字元串連線函式 119
8.4.6 其他的字元串函式 119
8.4.7 將字元串轉換成數值的函式 120
8.5 字元處理函式 121
8.5.1 字元檢測函式 121
8.5.2 字元大小寫轉換函式 122
8.6 技術解惑 123
8.6.1 數組的下標總是從0開始嗎 123
8.6.2 C語言對數組的處理非常有效嗎 124
8.6.3 初始化一維數組的注意事項 124
8.6.4 冒泡排序 125
8.7 課後練習 125
第9章 函式 126
9.1 C函式的基礎知識 127
9.1.1 函式的分類 127
9.1.2 函式的定義 128
9.2 函式聲明和函式原型 129
9.3 函式的參數 131
9.3.1 形參和實參 131
9.3.2 以數組名作為函式的參數 132
9.3.3 以數組作為函式的參數 133
9.4 函式的返回值 135
9.5 函式的調用 136
9.5.1 函式調用的格式 136
9.5.2 函式的調用方式 137
9.5.3 被調函式的聲明方式 138
9.5.4 對調用函式的方式進行深入分析 139
9.6 函式的嵌套調用和遞歸調用 140
9.6.1 函式的嵌套調用 140
9.6.2 函式的遞歸調用 142
9.7 變數的作用域和生存期 145
9.7.1 變數作用域 145
9.7.2 靜態存儲變數和動態存儲變數 147
9.8 C的內部函式和外部函式 153
9.8.1 內部函式 153
9.8.2 外部函式 153
9.9 庫函式 154
9.10 技術解惑 156
9.10.1 通過Turbo C深入分析 項目檔案 156
9.10.2 要儘量避免不必要的函式調用 157
9.10.3 請確保函式的聲明和定義是靜態的 158
9.10.4 避免過長的main()函式 158
9.10.5 函式的地址也是數據 160
9.10.6 說明函式的時機 160
9.10.7 一個函式可以有多少個參數 161
9.10.8 如果一個函式沒有返回值,是否需要加入return
語句 162
9.10.9 在程式退出
main函式之後還有可能執行一部分代碼 162
9.10.10 exit()函式和return語句的差異 162
9.11 課後練習 162
第10章 指針 164
10.1 基本概念 165
10.2 變數的指針和指向變數的指針變數 165
10.2.1 聲明指針變數 166
10.2.2 指針變數的初始化 166
10.2.3 指針變數的引用 167
10.2.5 指針變數的運算 169
10.2.6 以指針變數作為函式參數 170
10.2.7 void類型的指針 173
10.3 指針和數組 174
10.3.1 數組元素的指針 174
10.3.2 指向一維數組元素的指針變數 175
10.3.3 通過指針引用數組元素 176
10.3.4 以數組名作為函式參數 179
10.4 指針和多維數組 180
10.4.1 多維數組的地址 180
10.4.2 指向多維數組的指針變數 182
10.5 指針和字元串 185
10.5.1 指針訪問字元串 185
10.5.2 以字元串指針作為函式參數 186
10.5.3 字元串指針變數與字元數組的區別 187
10.6 指針數組和多級指針 188
10.6.1 指針數組 188
10.6.2 多級指針的定義和套用 189
10.6.3 指向指針的指針 191
10.7 指針函式和函式指針 192
10.7.1 指針函式 193
10.7.2 函式指針 193
10.8 技術解惑 195
10.8.1 初始化指針時的注意事項 195
10.8.2 為指針賦值時的注意事項 196
10.8.3 當指針用於數組時的注意事項 197
10.8.4 在結構中使用指針時的注意事項 197
10.8.5 避免不必要的記憶體引用 198
10.8.6 避免懸空指針和野指針 198
10.8.7 數組下標與指針的效率解析 199
10.8.8 使用指針時的常見錯誤 199
10.9 課後練習 200
第11章 數據的熔爐—結構體、共用體和枚舉 202
11.1 結構體 203
11.1.2 定義結構體類型變數 203
11.1.3 引用結構體變數 205
11.1.4 初始化結構體變數 206
11.2 結構體數組 207
11.2.1 定義結構體數組 208
11.2.2 初始化結構體數組 209
11.2.3 引用結構體數組 210
11.3 結構體指針 211
11.3.1 定義結構體指針變數 212
11.3.2 初始化結構體指針變數 212
11.3.3 引用結構體指針變數 212
11.3.4 指向結構變數的指針 213
11.3.5 指向結構體數組的指針 214
11.4 在函式中使用結構體 214
11.4.1 結構體變數和結構體指針可以作為函式參數 215
11.4.2 函式可以返回結構體類型的值 215
11.5 共用體(聯合) 217
11.5.1 定義共用體和共用體變數 217
11.5.2 引用和初始化共用體變數 218
11.6 枚舉 219
11.6.1 定義枚舉類型 219
11.6.2 定義枚舉變數 220
11.6.3 引用枚舉變數 220
11.7 typedef定義類型的作用 222
11.7.1 類型定義符typedef的基礎 222
11.7.2 使用typedef 223
11.8 技術解惑 224
11.8.1 可以省略結構名嗎 224
11.8.2 是否可以定義一種通用數據類型以存儲任意類型的數據 224
11.8.3 結構和共用體的區別 224
11.8.4 定義C結構體的問題 225
11.9 課後練習 225
第12章 鍊表 226
12.1 動態記憶體分配 227
12.1.1 動態記憶體分配的作用 227
12.1.2 實現動態記憶體分配及管理的方法 227
12.2 鍊表詳解 230
12.2.1 鍊表簡介 230
12.2.2 單向鍊表 231
12.2.3 創建一個鍊表 233
12.2.4 刪除整個鍊表 234
12.2.5 在鍊表中插入節點 234
12.2.6 在鍊表中刪除節點 235
12.2.7 雙向鍊表 236
12.2.8 循環鍊表 237
12.3 技術解惑 238
12.3.1 鍊表的總結 238
12.3.2 面試題—判斷單鍊表是否有環 242
12.3.3 面試題—實現單鍊表逆置 243
12.4 課後練習 244
第13章 位運算 245
13.1 位運算符和位運算 246
13.1.1 按位與運算 246
13.1.2 按位或運算 247
13.1.3 按位異或運算 247
13.1.4 取反運算 248
13.1.5 左移運算 248
13.1.6 右移運算 249
13.1.7 位運算的套用實例 249
13.2 位域 251
13.2.1 位域的定義和位域變數的說明 251
13.2.2 位域的使用 252
13.3 技術解惑 252
13.3.2 面試題—從某個數中取出指定的某些位 252
13.3.3 位域的記憶體對齊原則 253
13.4 課後練習 253
第14章 預編譯處理 255
14.1 預編譯的基礎 256
14.2 宏定義 256
14.2.1 不帶參數的宏定義 256
14.2.2 帶參數的宏定義 258
14.2.3 字元串化運算符 260
14.2.4 並接運算符 260
14.3 檔案包含 260
14.4 條件編譯 262
14.4.1 #ifdef… #else…#endif命令 262
14.4.2 #if defined… #else…#endif 263
14.4.3 #ifndef… #else…#endif 263
14.4.4 #if !defined… #else…#endif 264
14.4.5 #ifdef…#elif… #elif…#else… #endif 264
14.5 技術解惑 265
14.5.1 還有其他預編譯指令嗎 265
14.5.2 帶參的宏定義和函式不同 266
14.5.3 C語言中預處理指令的總結 266
14.5.4 預編譯指令的本質 267
14.5.5 sizeof(int)在預編譯階段是不會求值的 267
14.5.6 多行預處理指令的寫法 267
14.6 課後練習 267
第15章 檔案操作 268
15.1 檔案 269
15.1.1 文本檔案 269
15.1.2 檔案分類 270
15.2 檔案指針 270
15.3 檔案的打開與關閉 271
15.3.1 打開檔案 271
15.3.2 關閉檔案 273
15.4 檔案讀寫 274
15.4.1 字元讀寫函式 274
15.4.2 字元串讀寫函式 276
15.4.3 格式化讀寫函式 278
15.4.4 數據塊讀寫函式 279
15.4.5 其他讀寫函式 280
15.5 檔案的隨機讀寫 281
15.5.1 fseek函式 281
15.5.2 rewind函式 283
15.5.3 ftell函式 283
15.6 檔案管理函式 284
15.6.1 刪除檔案 284
15.6.2 重命名檔案 285
15.6.3 複製檔案 285
15.7 檔案狀態檢測函式 286
15.7.1 feof函式 287
15.7.2 ferror函式 287
15.7.3 clearerr函式 287
15.8 Win32 API中的檔案操作函式 288
15.8.1 創建和打開檔案 288
15.8.2 讀取、寫入和刪除檔案 289
15.9 技術解惑 289
15.9.1 檔案指針是檔案內部的位置指針嗎 289
15.9.2 fseek函式的換行問題 290
15.9.3 怎樣解決gets函式的溢出問題 290
15.9.4 feof函式會多讀一個數據嗎 290
15.9.5 流和檔案的關係 290
15.10 課後練習 291
第16章 錯誤和程式調試 292
16.1 常見錯誤分析 293
16.1.1 語法錯誤 293
16.1.2 邏輯錯誤(語義錯誤) 294
16.1.3 記憶體錯誤 297
16.2 錯誤的檢出與分離 302
16.3 調試時的注意事項 303
16.3.1 上機前要先熟悉程式的運行環境 303
16.3.2 在編程時要為調試做好準備 304
16.4 技術解惑 304
16.4.1 編譯通過並不代表運行正確 304
16.4.2 兩段代碼的編譯差別 305
16.4.3 調試程式的方法與技巧 305
16.5 課後練習 307
第17章 記憶體管理 308
17.1 C語言中的記憶體模型 309
17.2 棧和堆 309
17.2.1 棧操作 309
17.2.2 堆操作 310
17.3 動態管理 311
17.3.2 使用函式calloc分配記憶體空間並初始化 312
17.3.3 使用函式realloc重新分配記憶體 313
17.3.4 使用函式free釋放記憶體空間 314
17.4 課後練習 315
第18章 C語言高級編程技術 316
18.1 C語言的高級編程技術 317
18.2 分析文本的螢幕輸出和鍵盤輸入 317
18.2.1 實現文本的螢幕輸出 317
18.2.2 實現鍵盤輸入 322
18.2.3 套用實例 323
18.3 分析圖形顯示方式和滑鼠輸入 324
18.3.1 初始化圖形模式 325
18.3.2 清屏和恢復顯示函式 326
18.3.3 建立獨立圖形程式 327
18.3.4 基本繪圖函式 327
18.3.5 線性函式 330
18.3.6 顏色控制函式 331
18.3.7 填色函式和畫圖函式 334
18.3.8 圖形視窗函式 336
18.3.9 分析圖形方式下的文本輸出函式 337
18.4 選單設計 340
18.5 課後練習 343
第19章 算法—抓住程式的靈魂 344
19.1 我們對算法的理解 345
19.1.1 算法是程式的靈魂 345
19.1.2 何謂算法 345
19.1.3 算法的特性 346
19.2 算法表示法—流程圖 347
19.3 枚舉算法 348
19.3.1 枚舉算法的基礎 348
19.3.2 實戰演練—百錢買百雞 348
19.3.3 實戰演練—填寫運算符 349
19.4 遞推算法 351
19.4.1 遞推算法的基礎 351
19.4.3 實戰演練—銀行存款 353
19.5 遞歸算法 354
19.5.1 遞歸算法的基礎 354
19.5.2 實戰演練—漢諾塔 355
19.5.3 實戰演練—階乘 357
19.6 分治算法 358
19.6.1 分治算法的基礎 358
19.6.2 實戰演練—大數相乘 358
19.6.3 實戰演練—歐洲冠軍杯
比賽日程安排 360
19.7 貪心算法 362
19.7.1 貪心算法的基礎 363
19.7.2 實戰演練—裝箱 363
19.7.3 實戰演練—找零方案 365
19.8 試探法算法 366
19.8.1 試探法算法的基礎 366
19.8.2 實戰演練—八皇后 367
19.8.3 實戰演練—體彩29選7的組合 368
19.9 疊代算法 370
19.9.1 疊代算法的基礎 370
19.9.2 實戰演練—求平方根 370
19.10 模擬算法 371
19.10.1 模擬算法的思路 371
19.10.2 實戰演練—猜數字遊戲 372
19.10.3 實戰演練—擲骰子 遊戲 372
19.11 技術解惑 374
19.11.1 衡量算法的標準 374
19.11.2 選擇使用枚舉法的時機 375
19.11.3 遞推和遞歸的差異 376
19.11.4 分治法解決問題的類型 376
19.11.5 分治算法的機理 376
19.11.6 貪婪算法並不是解決問題最優方案的原因 376
19.11.7 回溯算法是否會影響算法效率 377
19.11.8 遞歸算法與疊代算法的區別 377
19.12 課後練習 377
第20章 數據結構 379
20.1 使用線性表 380
20.1.1 線性表的特性 380
20.1.2 順序表操作 381
20.1.3 實戰演練—使用順序表操作函式 385
20.2 佇列 386
20.2.1 佇列的定義 386
20.2.2 實戰演練—實現一個排號程式 387
20.3 棧 390
20.3.1 棧的定義 390
20.3.2 實戰演練—實現棧操作 390
20.4 技術解惑 392
20.4.1 線性表插入操作的時間複雜度 392
20.4.2 線性表刪除操作的時間複雜度 392
20.4.3 線性表按值查找操作的時間複雜度 392
20.4.4 線性表連結存儲操作的11種算法 393
20.4.5 堆和棧的區別 397
20.5 課後練習 397
第21章 網路編程技術 398
21.1 OSI 7層網路模型 399
21.2 TCP/IP 400
21.2.1 IP 401
21.2.2 TCP 402
21.2.3 UDP 403
21.2.4 ICMP 403
21.3 使用C語言開發網路項目 404
21.3.1 網路編程方式 404
21.3.2 網路通信的基本流程 404
21.3.3 搭建開發環境 405
21.3.4 兩個常用的數據結構 405
21.3.5 Windows套接字的基礎 406
21.4 常用的Winsock函式 406
21.4.1 WSAStartup函式 406
21.4.3 inet_addr函式 407
21.4.4 gethostbyname函式 407
21.4.5 bind函式 407
21.4.6 connect函式 407
21.4.8 recv函式 408
21.4.9 sendto函式 408
21.5 MAC地址 408
21.6 NetBIOS編程 409
21.6.1 處理過程 409
21.6.2 NetBIOS命令 410
21.6.3 NetBIOS名字解析 410
21.6.4 NetBEUI 413
21.6.5 NetBIOS的範圍 413
21.6.6 NetBIOS控制塊 413
21.7 實戰演練—獲取當前機器的MAC地址 413
21.7.1 選擇開發工具 413
21.7.2 設計MFC窗體 414
21.7.3 具體編碼 414
第22章 初入江湖—設計遊戲項目 421
22.1 遊戲功能描述 422
22.2 遊戲總體設計 422
22.2.1 功能模組設計 422
22.2.2 數據結構設計 424
22.2.3 構成函式介紹 425
22.3 遊戲的具體實現 426
22.3.1 預處理 426
22.3.2 主函式 429
22.3.3 初始化界面處理 430
22.3.4 時鐘中斷處理 431
22.3.5 成績、速度和幫助處理 431
22.3.6 滿行處理 432
22.3.7 方塊顯示和消除處理 434
22.3.8 方塊判斷處理 435
第23章 風雲再起—設計網路項目 438
23.1 系統功能描述 439
23.2 系統總體設計 439
23.2.1 功能模組設計 439
23.2.2 數據結構設計 441
23.2.3 構成函式介紹 442
23.3 系統的具體實現 442
23.3.1 預處理 442
23.3.2 初始化處理 444
23.3.3 控制模組 444
23.3.4 數據報解讀處理 446
23.3.5 Ping測試處理 447
23.3.6 主函式 449
第24章 爐火純青—學生成績管理系統 451
24.1 系統總體描述 452
24.1.1 項目開發的目標 452
24.1.2 項目的意義 452
24.1.3 系統功能描述 452
24.2 系統總體設計 453
24.2.1 功能模組設計 453
24.2.2 數據結構設計 454
24.2.3 構成函式介紹 455
24.3 系統的具體實現 456
24.3.1 預處理 456
24.3.2 主函式 457
24.3.3 系統主選單函式 458
24.3.4 表格顯示信息 458
24.3.5 信息查找定位 459
24.3.6 格式化輸入數據 459
24.3.7 增加學生記錄 460
24.3.8 查詢學生記錄 461
24.3.9 刪除學生記錄 462
24.3.10 修改學生記錄 463
24.3.11 插入學生記錄 463
24.3.12 統計學生記錄 464
24.3.13 排序處理 465
24.3.14 存儲學生信息 466
第25章 笑傲江湖—使用C51實現跑馬燈程式 471
25.1 單片機C語言基礎 472
25.1.1 單片機C語言的優越性 472