本書以學完C語言之后知道能做什么為編寫目標,共12章: Linux C語言程序設計、C語言基礎Ⅰ、C語言基礎Ⅱ、編譯與調試、鏈表、C標準庫、Linux系統(tǒng)調用、Socket編程、Linux函數(shù)庫和進程地址空間、Pthreads編程、GTK圖形界面編程、Linux內核編程。其中,C語言基礎Ⅰ、C語言基礎Ⅱ、C標準庫與Linux系統(tǒng)調用為本書最基礎、最重要的4章,全面介紹了標準C的基本語法和Linux系統(tǒng)調用編程。其他章節(jié)告訴讀者C語言具體能做什么。本書堅守Talk is cheap, show me the code信條,通過正確無誤的示例代碼向讀者展示C語言的具體用法。本書內容注重實用,結構清晰,圖文并茂,力求做到使讀者感興趣地學習Linux C語言編程。 本書可作為高等學校各專業(yè)的C語言程序設計課程教材,也可作為從事計算機相關工作的科技人員、計算機愛好者及各類自學人員的參考書。
本書作者多年來一直從事Linux教學和科研工作,使用C語言開發(fā)了多個Linux相關的橫向縱向項目。本書全面介紹了Linux C語言程序設計的多個方面,包括C語言程序設計的基礎知識,以及C標準庫、Linux系統(tǒng)調用、socket、pthread、GTK、靜態(tài)庫和共享庫的使用和編寫,另外,還介紹了Linux內核編程。通過本書的學習,讀者將成為一名全棧式Linux C語言開發(fā)人員。
C語言是目前較為流行的高級程序設計語言之一,是許多計算機專業(yè)人員和計算機愛好者學習程序設計的首選語言。但是,很多學過C語言的讀者在學習C語言之前以及學習過程中經常會問: 學習C語言能做什么?學完C語言之后感慨道: 學完C語言之后仍然不知道能做什么。其實,編者認為學習C語言有兩個目標: 第一,為學習其他編程語言打下堅實的基礎。因為計算機編程語言都是相通的,學好C語言再學習其他高級程序設計語言會很容易。這也是很多C語言教材能夠達到的目標。所以,那些學完C語言之后仍然不知道能做什么的讀者已經具備計算機編程基礎了。本書的第2、3、6、7章可以達到該目標。第二,真正使用C語言開發(fā)有實際意義的程序。這正是本書所追求的目標。希望使用C語言開發(fā)有實際意義的程序,就要清楚目前C語言的真正應用場景。目前市面上絕大多數(shù)操作系統(tǒng)都是用C語言編寫的。很多基礎軟件,如編譯器、數(shù)據(jù)庫、虛擬機、多媒體庫、圖形庫等,也都是用C語言實現(xiàn)的。很多流行的編程語言也是用C語言實現(xiàn)的,如Lua、Python腳本語言等。在嵌入式系統(tǒng)開發(fā)中,比如固件、BSP、內核驅動等,除少量匯編代碼,大部分都是用C語言開發(fā)的;ヂ(lián)網中的很多服務器程序也是用C語言開發(fā)的。總之,在整個計算機軟件世界中,C語言發(fā)揮著中流砥柱的作用。讀者可能對Linux不熟悉,但是,Linux早已深刻影響著我們生活的方方面面,從超級計算機、巨型機,到智能手機(Android),再到各種家電和嵌入式設備,內部都運行著Linux。另外,Linux支撐起了整個因特網。C語言和Linux操作系統(tǒng)有密不可分的血緣關系,因此本書的主要目標是幫助讀者掌握基于Linux的各種軟件的C語言開發(fā)方法,為讀者以后步入廣闊無垠的Linux世界打下堅實的基礎。編者堅信Linux之父、天才程序員Linus Torvalds所說: Talk is cheap, show me the code。考慮到有些讀者之前沒有接觸過Linux操作系統(tǒng),因此,讀者可以根據(jù)本書的第一個視頻安裝Linux虛擬機,搭建Linux C語言編程環(huán)境。
本書提供配套課件、教學大綱和習題參考答案等多種教學資源,還提供了94個微課視頻,讀者在學習過程中,掃描教學視頻二維碼可以觀看視頻。
本書由北京郵電大學計算機專業(yè)博士張同光擔任主編,田文強、荊春棋、田喬梅、陳明擔任副主編,參加編寫的人員還有洪雙喜、劉春紅、秦建保。洪雙喜和劉春紅工作于河南師范大學,陳明工作于鄭州輕工業(yè)大學,其他編者工作于新鄉(xiāng)學院。其中,洪雙喜和劉春紅編寫第1章,田文強、荊春棋和陳明共同編寫第2~5章和附錄A,張同光編寫第6~10章,田喬梅編寫第11章,秦建保編寫第12章。全書由張同光(jsjoscpu@163.com)統(tǒng)稿和定稿。
本書得到河南省高等教育教學改革研究與實踐重點項目(NO.2021SJGLX106)、河南省科技攻關項目(NO.202102210146)、網絡與交換技術國家重點實驗室開放課題(SKLNST2020101)以及高效能服務器和存儲技術國家重點實驗室的支持,在此表示感謝。
在本書的編寫過程中,得到清華大學出版社的大力支持和幫助,在此表示衷心的感謝。
由于編者水平有限,書中欠妥之處,敬請廣大讀者批評指正。
編者
2023年6月
第1章Linux C語言程序設計/1
1.1C語言/1
1.1.1C語言簡介/1
1.1.2C語言的發(fā)展歷史/2
1.1.3C語言的特點/2
1.2Linux概述/3
1.3Linux C語言程序設計簡介/4
1.3.1Linux應用編程、系統(tǒng)編程和內核編程/4
1.3.2Linux圖形界面編程/4
1.4Linux C語言編程環(huán)境/5
1.4.1Ubuntu Linux虛擬機/5
1.4.2gedit、vim和nano/5
1.4.3C語言編譯器及集成開發(fā)環(huán)境/6
1.4.4Hello World程序/6
1.5習題/7
第2章C語言基礎Ⅰ/9
2.1數(shù)據(jù)/9
2.1.1數(shù)據(jù)類型/9
2.1.2常量/11
2.1.3變量和標識符/13
2.1.4數(shù)據(jù)類型轉換/14
2.1.5轉義字符(轉義序列)/15
2.2運算符/16
2.2.1運算符和表達式/16
2.2.2算術運算/18
2.2.3賦值運算/18
2.2.4關系運算/19
2.2.5邏輯運算符/19
2.2.6條件運算符/20
2.2.7逗號運算符/20
2.2.8sizeof運算符與typedef類型聲明/21
2.2.9位運算/21
2.2.10復合賦值運算符/22
2.3結構化程序設計/23
2.3.1順序結構/23
2.3.2分支結構/24
2.3.3循環(huán)結構/26
2.4輸入/輸出/29
2.4.1標準輸出函數(shù)printf/30
2.4.2標準輸入函數(shù)scanf/32
2.5數(shù)組/34
2.5.1一維數(shù)組/34
2.5.2二維數(shù)組/35
2.5.3一維字符數(shù)組/36
2.5.4一維字符數(shù)組的輸入/輸出/36
2.5.5字符串處理函數(shù)/37
2.5.6二維字符數(shù)組/39
2.6習題/40
第3章C語言基礎II/44
3.1函數(shù)/44
3.1.1C語言庫函數(shù)/44
3.1.2函數(shù)定義和聲明/44
3.1.3函數(shù)調用及參數(shù)傳遞/46
3.1.4函數(shù)的嵌套與遞歸/49
3.1.5回調函數(shù)/50
3.1.6return語句/50
3.1.7全局變量、局部變量和作用域/51
3.1.8變量的存儲類別及生存期/52
3.1.9內部函數(shù)和外部函數(shù)/54
3.2預處理/54
3.2.1預處理的步驟/54
3.2.2宏定義和內聯(lián)函數(shù)/55
3.2.3條件編譯/57
3.2.4文件包含/57
3.3指針/58
3.3.1指針的基本運算/58
3.3.2指針與數(shù)組/61
3.3.3指針與const限定符/64
3.3.4指針與字符串/65
3.3.5指針函數(shù)與函數(shù)指針/65
3.3.6再講回調函數(shù)/66
3.3.7可變參數(shù)/67
3.3.8二級指針與多級指針/68
3.3.9指針數(shù)組和數(shù)組指針/69
3.3.10動態(tài)內存管理/70
3.4結構體、共用體和枚舉/71
3.4.1結構體/71
3.4.2位域/72
3.4.3共用體/73
3.4.4枚舉/74
3.5零長數(shù)組、變長數(shù)組和動態(tài)數(shù)組/75
3.6編碼風格與縮進工具indent/77
3.7習題/79
第4章編譯與調試/82
4.1gcc、make、Makefile、cmake和CMakeLists.txt/82
4.1.1gcc/82
4.1.2make和Makefile/84
4.1.3cmake和CMakeLists.txt/90
4.2完整的編譯過程/90
4.3調試程序/92
4.3.1調試(Debug)和GDB/92
4.3.2測試用例/93
4.3.3GDB啟動程序/93
4.3.4斷點/94
4.3.5觀察點/95
4.3.6捕捉點/96
4.3.7信號/96
4.3.8單步調試/97
4.3.9打印輸出/97
4.3.10函數(shù)棧幀/99
4.3.11TUI窗口/100
4.3.12函數(shù)跳轉/101
4.3.13段錯誤/101
4.3.14coredump/101
4.3.15調試正在運行的程序/102
4.3.16調試多進程和多線程/103
4.3.17gdb使用示例/105
4.4習題/105
第5章鏈表/107
5.1單向鏈表/107
5.1.1單鏈表結構與鏈表結點類型/107
5.1.2創(chuàng)建單鏈表/108
5.1.3插入結點/109
5.1.4刪除結點/109
5.1.5讀取結點/110
5.1.6查找結點/110
5.1.7打印單鏈表/110
5.1.8逆轉單鏈表/111
5.1.9構建單向循環(huán)鏈表/111
5.1.10銷毀單鏈表/112
5.1.11主函數(shù)及測試結果/112
5.2雙向鏈表/113
5.2.1雙鏈表結構與鏈表結點類型/113
5.2.2創(chuàng)建雙鏈表/113
5.2.3插入結點/115
5.2.4刪除結點/115
5.2.5讀取結點/116
5.2.6查找結點/116
5.2.7打印雙鏈表/116
5.2.8逆轉雙鏈表/117
5.2.9構建雙向循環(huán)鏈表/117
5.2.10銷毀雙向循環(huán)鏈表/118
5.2.11主函數(shù)及測試結果/118
5.3內核鏈表/119
5.3.1list_head/119
5.3.2offsetof、container_of和list_entry/120
5.3.3鏈表初始化/120
5.3.4插入結點/121
5.3.5刪除結點/121
5.3.6替換結點/122
5.3.7移動結點/122
5.3.8判斷函數(shù)/123
5.3.9合并結點/123
5.3.10遍歷鏈表/124
5.3.11用戶空間使用內核鏈表/124
5.4習題/125
第6章C標準庫/127
6.1C語言標準和glibc/127
6.2標準輸入/輸出函數(shù)庫/129
6.2.1fopen/fclose/130
6.2.2stdin/stdout/stderr/132
6.2.3errno與perror函數(shù)/132
6.2.4以字節(jié)為單位的I/O函數(shù)/133
6.2.5以字符串為單位的I/O函數(shù)/135
6.2.6以記錄為單位的I/O函數(shù)/136
6.2.7格式化讀寫文件/137
6.2.8操作讀寫位置的函數(shù)/138
6.2.9FILE結構體及I/O緩沖區(qū)/140
6.3標準工具函數(shù)庫/143
6.3.1動態(tài)內存分配與釋放/144
6.3.2整數(shù)算術/145
6.3.3隨機數(shù)/146
6.3.4數(shù)值字符串轉換/147
6.3.5寬字符和多字節(jié)字符轉換/148
6.4字符串處理函數(shù)庫/152
6.4.1內存賦值/152
6.4.2取字符串的長度/153
6.4.3復制字符串/153
6.4.4比較字符串/154
6.4.5搜索字符串/155
6.4.6連接字符串/156
6.4.7分割字符串/157
6.4.8本地函數(shù)/158
6.5字符處理函數(shù)庫/160
6.6數(shù)學函數(shù)庫/161
6.7學生信息管理系統(tǒng)的設計與實現(xiàn)/163
6.7.1系統(tǒng)設計要求/163
6.7.2系統(tǒng)設計/163
6.7.3函數(shù)設計/164
6.7.4參考程序/165
6.7.5運行結果/168
6.8習題/168
第7章Linux系統(tǒng)調用/171
7.1C庫函數(shù)和Linux系統(tǒng)調用/171
7.2Linux中使用系統(tǒng)調用的三種方法/173
7.2.1通過glibc封裝的庫函數(shù)/173
7.2.2使用syscall直接調用/173
7.2.3通過CPU指令調用/173
7.3Linux系統(tǒng)調用編程: 進程管理/174
7.4Linux系統(tǒng)調用編程: 進程間通信/177
7.5Linux系統(tǒng)調用編程: exec函數(shù)族/179
7.6Linux系統(tǒng)調用編程: 文件管理/181
7.7習題/188
第8章Socket編程/190
8.1Socket基本概念/190
8.1.1Socket是什么/190
8.1.2主機字節(jié)序與網絡字節(jié)序/191
8.1.3Socket地址結構/192
8.1.4地址轉換函數(shù)/194
8.1.5C/S架構/195
8.2Socket相關函數(shù)/196
8.2.1socket函數(shù)/196
8.2.2bind函數(shù)/196
8.2.3listen/connect函數(shù)/196
8.2.4accept函數(shù)/197
8.2.5網絡I/O函數(shù)/198
8.2.6close函數(shù)/200
8.2.7getsockopt和setsockopt函數(shù)/200
8.2.8select函數(shù)/203
8.2.9poll函數(shù)/203
8.2.10epoll函數(shù)/204
8.3基于TCP的網絡程序/205
8.3.1簡單C/S應用程序的設計/206
8.3.2交互式C/S應用程序的設計/208
8.3.3簡單聊天室應用程序的設計(select)/210
8.3.4聊天室應用程序的設計(select)/214
8.3.5簡單C/S應用程序的設計(epoll)/219
8.4基于UDP的網絡程序/221
8.4.1簡單C/S應用程序的設計/221
8.4.2簡單聊天室應用程序的設計/223
8.5原始套接字編程/225
8.6UNIX Domain Socket/227
8.7習題/230
第9章Linux函數(shù)庫和進程地址空間/232
9.1靜態(tài)庫和共享庫/232
9.2函數(shù)庫的制作和使用/233
9.2.1靜態(tài)庫的制作和使用/234
9.2.2共享庫的制作和使用/236
9.3顯式鏈接共享庫/239
9.4進程地址空間/241
9.4.132位系統(tǒng)的進程地址空間/241
9.4.264位系統(tǒng)的進程地址空間/244
9.4.3查看進程地址空間/245
9.4.4編程驗證進程地址空間布局/249
9.5動態(tài)鏈接過程/250
9.5.1ELF文件格式/251
9.5.2加載解釋器/252
9.5.3運行解釋器/253
9.6習題/260
第10章Pthreads編程/261
10.1Pthreads概述/261
10.1.1Linux進程和線程/261
10.1.2Linux線程模型/262
10.1.3Pthreads簡介/263
10.2Pthreads函數(shù)/263
10.2.1創(chuàng)建線程/263
10.2.2終止線程/264
10.2.3線程的結合和分離/265
10.2.4線程屬性/268
10.2.5自動清理線程資源/273
10.2.6線程同步與互斥/274
10.3Pthreads編程示例/281
10.3.1讀者寫者/281
10.3.2生產者消費者/282
10.3.3哲學家就餐/283
10.4習題/285
第11章GTK圖形界面編程/287
11.1GTK概述/287
11.2GLib概述/288
11.3信號和回調函數(shù)/295
11.4GTK控件/297
11.4.1非容器控件/297
11.4.2容器控件/297
11.5GTK圖形界面編程/298
11.5.1Hello World/298
11.5.2GtkGrid/299
11.5.3Custom Drawing/301
11.5.4GtkBuilder創(chuàng)建界面/304
11.5.5Cambalache/306
11.6GTK圖形界面聊天室/308
11.6.1聊天室服務器端/308
11.6.2聊天室客戶端/311
11.6.3測試/316
11.7習題/317
第12章Linux內核編程/319
12.1Linux內核編程概念/319
12.2LKM編程: Hello World/320
12.2.1LKM簽名驗證/320
12.2.2Hello World模塊的編寫和運行/322
12.2.3模塊參數(shù)和模塊導出符號/324
12.3Linux驅動程序設計/327
12.3.1Linux驅動程序簡介/327
12.3.2字符設備驅動程序/328
12.3.3虛擬網卡驅動程序/332
12.4習題/335
附錄AASCII碼表/337
附錄B資源及學習網站/338
參考文獻/339