關于我們
書單推薦
新書推薦
|
嵌入式Linux與物聯網軟件開發(fā) C語言內核深度解析
本書的原型思想和內容,發(fā)源于朱有鵬老師早些年的研發(fā)和學習經歷,發(fā)展于后來數年的線下培訓授課經歷,并成熟于視頻課程《C語言高級專題》(隸屬于《朱有鵬老師嵌入式Linux核心課程》系列視頻課程的第4部分)。本書正是基于這套視頻課程的課件整理而來,參與各章節(jié)整理和編寫的都是學習了視頻課程的學生,由朱有鵬老師和張先鳳老師檢驗并完善成書。這些參與編寫的同學有的已經工作數年、有的則尚未走出大學校園。選擇他們合作創(chuàng)作本書,就是為了告訴讀者:做技術并不要求你天賦異稟,只需要你感興趣、愿意去探索和練習,你也可以成功。
針對性強:面向嵌入式Linux內核源碼、底層驅動軟件開發(fā)等技術方向。
精華原創(chuàng):凝結作者多年研發(fā)及教學經驗,幫助讀者真正深度理解難點。 求職必讀:詳解常見面試題,完全應對 “嵌入式軟件工程師”崗位需求。
朱有鵬,互聯網課程《朱老師物聯網大講堂》創(chuàng)始人、杰出講師;51CTO學院杰出講師、CSDN技術專家、國內物聯網教育領域先驅;具有大型企業(yè)級項目研發(fā)經驗和豐富的教學經驗。授課風趣幽默、條理清晰、通俗易懂,對知識有自己獨到見解。能舉一反三,發(fā)散學生的思維,指引學生發(fā)掘適合自己的學習方法。
張先鳳,《朱老師物聯網大講堂》聯合創(chuàng)始人、杰出講師;長期從事企業(yè)級物聯網項目研發(fā)和物聯網相關教學工作,對物聯網各關鍵環(huán)節(jié)技術均有所涉獵,對物聯網未來發(fā)展和教學有著獨特見解,立志長期扎根物聯網相關研發(fā)和教學工作。
第1 章 C 語言與內存… ……………………………………………………………………… 1
1.1 引言………………………………………………………………………………………………… 1 1.2 計算機程序運行的目的…………………………………………………………………………… 1 1.2.1 什么是程序… …………………………………………………………………………………… 1 1.2.2 計算機運行程序的目的………………………………………………………………………… 1 1.2.3 靜態(tài)內存SRAM 和動態(tài)內存DRAM…………………………………………………………2 1.2.4 馮·諾伊曼結構和哈佛結構… ………………………………………………………………3 1.2.5 總結:程序運行為什么需要內存呢……………………………………………………………4 1.2.6 深入思考:如何管理內存(無OS 時,有OS 時)… ………………………………………4 1.3 位、字節(jié)、半字、字的概念和內存位寬………………………………………………………… 5 1.3.1 深入了解內存(硬件和邏輯兩個角度)… ……………………………………………………5 1.3.2 內存的邏輯抽象圖(內存的編程模型)… ……………………………………………………6 1.3.3 位和字節(jié)…………………………………………………………………………………………7 1.3.4 字和半字…………………………………………………………………………………………7 1.3.5 內存位寬(硬件和邏輯兩個角度)… …………………………………………………………7 1.4 內存編址和尋址、內存對齊……………………………………………………………………… 8 1.4.1 內存編址方法… …………………………………………………………………………………8 1.4.2 關鍵:內存編址是以字節(jié)為單位………………………………………………………………8 1.4.3 內存和數據類型的關系…………………………………………………………………………9 1.4.4 內存對齊……………………………………………………………………………………… 10 1.5 C語言如何操作內存… …………………………………………………………………………… 10 1.5.1 C 語言對內存地址的封裝…………………………………………………………………… 10 1.5.2 用指針來間接訪問內存……………………………………………………………………… 11 1.5.3 指針類型的含義……………………………………………………………………………… 12 1.5.4 用數組來管理內存…………………………………………………………………………… 12 1.6 內存管理之結構體………………………………………………………………………………… 14 1.6.1 數據結構這門學問的意義… ………………………………………………………………… 14 1.6.2 最簡單的數據結構:數組…………………………………………………………………… 141 6.3 數組的優(yōu)缺點………………………………………………………………………………… 14 1.6.4 結構體隆重登場……………………………………………………………………………… 14 1.6.5 題外話:結構體內嵌指針實現面向對象…………………………………………………… 15 1.7 內存管理之棧(stack)… ……………………………………………………………………… 15 1.7.1 什么是棧… …………………………………………………………………………………… 15 1.7.2 棧管理內存的特點(小內存、自動化)… ………………………………………………… 16 1.7.3 棧的應用舉例:局部變量和函數調用……………………………………………………… 16 1.7.4 棧的約束(預定棧大小不靈活,怕溢出)… ……………………………………………… 17 1.8 內存管理之堆……………………………………………………………………………………… 18 1.8.1 什么是堆… …………………………………………………………………………………… 18 1.8.2 堆管理內存的特點(大塊內存、手工分配/ 使用/ 釋放)………………………………… 18 1.8.3 C 語言操作堆內存的接口(malloc/free)… ……………………………………………… 18 1.8.4 堆的優(yōu)勢和劣勢(管理大塊內存、靈活、容易內存泄漏)… …………………………… 19 1.8.5 靜態(tài)存儲區(qū)…………………………………………………………………………………… 19 課后題… ………………………………………………………………………………………………… 19 第2 章 C 語言位操作… ………………………………………………………………………21 2.1 引言………………………………………………………………………………………………… 21 2.2 常用位操作符……………………………………………………………………………………… 21 2.2.1 位與(&)……………………………………………………………………………………… 21 2.2.2 位或(|)… …………………………………………………………………………………… 22 2.2.3 位取反(~)…………………………………………………………………………………… 23 2.2.4 位異或(^)…………………………………………………………………………………… 24 2.2.5 左移位(<<)………………………………………………………………………………… 25 2.2.6 右移位(>>)………………………………………………………………………………… 26 2.3 位操作與寄存器…………………………………………………………………………………… 26 2.3.1 寄存器的操作………………………………………………………………………………… 26 2.3.2 寄存器特定位清零用&……………………………………………………………………… 27 2.3.3 寄存器特定位置1 用|… …………………………………………………………………… 27 2.3.4 寄存器特定位取反用~……………………………………………………………………… 27 2.4 位運算構建特定二進制數………………………………………………………………………… 28 2.4.1 使用移位獲取特定位為1 的二進制數……………………………………………………… 28 2.4.2 結合位取反獲取特定位為0 的二進制數…………………………………………………… 29 2.4.3 總結…………………………………………………………………………………………… 29 2.5 位運算實戰(zhàn)演練1… ……………………………………………………………………………… 30 2.5.1 給定整型數a,設置a 的bit3,保證其他位不變………………………………………… 30 2.5.2 給定整型數a,設置a 的bit3~bit7,保持其他位不變… ……………………………… 30 2.5.3 給定整型數a,清除a 的bit15,保證其他位不變… …………………………………… 302 5.4 給定整型數a,清除a 的bit15~bit23,保持其他位不變… …………………………… 31 2.5.5 給定整型數a,取出a 的bit3~bit8… …………………………………………………… 31 2.5.6 用C 語言給寄存器a 的bit7~bit17 賦值937(其余位不受影響)……………………… 31 2.6 位運算實戰(zhàn)演練2… ……………………………………………………………………………… 32 2.6.1 用C 語言將寄存器a 的bit7~bit17 中的值加17(其余位不受影響)…………………… 32 2.6.2 用C 語言給寄存器a 的bit7~bit17 賦值937,同時給bit21~bit25 賦值17… ……… 32 2.7 技術升級:用宏定義來完成位運算……………………………………………………………… 33 2.7.1 直接用宏來置位……………………………………………………………………………… 33 2.7.2 直接用宏來復位……………………………………………………………………………… 33 2.7.3 截取變量的部分連續(xù)位……………………………………………………………………… 33 課后題… ………………………………………………………………………………………………… 34 第3 章 指針才是C 語言的精髓… ………………………………………………………… 36 3.1 引言………………………………………………………………………………………………… 36 3.2 指針到底是什么…………………………………………………………………………………… 37 3.2.1 普通變量……………………………………………………………………………………… 37 3.2.2 指針變量……………………………………………………………………………………… 37 3.2.3 變量空間的首字節(jié)地址,作為整個空間的地址…………………………………………… 38 3.2.4 指針變量的類型作用………………………………………………………………………… 38 3.2.5 為什么需要指針……………………………………………………………………………… 39 3.2.6 高級語言如Java、C# 的指針到哪里去了… …………………………………………… 39 3.2.7 指針使用之三部曲…………………………………………………………………………… 40 3.3 理解指針符號……………………………………………………………………………………… 40 3.3.1 星號* 的理解………………………………………………………………………………… 40 3.3.2 取地址符& 的理解… ……………………………………………………………………… 41 3.3.3 指針變量的初始化和指針變量賦值之間的區(qū)別…………………………………………… 41 3.3.4 左值與右值…………………………………………………………………………………… 41 3.3.5 定義指針后,需要關心的一些內容………………………………………………………… 42 3.4 野指針與段錯誤問題……………………………………………………………………………… 43 3.4.1 什么是野指針………………………………………………………………………………… 43 3.4.2 野指針可能引發(fā)的危害……………………………………………………………………… 44 3.4.3 野指針產生的原因…………………………………………………………………………… 44 3.4.4 如何避免野指針……………………………………………………………………………… 45 3.4.5 NULL 到底是什么…………………………………………………………………………… 45 3.4.6 段錯誤產生的原因匯總……………………………………………………………………… 46 3.5 const關鍵字與指針… …………………………………………………………………………… 46 3.5.1 什么是const… ……………………………………………………………………………… 46 3.5.2 const 對于普通變量的修飾………………………………………………………………… 463 5.3 const 修飾指針的三種形式………………………………………………………………… 46 3.5.4 const 的變量真的不能改嗎………………………………………………………………… 47 3.5.5 為什么要用const…………………………………………………………………………… 48 3.5.6 有關變量和常量的探討……………………………………………………………………… 48 3.6 深入學習數組……………………………………………………………………………………… 49 3.6.1 為什么需要數組……………………………………………………………………………… 49 3.6.2 從編譯器角度理解數組……………………………………………………………………… 49 3.6.3 從內存角度理解數組………………………………………………………………………… 49 3.6.4 一位數組中幾個關鍵符號的理解…………………………………………………………… 50 3.7 指針與數組的天生“姻緣”……………………………………………………………………… 50 3.7.1 如何使用指針訪問數組……………………………………………………………………… 50 3.7.2 從內存角度理解指針訪問數組的實質……………………………………………………… 51 3.7.3 指針與數組類型的匹配問題………………………………………………………………… 51 3.7.4 總結:指針類型決定了指針如何參與運算………………………………………………… 51 3.8 指針類型與強制類型轉換………………………………………………………………………… 52 3.8.1 變量數據類型的作用………………………………………………………………………… 52 3.8.2 數據的存入和讀取…………………………………………………………………………… 53 3.8.3 普通變量的強制轉換………………………………………………………………………… 53 3.8.4 指針變量數據類型的含義…………………………………………………………………… 56 3.8.5 指針變量數據類型的強制轉換……………………………………………………………… 56 3.9 指針、數組與sizeof運算符… …………………………………………………………………… 57 3.9.1 char str[]="hello"; sizeof(str) ,sizeof(str[0]) ,strlen(str)………………………… 58 3.9.2 char str[]="hello"; char *p=str; sizeof(*p) …………………………………………… 58 3.9.3 int b[100]; sizeof(b)… …………………………………………………………………… 58 3.9.4 數組的傳參…………………………………………………………………………………… 58 3.9.5 #define 和typedef 的區(qū)別………………………………………………………………… 59 3.10 指針與函數傳參… ……………………………………………………………………………… 60 3.10.1 普通傳參… ………………………………………………………………………………… 60 3.10.2 傳遞地址(指針)…………………………………………………………………………… 61 3.10.3 傳遞數組… ………………………………………………………………………………… 61 3.10.4 傳遞結構體… ……………………………………………………………………………… 61 3.10.5 傳遞普通值和傳遞地址的異同,以及傳遞地址(指針)應該遵循的原則… ………… 62 3.11 輸入型參數與輸出型參數… …………………………………………………………………… 62 3.11.1 函數為什么需要傳參和返回值… ………………………………………………………… 62 3.11.2 函數傳參中為什么使用const 指針… …………………………………………………… 64 3.11.3 總結… ……………………………………………………………………………………… 65 課后題… ………………………………………………………………………………………………… 65 第4 章 C 語言復雜表達式與指針高級應用……………………………………………… 67 4.1 引言………………………………………………………………………………………………… 67 4.2 指針數組與數組指針……………………………………………………………………………… 67 4.2.1 簡單理解指針數組與數組指針……………………………………………………………… 67 4.2.2 分析指針數組與數組指針的表達式………………………………………………………… 68 4.3 函數指針與typedef… …………………………………………………………………………… 69 4.3.1 函數指針的實質(還是指針變量)… ……………………………………………………… 70 4.3.2 函數指針的書寫和分析方法………………………………………………………………… 70 4.3.3 typedef 關鍵字的用法……………………………………………………………………… 72 4.4 函數指針實戰(zhàn)1—用函數指針調用執(zhí)行函數… ……………………………………………… 73 4.5 函數指針實戰(zhàn)2—結構體內嵌函數指針實現分層… ………………………………………… 75 4.6 再論typedef… …………………………………………………………………………………… 78 4.6.1 輕松理解和應用typedef… ………………………………………………………………… 78 4.6.2 typedef 與#define 宏的區(qū)別……………………………………………………………… 80 4.6.3 typedef 與struct… ………………………………………………………………………… 81 4.6.4 typedef 與const… ………………………………………………………………………… 81 4.6.5 使用typedef 的重要意義…………………………………………………………………… 82 4.6.6 二重指針……………………………………………………………………………………… 82 4.7 二維數組…………………………………………………………………………………………… 83 4.7.1 二維數組的內存映像………………………………………………………………………… 83 4.7.2 識別第一維和第二維………………………………………………………………………… 83 4.7.3 數組名代表數組首元素的地址……………………………………………………………… 84 4.7.4 指針訪問二維數組的兩種方式……………………………………………………………… 84 4.7.5 總結…………………………………………………………………………………………… 85 課后題… ………………………………………………………………………………………………… 85 第5 章 數組& 字符串& 結構體& 共用體& 枚舉……………………………………… 88 5.1 引言………………………………………………………………………………………………… 88 5.2 程序中的內存從哪里來…………………………………………………………………………… 88 5.2.1 三種內存來源:棧(stack)、堆(heap)、數據區(qū)(.data)…………………………… 89 5.2.2 棧內存特點詳解……………………………………………………………………………… 89 5.3 堆…………………………………………………………………………………………………… 90 5.3.1 堆內存特點詳解……………………………………………………………………………… 90 5.3.2 使用堆內存注意事項………………………………………………………………………… 91 5.3.3 malloc 的一些細節(jié)表現… ………………………………………………………………… 92 5.4 內存中的各個段…………………………………………………………………………………… 92 5.4.1 代碼段、數據段、bss 段…………………………………………………………………… 92 5.4.2 特殊數據會被放到代碼段…………………………………………………………………… 925 4.3 未初始化或顯式初始化為0 的全局變量放在bss 段… ………………………………… 93 5.4.4 內存管理方式的總結………………………………………………………………………… 93 5.5 C語言的字符串類型… …………………………………………………………………………… 93 5.5.1 C 語言使用指針來管理字符串……………………………………………………………… 93 5.5.2 C 語言中字符串的本質:指向字符串的存放空間的指針………………………………… 94 5.5.3 指向字符串的指針變量空間和字符串存放的空間是分開的……………………………… 94 5.5.4 存儲多個字符的兩種方式—字符串和字符數組………………………………………… 94 5.6 字符串和字符數組的細節(jié)………………………………………………………………………… 95 5.6.1 字符數組的初始化、sizeof 以及strlen…………………………………………………… 95 5.6.2 字符串的初始化與sizeof、strlen… ……………………………………………………… 96 5.6.3 字符數組與字符串的本質差異……………………………………………………………… 96 5.7 結構體概述………………………………………………………………………………………… 96 5.7.1 結構體使用時先定義結構體類型,再用類型定義變量…………………………………… 96 5.7.2 從數組到結構體的進步之處………………………………………………………………… 97 5.7.3 結構體變量中的元素如何訪問……………………………………………………………… 97 5.8 結構體的對齊訪問………………………………………………………………………………… 98 5.8.1 結構體對齊訪問實例………………………………………………………………………… 98 5.8.2 結構體為何要對齊訪問……………………………………………………………………… 99 5.8.3 結構體對齊的規(guī)則和運算…………………………………………………………………… 99 5.8.4 手動對齊 … ……………………………………………………………………………… 100 5.8.5 GCC 推薦的對齊指令:_attribute_((packed)) 和_attribute_((aligned(n)))… … 102 5.9 offsetof宏與container_of宏… ……………………………………………………………… 103 5.9.1 由結構體指針進而訪問各元素的原理…………………………………………………… 103 5.9.2 offsetof 宏………………………………………………………………………………… 104 5.9.3 container_of 宏… ……………………………………………………………………… 104 5.9.4 學習指南和要求…………………………………………………………………………… 105 5.10 共用體(union)… ………………………………………………………………………… 105 5.10.1 共用體的類型聲明、變量定義和使用… ……………………………………………… 105 5.10.2 共用體和結構體的區(qū)別… ……………………………………………………………… 106 5.10.3 共用體的主要用途… …………………………………………………………………… 106 5.11 大小端模式… ………………………………………………………………………………… 107 5.11.1 什么是大小端模式… …………………………………………………………………… 107 5.11.2 用union 來測試機器的大小端模式… ………………………………………………… 108 5.11.3 用指針方式來測試機器的大小端… …………………………………………………… 109 5.11.4 通信系統中的大小端(數組的大小端)………………………………………………… 109 5.12 枚舉enum… ………………………………………………………………………………… 110 5.12.1 枚舉的作用是什么… ………………………………………………………………………110 5.12.2 C 語言為何需要枚舉… …………………………………………………………………… 1115 12.3 宏定義和枚舉的區(qū)別… …………………………………………………………………… 111 5.12.4 枚舉的定義形式… ………………………………………………………………………… 111 課后題… ……………………………………………………………………………………………… 113 第6 章 C 語言的預處理、函數和函數庫… ……………………………………………… 116 6.1 引言……………………………………………………………………………………………… 116 6.2 C語言為什么需要編譯鏈接… ………………………………………………………………… 116 6.2.1 編譯鏈接的流程………………………………………………………………………………116 6.2.2 編譯鏈接中各種文件擴展名的含義…………………………………………………………118 6.3 預處理詳解……………………………………………………………………………………… 119 6.3.1 C 語言預處理的意義…………………………………………………………………………119 6.3.2 預處理涉及的內容……………………………………………………………………………119 6.3.3 使用GCC 進行編譯和鏈接的過程…………………………………………………………119 6.4 常見的預處理詳解……………………………………………………………………………… 120 6.4.1 文件包含…………………………………………………………………………………… 120 6.4.2 注釋………………………………………………………………………………………… 122 6.4.3 宏定義……………………………………………………………………………………… 123 6.4.4 條件編譯…………………………………………………………………………………… 126 6.5 函數的本質……………………………………………………………………………………… 129 6.5.1 C 語言為什么會有函數…………………………………………………………………… 129 6.5.2 函數書寫的一般原則……………………………………………………………………… 129 6.5.3 函數是動詞、變量是名詞(面向對象中分別叫方法和成員變量)… ………………… 129 6.5.4 函數的實質是數據處理器………………………………………………………………… 130 6.6 函數的基本使用………………………………………………………………………………… 130 6.6.1 函數三要素:定義、聲明、調用………………………………………………………… 130 6.6.2 函數原型和作用………………………………………………………………………………131 6.7 遞歸函數………………………………………………………………………………………… 131 6.7.1 函數的調用機制………………………………………………………………………………131 6.7.2 遞歸函數…………………………………………………………………………………… 132 6.7.3 使用遞歸的原則:收斂性、棧溢出……………………………………………………… 134 6.7.4 遞歸與循環(huán)的區(qū)別………………………………………………………………………… 135 6.8 庫函數…………………………………………………………………………………………… 135 6.8.1 什么是函數庫……………………………………………………………………………… 135 6.8.2 函數庫的由來……………………………………………………………………………… 135 6.8.3 函數庫的提供形式:靜態(tài)鏈接庫與動態(tài)鏈接庫………………………………………… 135 6.8.4 庫函數的使用……………………………………………………………………………… 136 6.9 常見的庫函數之字符串函數…………………………………………………………………… 138 6.9.1 什么是字符串……………………………………………………………………………… 1386 9.2 字符串處理函數…………………………………………………………………………… 138 6.9.3 man 手冊的引入… ……………………………………………………………………… 138 6.9.4 man 手冊的使用… ……………………………………………………………………… 138 6.9.5 常用的字符串處理函數…………………………………………………………………… 139 6.10 常見的庫函數之數學庫函數… ……………………………………………………………… 140 6.10.1 數學庫函數… …………………………………………………………………………… 140 6.10.2 計算開平方… …………………………………………………………………………… 140 6.10.3 鏈接時加-lm… ……………………………………………………………………………141 6.11 制作靜態(tài)鏈接庫并使用… …………………………………………………………………… 141 6.12 制作動態(tài)鏈接庫并使用… …………………………………………………………………… 143 課后題… ……………………………………………………………………………………………… 144 第7 章 存儲類& 作用域& 生命周期& 鏈接屬性………………………………………… 147 7.1 引言……………………………………………………………………………………………… 147 7.2 概念解析………………………………………………………………………………………… 147 7.2.1 存儲類……………………………………………………………………………………… 147 7.2.2 作用域……………………………………………………………………………………… 148 7.2.3 生命周期…………………………………………………………………………………… 148 7.2.4 鏈接屬性…………………………………………………………………………………… 148 7.3 Linux下C程序的內存映像… ………………………………………………………………… 149 7.3.1 代碼段、rodata 段(只讀數據段)… …………………………………………………… 149 7.3.2 數據段、bss 段…………………………………………………………………………… 149 7.3.3 堆…………………………………………………………………………………………… 149 7.3.4 文件映射區(qū)………………………………………………………………………………… 149 7.3.5 棧…………………………………………………………………………………………… 150 7.3.6 內核映射區(qū)………………………………………………………………………………… 150 7.3.7 操作系統下和裸機下C 程序加載執(zhí)行的差異… ……………………………………… 150 7.4 存儲類相關的關鍵字1… ……………………………………………………………………… 150 7.4.1 auto………………………………………………………………………………………… 150 7.4.2 static… ………………………………………………………………………………………151 7.4.3 register… ……………………………………………………………………………………151 7.5 存儲類相關的關鍵字2… ……………………………………………………………………… 152 7.5.1 extern……………………………………………………………………………………… 152 7.5.2 volatile… ………………………………………………………………………………… 153 7.5.3 restrict… ………………………………………………………………………………… 154 7.5.4 typedef… ………………………………………………………………………………… 154 7.6 作用域詳解……………………………………………………………………………………… 154 7.6.1 局部變量的代碼塊作用域………………………………………………………………… 1547 6.2 函數名和全局變量的文件作用域………………………………………………………… 155 7.7 變量的生命周期………………………………………………………………………………… 155 7.7.1 研究變量生命周期的意義………………………………………………………………… 155 7.7.2 棧變量的生命周期………………………………………………………………………… 156 7.7.3 堆變量的生命周期………………………………………………………………………… 156 7.7.4 數據段、bss 段變量的生命周期………………………………………………………… 156 7.7.5 代碼段、只讀段的生命周期……………………………………………………………… 156 7.8 鏈接屬性………………………………………………………………………………………… 156 7.8.1 C 語言程序的組織架構:多個C 文件+ 多個h 文件… ……………………………… 156 7.8.2 編譯以文件為單位、鏈接以工程為單位………………………………………………… 157 7.8.3 三種鏈接屬性:外連接、內鏈接、無鏈接……………………………………………… 157 7.8.4 函數和全局變量的命名沖突問題………………………………………………………… 157 7.8.5 static 的第二種用法:修飾全局變量和函數…………………………………………… 158 課后題… ……………………………………………………………………………………………… 158 第8 章 C 語言關鍵細節(jié)討論… …………………………………………………………… 159 8.1 引言……………………………………………………………………………………………… 159 8.2 操作系統概述…………………………………………………………………………………… 159 8.2.1 什么是操作系統…………………………………………………………………………… 159 8.2.2 C 庫函數…………………………………………………………………………………… 160 8.2.3 操作系統的重大意義…………………………………………………………………………161 8.3 main函數返回值… …………………………………………………………………………… 162 8.3.1 普通函數的返回值………………………………………………………………………… 162 8.3.2 main 函數的返回值… …………………………………………………………………… 163 8.3.3 誰調用了main 函數……………………………………………………………………… 164 8.4 argc、argv與main函數的傳參… …………………………………………………………… 164 8.5 void類型的本質………………………………………………………………………………… 165 8.6 C語言中的NULL… …………………………………………………………………………… 166 8.6.1 NULL 的定義……………………………………………………………………………… 166 8.6.2 '\0' 、 '0' 、0 和NULL 的區(qū)別… ……………………………………………………… 167 8.7 運算中的臨時匿名變量………………………………………………………………………… 168 8.7.1 C 語言和匯編語言的區(qū)別………………………………………………………………… 168 8.7.2 強制類型轉換……………………………………………………………………………… 168 8.7.3 使用臨時變量來理解不同數據類型之間的運算………………………………………… 169 8.8 順序結構………………………………………………………………………………………… 169 8.8.1 C 語言中的結構…………………………………………………………………………… 169 8.8.2 編譯過程中的順序結構…………………………………………………………………… 169 8.8.3 思考:為什么本質都是順序結構………………………………………………………… 170 8.9 程序調試………………………………………………………………………………………… 170 8.9.1 程序調試手段……………………………………………………………………………… 170 8.9.2 調試(DEBUG) 版本和發(fā)行(RELEASE) 版本的區(qū)別… ………………………………171 8.9.3 debug 宏的使用方法… ……………………………………………………………………171 課后題… ……………………………………………………………………………………………… 172 第9 章 鏈表& 狀態(tài)機& 多線程…………………………………………………………… 173 9.1 引言……………………………………………………………………………………………… 173 9.2 鏈表的引入……………………………………………………………………………………… 173 9.2.1 數組的缺陷………………………………………………………………………………… 173 9.2.2 鏈表是什么樣子的………………………………………………………………………… 174 9.2.3 鏈表的作用是什么………………………………………………………………………… 174 9.3 單鏈表的實現之構建第一個節(jié)點……………………………………………………………… 175 9.3.1 不實用卻意義重大的簡單鏈表…………………………………………………………… 175 9.3.2 從簡單的鏈表開始………………………………………………………………………… 175 9.3.3 單鏈表的節(jié)點構成………………………………………………………………………… 175 9.3.4 使用堆內存創(chuàng)建一個節(jié)點………………………………………………………………… 176 9.3.5 鏈表的頭指針……………………………………………………………………………… 177 9.3.6 構建第一個簡單的鏈表…………………………………………………………………… 177 9.4 單鏈表的實現之從尾部插入節(jié)點……………………………………………………………… 177 9.4.1 從尾部插入節(jié)點…………………………………………………………………………… 177 9.4.2 構建第一個簡單的鏈表…………………………………………………………………… 178 9.4.3 什么是頭節(jié)點……………………………………………………………………………… 179 9.5 單鏈表的算法之從頭部插入節(jié)點……………………………………………………………… 180 9.5.1 鏈表頭部插入思路解析…………………………………………………………………… 180 9.5.2 箭頭非指向……………………………………………………………………………………181 9.6 單鏈表的算法之遍歷節(jié)點……………………………………………………………………… 181 9.6.1 什么是遍歷……………………………………………………………………………………181 9.6.2 如何遍歷單鏈表………………………………………………………………………………181 9.6.3 代碼分析…………………………………………………………………………………… 182 9.7 單鏈表的算法之刪除節(jié)點……………………………………………………………………… 182 9.7.1 為什么要刪除節(jié)點………………………………………………………………………… 182 9.7.2 注意堆內存的釋放………………………………………………………………………… 183 9.7.3 設計一個刪除節(jié)點算法…………………………………………………………………… 184 9.8 單鏈表的算法之逆序…………………………………………………………………………… 184 9.8.1 什么是鏈表的逆序………………………………………………………………………… 184 9.8.2 單鏈表的逆序算法分析…………………………………………………………………… 185 9.8.3 編程實現逆序算法………………………………………………………………………… 185 雙鏈表的引入和基本實現……………………………………………………………………… 187 9.9.1 單鏈表的優(yōu)缺點…………………………………………………………………………… 187 9.9.2 雙鏈表的結構……………………………………………………………………………… 187 9.10 雙鏈表的算法之插入節(jié)點… ………………………………………………………………… 188 9.10.1 尾部插入… ……………………………………………………………………………… 188 9.10.2 頭部插入… ……………………………………………………………………………… 189 9.11 雙鏈表的算法之遍歷… ……………………………………………………………………… 190 9.11.1 正向遍歷… ……………………………………………………………………………… 190 9.11.2 逆向遍歷… ……………………………………………………………………………… 190 9.12 雙鏈表的算法之刪除節(jié)點… ………………………………………………………………… 191 9.13 Linux內核鏈表………………………………………………………………………………… 192 9.13.1 前述鏈表數據區(qū)域的局限性… ………………………………………………………… 193 9.13.2 解決思路:數據區(qū)的結構體的封裝由用戶實現,通用部分通過調用函數實現… … 193 9.13.3 內核鏈表的設計思路… ………………………………………………………………… 193 9.13.4 list.h 文件簡介…………………………………………………………………………… 194 9.14 內核鏈表的基本算法和使用簡介… ………………………………………………………… 196 9.14.1 內核鏈表的常用操作… ………………………………………………………………… 196 9.14.2 內核鏈表的使用實踐… ………………………………………………………………… 197 9.15 什么是狀態(tài)機… ……………………………………………………………………………… 198 9.15.1 有限狀態(tài)機… …………………………………………………………………………… 199 9.15.2 兩種狀態(tài)機:Moore 型和Mealy 型…………………………………………………… 199 9.15.3 狀態(tài)機的主要用途… …………………………………………………………………… 200 9.15.4 狀態(tài)機解決了什么問題… ……………………………………………………………… 200 9.16 用C語言實現簡單的狀態(tài)機… ……………………………………………………………… 201 9.16.1 題目:開鎖狀態(tài)機… …………………………………………………………………… 201 9.16.2 題目分析… ……………………………………………………………………………… 201 9.17 多線程簡介… ………………………………………………………………………………… 203 9.17.1 操作系統下的并行執(zhí)行機制… ………………………………………………………… 203 9.17.2 進程和線程的區(qū)別和聯系… …………………………………………………………… 204 9.17.3 多線程的優(yōu)勢… ………………………………………………………………………… 204 課后題… ……………………………………………………………………………………………… 204 第10 章 程序員和編譯器的曖昧…………………………………………………………… 206 10.1 引言… ………………………………………………………………………………………… 206 10.2 編程工作的演進史… ………………………………………………………………………… 206 10.2.1 CPU 與二進制…………………………………………………………………………… 206 10.2.2 編程語言的革命… ……………………………………………………………………… 207 10.3 程序員、編譯器和CPU之間的三角戀……………………………………………………… 207 10.3.1 程序員與CPU 的之間的“翻譯”—編譯器………………………………………… 207 10.3.2 高級語言與低級語言的差別… ………………………………………………………… 208 10.4 像編譯器一樣思考吧—理論篇… ………………………………………………………… 208 10.4.1 編譯器的結構… ………………………………………………………………………… 208 10.4.2 語法是什么?語法就是編譯器的習性… ……………………………………………… 208 10.5 像編譯器一樣思考吧—實戰(zhàn)篇… ………………………………………………………… 209 10.5.1 充分地利用語法規(guī)則,寫出簡潔、高效的代碼… …………………………………… 209 10.5.2 復雜表達式理解… ……………………………………………………………………… 209 課后題… ……………………………………………………………………………………………… 214 附錄 答案…………………………………………………………………………………… 215 第1章 課后題答案…………………………………………………………………………………… 215 第2章 課后題答案…………………………………………………………………………………… 217 第3章 課后題答案…………………………………………………………………………………… 218 第4章 課后題答案…………………………………………………………………………………… 220 第5章 課后題答案…………………………………………………………………………………… 222 第6章 課后題答案…………………………………………………………………………………… 226 第7章 課后題答案…………………………………………………………………………………… 228 第8章 課后題答案…………………………………………………………………………………… 230 第9章 課后題答案…………………………………………………………………………………… 231 第10章 課后題答案… ……………………………………………………………………………… 236
你還可能感興趣
我要評論
|