第1章 c語言概述 1
1.1 c語言的歷史 1
1.1.1 起源 1
1.1.2 標準化 1
1.1.3 基於c的語言 2
1.2 c語言的優缺點 3
1.2.1 c語言的優點 3
1.2.2 c語言的缺點 3
1.2.3 高效地使用c語言 4
問與答 5
第2章 c語言基本概念 7
2.1 編寫壹個簡單的c程序 7
程序 顯示雙關語 7
2.1.1 編譯和鏈接 8
2.1.2 集成開發環境 8
2.2 簡單程序的壹般形式 9
2.2.1 指令 9
2.2.2 函數 9
2.2.3 語句 10
2.2.4 顯示字符串 10
.2.3 註釋 11
2.4 變量和賦值 12
2.4.1 類型 12
2.4.2 聲明 13
2.4.3 賦值 13
2.4.4 顯示變量的值 14
程序 計算箱子的空間重量 14
2.4.5 初始化 15
2.4.6 顯示表達式的值 16
2.5 讀入輸入 16
程序 計算箱子的空間重量(改進版) 16
2.6 定義常量的名字 17
程序 華氏溫度轉換為攝氏溫度 17
2.7 標識符 18
2.8 c程序的書寫規範 19
問與答 21
練習題 23
編程題 24
第3章 格式化輸入/輸出 26
3.1 printf函數 26
3.1.1 轉換說明 27
程序 用printf函數格式化數 28
3.1.2 轉義序列 28
3.2 scanf函數 29
3.2.1 scanf函數的工作方法 30
3.2.2 格式串中的普通字符 31
3.2.3 易混淆的printf函數和scanf
函數 32
程序 分數相加 32
問與答 33
練習題 34
編程題 35
第4章 表達式 36
4.1 算術運算符 36
程序 計算通用產品代碼的校驗位 38
4.2 賦值運算符 39
4.2.1 簡單賦值 40
4.2.2 左值 41
4.2.3 復合賦值 41
4.3 自增運算符和自減運算符 42
4.4 表達式求值 43
4.5 表達式語句 45
問與答 45
練習題 47
編程題 49
第5章 選擇語句 50
5.1 邏輯表達式 50
5.1.1 關系運算符 50
5.1.2 判等運算符 51
5.1.3 邏輯運算符 51
5.2 if語句 52
5.2.1 復合語句 53
5.2.2 else子句 53
5.2.3 級聯式if語句 54
程序 計算股票經紀人的傭金 55
5.2.4 “懸空else”的問題 56
5.2.5 條件表達式 57
5.2.6 c89中的布爾值 58
5.2.7 c99中的布爾值 58
5.3 switch語句 59
程序 顯示法定格式的日期 61
問與答 62
練習題 65
編程題 67
第6章 循環 69
6.1 while語句 69
程序 顯示平方表 71
程序 數列求和 71
6.2 do語句 72
程序 計算整數的位數 73
6.3 for語句 73
6.3.1 for語句的慣用法 74
6.3.2 在for語句中省略表達式 75
6.3.3 c99中的for語句 75
6.3.4 逗號運算符 76
程序 顯示平方表(改進版) 77
6.4 退出循環 78
6.4.1 break語句 78
6.4.2 continue語句 78
6.4.3 goto語句 79
程序 賬簿結算 80
6.5 空語句 81
問與答 83
練習題 84
編程題 85
第7章 基本類型 88
7.1 整數類型 88
7.1.1 c99中的整數類型 90
7.1.2 整數常量 90
7.1.3 c99中的整數常量 91
7.1.4 整數溢出 91
7.1.5 讀/寫整數 91
程序 數列求和(改進版) 92
7.2 浮點類型 93
7.2.1 浮點常量 94
7.2.2 讀/寫浮點數 94
7.3 字符類型 94
7.3.1 字符操作 95
7.3.2 有符號字符和無符號字符 95
7.3.3 算術類型 96
7.3.4 轉義序列 96
7.3.5 字符處理函數 97
7.3.6 用scanf和printf讀/寫字符 98
7.3.7 用getchar和putchar讀/寫
字符 98
程序 確定消息的長度 99
7.4 類型轉換 100
7.4.1 常用算術轉換 101
7.4.2 賦值過程中的轉換 102
7.4.3 c99中的隱式轉換 103
7.4.4 強制類型轉換 103
7.5 類型定義 105
7.5.1 類型定義的優點 105
7.5.2 類型定義和可移植性 105
7.6 sizeof運算符 106
問與答 107
練習題 109
編程題 110
第8章 數組 113
8.1 壹維數組 113
8.1.1 數組下標 113
程序 數列反向 115
8.1.2 數組初始化 115
8.1.3 指定初始化式 116
程序 檢查數中重復出現的數字 116
8.1.4 對數組使用sizeof運算符 117
程序 計算利息 118
8.2 多維數組 119
8.2.1 多維數組初始化 120
8.2.2 常量數組 121
程序 發牌 121
8.3 c99中的變長數組 122
問與答 123
練習題 124
編程題 125
第9章 函數 129
9.1 函數的定義和調用 129
程序 計算平均值 129
程序 顯示倒計數 130
程序 顯示雙關語(改進版) 131
9.1.1 函數定義 132
9.1.2 函數調用 133
程序 判定素數 134
9.2 函數聲明 135
9.3 實際參數 136
9.3.1 實際參數的轉換 137
9.3.2 數組型實際參數 138
9.3.3 變長數組形式參數 140
9.3.4 在數組參數聲明中使用
static 141
9.3.5 復合字面量 141
9.4 return語句 142
9.5 程序終止 143
9.6 遞歸 144
程序 快速排序 146
問與答 147
練習題 150
編程題 153
第10章 程序結構 155
10.1 局部變量 155
10.1.1 靜態局部變量 156
10.1.2 形式參數 156
10.2 外部變量 156
10.2.1 示例:用外部變量實現棧 156
10.2.2 外部變量的利與弊 157
程序 猜數 158
10.3 程序塊 161
10.4 作用域 162
10.5 構建c程序 163
程序 給壹手牌分類 163
問與答 169
練習題 169
編程題 170
第11章 指針 172
11.1 指針變量 172
11.2 取地址運算符和間接尋址運算符 173
11.2.1 取地址運算符 173
11.2.2 間接尋址運算符 174
11.3 指針賦值 174
11.4 指針作為參數 176
程序 找出數組中的最大元素和最
小元素 177
11.5 指針作為返回值 179
問與答 180
練習題 181
編程題 182
第12章 指針和數組 184
12.1 指針的算術運算 184
12.1.1 指針加上整數 185
12.1.2 指針減去整數 185
12.1.3 兩個指針相減 186
12.1.4 指針比較 186
12.1.5 指向復合常量的指針 186
12.2 指針用於數組處理 186
12.3 用數組名作為指針 188
程序 數列反向(改進版) 189
12.3.1 數組型實際參數(改進版) 189
12.3.2 用指針作為數組名 191
12.4 指針和多維數組 191
12.4.1 處理多維數組的元素 191
12.4.2 處理多維數組的行 192
12.4.3 處理多維數組的列 192
12.4.4 用多維數組名作為指針 192
12.5 c99中的指針和變長數組 193
問與答 194
練習題 195
編程題 197
第13章 字符串 198
13.1 字符串字面量 198
13.1.1 字符串字面量中的轉義序列 198
13.1.2 延續字符串字面量 199
13.1.3 如何存儲字符串字面量 199
13.1.4 字符串字面量的操作 200
13.1.5 字符串字面量與字符常量 200
13.2 字符串變量 200
13.2.1 初始化字符串變量 201
13.2.2 字符數組與字符指針 202
13.3 字符串的讀和寫 203
13.3.1 用printf函數和puts函數
寫字符串 203
13.3.2 用scanf函數和gets函數讀
字符串 203
13.3.3 逐個字符讀字符串 204
13.4 訪問字符串中的字符 205
13.5 使用c語言的字符串庫 206
13.5.1 strcpy函數 207
13.5.2 strlen函數 208
13.5.3 strcat函數 208
13.5.4 strcmp函數 209
程序 顯示壹個月的提醒列表 209
13.6 字符串慣用法 211
13.6.1 搜索字符串的結尾 211
13.6.2 復制字符串 213
13.7 字符串數組 214
程序 核對行星的名字 217
問與答 218
練習題 220
編程題 222
第14章 預處理器 225
14.1 預處理器的工作原理 225
14.2 預處理指令 227
14.3 宏定義 227
14.3.1 簡單的宏 227
14.3.2 帶參數的宏 229
14.3.3 #運算符 231
14.3.4 ##運算符 231
14.3.5 宏的通用屬性 232
14.3.6 宏定義中的圓括號 233
14.3.7 創建較長的宏 233
14.3.8 預定義宏 234
14.3.9 c99中新增的預定義宏 235
14.3.10 空的宏參數 236
14.3.11 參數個數可變的宏 236
14.3.12 __func__標識符 237
14.4 條件編譯 237
14.4.1 #if指令和#endif指令 238
14.4.2 defined運算符 238
14.4.3 #ifdef指令和#ifndef
指令 239
14.4.4 #elif指令和#else指令 239
14.4.5 使用條件編譯 240
14.5 其他指令 240
14.5.1 #error指令 240
14.5.2 #line指令 241
14.5.3 #pragma指令 242
14.5.4 _pragma運算符 242
問與答 243
練習題 245
第15章 編寫大型程序 248
15.1 源文件 248
15.2 頭文件 249
15.2.1 #include指令 249
15.2.2 ***享宏定義和類型定義 250
15.2.3 ***享函數原型 251
15.2.4 ***享變量聲明 252
15.2.5 嵌套包含 253
15.2.6 保護頭文件 253
15.2.7 頭文件中的#error指令 254
15.3 把程序劃分成多個文件 254
程序 文本格式化 255
15.4 構建多文件程序 260
15.4.1 makefile 260
15.4.2 鏈接期間的錯誤 262
15.4.3 重新構建程序 262
15.4.4 在程序外定義宏 264
問與答 264
練習題 265
編程題 266
第16章 結構、聯合和枚舉 267
16.1 結構變量 267
16.1.1 結構變量的聲明 267
16.1.2 結構變量的初始化 269
16.1.3 指定初始化 269
16.1.4 對結構的操作 270
16.2 結構類型 270
16.2.1 結構標記的聲明 271
16.2.2 結構類型的定義 272
16.2.3 結構作為參數和返回值 272
16.2.4 復合字面量 273
16.3 嵌套的數組和結構 274
16.3.1 嵌套的結構 274
16.3.2 結構數組 274
16.3.3 結構數組的初始化 275
程序 維護零件數據庫 275
16.4 聯合 281
16.4.1 用聯合來節省空間 282
16.4.2 用聯合來構造混合的數據
結構 284
16.4.3 為聯合添加“標記字段” 284
16.5 枚舉 285
16.5.1 枚舉標記和類型名 286
16.5.2 枚舉作為整數 286
16.5.3 用枚舉聲明“標記字段” 286
問與答 287
練習題 289
編程題 293
第17章 指針的高級應用 294
17.1 動態存儲分配 294
17.1.1 內存分配函數 294
17.1.2 空指針 295
17.2 動態分配字符串 296
17.2.1 使用malloc函數為字符串
分配內存 296
17.2.2 在字符串函數中使用動態
存儲分配 296
17.2.3 動態分配字符串的數組 297
程序 顯示壹個月的提醒列表
(改進版) 297
17.3 動態分配數組 299
17.3.1 使用malloc函數為數組分配
存儲空間 299
17.3.2 calloc函數 300
17.3.3 realloc函數 300
17.4 釋放存儲空間 301
17.4.1 free函數 301
17.4.2 “懸空指針”問題 301
17.5 鏈表 302
17.5.1 聲明結點類型 302
17.5.2 創建結點 303
17.5.3 -)運算符 303
17.5.4 在鏈表的開始處插入結點 304
17.5.5 搜索鏈表 306
17.5.6 從鏈表中刪除結點 307
17.5.7 有序鏈表 308
程序 維護零件數據庫(改進版) 309
17.6 指向指針的指針 313
17.7 指向函數的指針 314
17.7.1 函數指針作為參數 314
17.7.2 qsort函數 314
17.7.3 函數指針的其他用途 316
程序 列三角函數表 317
17.8 受限指針 318
17.9 靈活數組成員 319
問與答 320
練習題 323
編程題 325
第18章 聲明 327
18.1 聲明的語法 327
18.2 存儲類型 328
18.2.1 變量的性質 328
18.2.2 auto存儲類型 329
18.2.3 static存儲類型 329
18.2.4 extern存儲類型 330
18.2.5 register存儲類型 331
18.2.6 函數的存儲類型 332
18.2.7 小結 332
18.3 類型限定符 333
18.4 聲明符 334
18.4.1 解釋復雜聲明 335
18.4.2 使用類型定義來簡化聲明 336
18.5 初始化式 336
18.6 內聯函數 337
18.6.1 內聯定義 338
18.6.2 對內聯函數的限制 339
18.6.3 在gcc中使用內聯函數 339
問與答 339
練習題 342
第19章 程序設計 345
19.1 模塊 345
19.1.1 內聚性與耦合性 347
19.1.2 模塊的類型 347
19.2 信息隱藏 347
19.3 抽象數據類型 350
19.3.1 封裝 351
19.3.2 不完整類型 351
19.4 棧抽象數據類型 352
19.4.1 為棧抽象數據類型定義接口 352
19.4.2 用定長數組實現棧抽象數據
類型 353
19.4.3 改變棧抽象數據類型中數據
項的類型 354
19.4.4 用動態數組實現棧抽象數據
類型 355
19.4.5 用鏈表實現棧抽象數據類型 357
19.5 抽象數據類型的設計問題 359
19.5.1 命名慣例 359
19.5.2 錯誤處理 359
19.5.3 通用抽象數據類型 359
19.5.4 新語言中的抽象數據類型 360
問與答 360
練習題 361
編程題 362
第20章 底層程序設計 363
20.1 位運算符 363
20.1.1 移位運算符 363
20.1.2 按位求反運算符、按位與運
算符、按位異或運算符和按
位或運算符 364
20.1.3 用位運算符訪問位 365
20.1.4 用位運算符訪問位域 366
程序 xor加密 366
20.2 結構中的位域 367
20.3 其他底層技術 369
20.3.1 定義依賴機器的類型 369
20.3.2 用聯合提供數據的多個視角 370
20.3.3 將指針作為地址使用 371
程序 查看內存單元 371
20.3.4 volatile類型限定符 373
問與答 374
練習題 374
編程題 376
第21章 標準庫 377
21.1 標準庫的使用 377
21.1.1 對標準庫中所用名字的
限制 377
21.1.2 使用宏隱藏的函數 378
21.2 c89標準庫概述 378
21.3 c99標準庫更新 380
21.4 (stddef.h):常用定義 381
21.5 (stdbool.h):布爾類型和值 381
問與答 382
練習題 382
編程題 383
第22章 輸入/輸出 384
22.1 流 384
22.1.1 文件指針 385
22.1.2 標準流和重定向 385
22.1.3 文本文件與二進制文件 385
22.2 文件操作 386
22.2.1 打開文件 386
22.2.2 模式 387
22.2.3 關閉文件 388
22.2.4 為打開的流附加文件 389
22.2.5 從命令行獲取文件名 389
程序 檢查文件是否可以打開 389
22.2.6 臨時文件 390
22.2.7 文件緩沖 391
22.2.8 其他文件操作 392
22.3 格式化的輸入/輸出 393
22.3.1 …printf函數 393
22.3.2 …printf轉換說明 393
22.3.3 c99對…printf轉換說明的
修改 395
22.3.4 …printf轉換說明示例 396
22.3.5 …scanf函數 398
22.3.6 …scanf格式串 398
22.3.7 …scanf轉換說明 398
22.3.8 c99對...scanf轉換說明的
改變 400
22.3.9 scanf示例 400
22.3.10 檢測文件末尾和錯誤條件 401
22.4 字符的輸入/輸出 403
22.4.1 輸出函數 403
22.4.2 輸入函數 403
程序 復制文件 404
22.5 行的輸入/輸出 405
22.5.1 輸出函數 405
22.5.2 輸入函數 406
22.6 塊的輸入/輸出 406
22.7 文件定位 407
程序 修改零件記錄文件 409
22.8 字符串的輸入/輸出 409
22.8.1 輸出函數 410
22.8.2 輸入函數 410
問與答 411
練習題 414
編程題 416
第23章 庫對數值和字符數據的支持 419
23.1 (float.h):浮點類型的特性 419
23.2 (limits.h):整數類型的大小 421
23.3 (math.h):數學計算(c89) 422
23.3.1 錯誤 422
23.3.2 三角函數 422
23.3.3 雙曲函數 423
23.3.4 指數函數和對數函數 423
23.3.5 冪函數 424
23.3.6 就近取整函數、絕對值函數
和取余函數 424
23.4 (math.h):數學計算(c99) 425
23.4.1 ieee浮點標準 425
23.4.2 類型 426
23.4.3 宏 426
23.4.4 錯誤 426
23.4.5 函數 427
23.4.6 分類宏 427
23.4.7 三角函數 428
23.4.8 雙曲函數 428
23.4.9 指數函數和對數函數 429
23.4.10 冪函數和絕對值函數 430
23.4.11 誤差函數和伽瑪函數 430
23.4.12 就近取整函數 431
23.4.13 取余函數 432
23.4.14 操作函數 432
23.4.15 最大值函數、最小值函數
和正差函數 433
23.4.16 浮點乘加 433
23.4.17 比較宏 434
23.5 (ctype.h):字符處理 434
23.5.1 字符分類函數 435
程序 測試字符分類函數 436
23.5.2 字符大小寫映射函數 437
程序 測試大小寫映射函數 437
23.6 (string.h):字符串處理 437
23.6.1 復制函數 437
23.6.2 拼接函數 438
23.6.3 比較函數 439
23.6.4 搜索函數 440
23.6.5 其他函數 442
問與答 442
練習題 443
編程題 444
第24章 錯誤處理 446
24.1 (assert.h):診斷 446
24.2 (errno.h):錯誤 447
24.3 (signal.h):信號處理 448
24.3.1 信號宏 449
24.3.2 signal函數 449
24.3.3 預定義的信號處理函數 450
24.3.4 raise函數 450
程序 測試信號 451
24.4 (setjmp.h):非局部跳轉 452
程序 測試setjmp和longjmp 452
問與答 453
練習題 454
第25章 國際化特性 456
25.1 (locale.h):本地化 456
25.1.1 類別 456
25.1.2 setlocale函數 457
25.1.3 localeconv函數 458
25.2 多字節字符和寬字符 461
25.2.1 多字節字符 461
25.2.2 寬字符 461
25.2.3 統壹碼和通用字符集 462
25.2.4 統壹碼編碼 462
25.2.5 多字節/寬字符轉換函數 463
25.2.6 多字節/寬字符串轉換函數 465
25.3 雙字符和三字符 465
25.3.1 三字符 465
25.3.2 雙字符 466
25.3.3 (iso646.h):拼寫替換 467
25.4 通用字符名 467
25.5 (wchar.h):擴展的多字節和寬字符
實用工具 467
25.5.1 流傾向 468
25.5.2 格式化寬字符輸入/輸出
函數 468
25.5.3 寬字符輸入/輸出函數 470
25.5.4 通用的寬字符串實用工具 471
25.5.5 寬字符時間轉換函數 474
25.5.6 擴展的多字節/寬字符轉換
實用工具 474
25.6 (wctype.h):寬字符分類和映射實
用工具 477
25.6.1 寬字符分類函數 477
25.6.2 可擴展的寬字符分類函數 478
25.6.3 寬字符大小寫映射函數 478
25.6.4 可擴展的寬字符大小寫映射
函數 478
問與答 479
練習題 479
編程題 480
第26章 其他庫函數 482
26.1 (stdarg.h):可變參數 482
26.1.1 調用帶有可變參數列表的
函數 483
26.1.2 v…printf函數 484
26.1.3 v…scanf函數 485
26.2 (stdlib.h):通用的實用工具 485
26.2.1 數值轉換函數 485
程序 測試數值轉換函數 486
26.2.2 偽隨機序列生成函數 488
程序 測試偽隨機序列生成函數 488
26.2.3 與環境的通信 489
26.2.4 搜索和排序實用工具 490
程序 確定航空裏程 491
26.2.5 整數算術運算函數 492
26.3 (time.h):日期和時間 492
26.3.1 時間處理函數 493
26.3.2 時間轉換函數 495
程序 顯示日期和時間 498
問與答 500
練習題 501
編程題 502
第27章 c99對數學計算的新增支持 503
27.1 (stdint.h):整數類型 503
27.1.1 (stdint.h)類型 503
27.1.2 對指定寬度整數類型的限制 504
27.1.3 對其他整數類型的限制 505
27.1.4 用於整數常量的宏 505
27.2 (inttypes.h):整數類型的格式
轉換 506
27.2.1 用於格式說明符的宏 506
27.2.2 用於最大寬度整數類型的
函數 507
27.3 復數 508
27.3.1 復數的定義 508
27.3.2 復數的算術運算 509
27.3.3 c99中的復數類型 509
27.3.4 復數的運算 510
27.3.5 復數類型的轉換規則 510
27.4 (complex.h):復數算術運算 511
27.4.1 (complex.h)宏 511
27.4.2 cx_limited_range編譯
提示 512
27.4.3 (complex.h)函數 512
27.4.4 三角函數 512
27.4.5 雙曲函數 513
27.4.6 指數函數和對數函數 514
27.4.7 冪函數和絕對值函數 514
27.4.8 操作函數 514
程序 求二次方程的根 515
27.5 (tgmath.h):泛型數學 515
27.5.1 泛型宏 516
27.5.2 調用泛型宏 517
27.6 (fenv.h):浮點環境 518
27.6.1 浮點狀態標誌和控制模式 518
27.6.2 (fenv.h)宏 519
27.6.3 fenv_access編譯提示 519
27.6.4 浮點異常函數 520
27.6.5 舍入函數 520
27.6.6 環境函數 521
問與答 521
練習題 522
編程題 523
附錄a c語言運算符 524
附錄b c99與c89的比較 525
附錄c c89與經典c的比較 529
附錄d 標準庫函數 532
附錄e ascii字符集 569
參考文獻 570
索引 573