1.存在的問題
最近十多年來,軟件產業(yè)和互聯(lián)網(wǎng)產業(yè)的迅猛發(fā)展,給人們提供了用武之地,同時也對軟件工程教育提出了巨大的挑戰(zhàn)。從教育現(xiàn)狀看,通過灌輸知識可以讓人具有很強的考試能力,卻往往經(jīng)不起用人單位的檢驗(筆試和機試)。雖然大家都知道,教育的本質在于培養(yǎng)人的創(chuàng)造力、好奇心、獨特的思考能力和解決問題的能力,但實際上我們的教學實踐背離了教育理念。代碼的優(yōu)劣不僅直接決定了軟件的質量,還將直接影響軟件成本。軟件成本是由開發(fā)成本和維護成本組成的,但維護成本卻遠高于開發(fā)成本,蠻力開發(fā)的現(xiàn)象比比皆是,大量來之不易的資金就這樣被無聲無息地吞沒了,造成了社會資源的嚴浪費。
2.核心域和非核心域
一個軟件系統(tǒng)封裝了若干領域的知識,其中一個領域的知識代表了系統(tǒng)的核心競爭力,這個領域就稱為核心域,其他領域稱為非核心域。雖然更通俗的說法是業(yè)務和技術,但使用核心域和非核心域更嚴謹。非核心域就是別人的領域,如底層驅動、操作系統(tǒng)和組件,即便自己有一些優(yōu)勢,那也是暫時的,競爭對手也能通過其他渠道獲得。非核心域的改進是必要的,但不充分,還是要在核心域上深入挖掘,讓競爭對手無法輕易從第三方獲得。只有在核心域中深入挖掘,達到基于核心域的復用,才能獲得和保持競爭力。要達到基于核心域的復用,有必要將核心域和非核心域分開考慮。因為過早地將各個領域的知識混雜,會增加不必要的負擔,從而導致開發(fā)人員騰不出腦力思考核心域中更深刻的問題,待解決問題的規(guī)模一旦變大,而人腦的容量和運算能力又是有限的,就會造成顧此失彼,因此必須分而治之。核心域與非核心域的知識都是獨的,比如,一個計算器要做到?jīng)]有漏洞,其中的問題也很復雜。如果不使用狀態(tài)圖對程序設計與數(shù)據(jù)結構?領域邏輯顯式地建模,再根據(jù)模型映射到實現(xiàn),而是直接下手編程,領域邏輯的知識靠臨時去想,最終得到的代碼肯定破綻百出。其實有利潤的系統(tǒng),其內部都是很復雜的,千萬不要幼稚地認為我的系統(tǒng)不復雜。
3.利潤從哪里來
早期創(chuàng)業(yè)時,只要抓住一個機會,多參加展會,多做廣告,成功的概率就很大了。在互聯(lián)網(wǎng)時代,突然發(fā)現(xiàn)入口多了,聚焦用戶的難度也越來越大了。當產品面臨競爭時,你會發(fā)現(xiàn)沒有最低只有更低。而且現(xiàn)在已經(jīng)沒有互聯(lián)網(wǎng)公司了,攜程變成了旅行社,新浪變成了新媒體……機會驅動、粗放經(jīng)營的時代已經(jīng)過去了。Apple之所以能成為全球最賺錢的手機公司,關鍵在于產品的性能超越了用戶的預期,且因為大量 可 重 用 的 核 心 領 域 知 識,綜 合 成 本 做 到
了 極 致。Yourdon 和Constantine在《結構化設計》一書中,將經(jīng)濟學作為軟件設計的底層驅動力,軟件設計應該致力于降低整體成本。人們發(fā)現(xiàn)軟件的維護成本遠遠高于它的初始成本,因為理解現(xiàn)有代碼需要花費時間,而且容易出錯。同時改動之后,還要進行測試和部署。更多的時候,程序員不是在編碼,而是在閱讀程序。由于閱讀程序需要從細節(jié)和概念上理解,因此修改程序的投入會遠遠大于最初編程的投入。基于這樣的共識,讓我們操心的一系列事情,需要不斷地思考和總結使之可以重用,這就是方法論的緣起。通過財務數(shù)據(jù)分析可知,由于決策失誤,我們開發(fā)了一些周期長、技術難度大且回報率極低的產品。由于缺乏科學的軟件工程方法,不僅軟件難以重用,而且擴展和維護難度很大,從而導致開發(fā)成本居高不下。顯而易見,從軟件開發(fā)來看,軟件工程與計算機科學是完全不同的兩個領域的知識。其主要區(qū)別在于人,因為軟件開發(fā)是以人為中心的過程。如果考慮人的因素,軟件工程更接近經(jīng)濟學,而非計算機科學。如果不改變思維方式,則很難開發(fā)出既好賣成本又低的產品。
4.優(yōu)秀人才在哪里
學徒模式是過去造就大師、傳承技藝的方法,而現(xiàn)在指導和輔導卻成為了一項被忽略的活動,團隊成員得不到所需的支持。技術領導人不僅要引導整個項目,而且還要為員工提供必需的協(xié)助。除此之外,指導和輔導提供了一種增強員工技能的方式,可幫助他們完善自己的職業(yè)生涯。這種協(xié)助有時是技術性的,有時是軟技能的?上У氖,在我們的行業(yè)里,許多優(yōu)秀的開發(fā)者在轉向管理崗位之后,就放棄了對技術的追求,甚至再也不寫代碼了,因而團隊中失去了最有價值的技術領導和導師,導致今天的開發(fā)者還會繼續(xù)重蹈覆轍。很多優(yōu)秀的導師都消失了,讓開發(fā)者到哪里去獲得經(jīng)驗呢? 未來的優(yōu)秀人才從哪里來?
5.告知讀者
這本書如同培訓講師的教案,是我和同事們的讀書筆記及程序設計實踐的心得,并不是一本從零開始編寫的專著或圖書。其中的很多內容并非我們原創(chuàng),而是重用了一些公開出版物的內容,詳見本書的參考文獻。
6.叢書簡介
這套叢書命名為《嵌入式軟件工程方法與實踐叢書》,目前已經(jīng)完成《程序設計與數(shù)據(jù)結構》、《面向 AMetal框架和接口的 C編程》和《面向 AWorks框架和接口的 C編程(上)》,后續(xù)還將推出《面向 AWorks框架和接口的 C編程(下)》、《面向 AMetal框架和 接 口 的 LoRa 編 程》、《面 向 AWorks 框 架 和 接 口 的 C 編 程》、《面 向AWorks框架和接口的 GUI編程》、《面向 AWorks框架和接口的 CAN 編程》、《面向AWorks框架和接口的網(wǎng)絡編程》、《面向 AWorks框架和接口的 EtherCAT 編程》和《嵌入式系統(tǒng)應用設計》等系列圖書,最新動態(tài)詳見 www.zlg.cn(致遠電子官網(wǎng))和www.zlgmcu.com(周立功單片機官網(wǎng))
周立功
2018年9月2
周立功:周立功單片機發(fā)展有限公司總經(jīng)理,江西理工大學機電學院自動化教研室教授,碩士生導師,嵌入式系統(tǒng)技術方向學科帶頭人,中國計算機學會高級會員,中國計算機學會嵌入式系統(tǒng)學會(微機專委)理事,中國單片機學會理事。從1981年開始從事單片機與嵌入式系統(tǒng)的應用、開發(fā)與推廣。在教學實踐過程中,為了培養(yǎng)具有較好工程實踐能力"零適應期"的大學生,周立功創(chuàng)立了"3+1"嵌入式系統(tǒng)應用創(chuàng)新教學模式。
第1章 程序設計基礎………………………………………………………………… 1
1.1 思想的力量
……………………………………………………………………… 1
1.1.1 過程主題
…………………………………………………………………… 1
1.1.2 思維差異
…………………………………………………………………… 2
1.1.3 語言的鴻溝…………………………………………………………………… 3
1.2 變量與指針
……………………………………………………………………… 12
1.2.1 變
量 ……………………………………………………………………… 12
1.2.2 值的表示形式
……………………………………………………………… 16
1.2.3 數(shù)據(jù)的輸入/輸出
…………………………………………………………… 23
1.3 指針變量與指針的指針…………………………………………………………… 28
1.3.1 聲明與訪問
………………………………………………………………… 28
1.3.2 變量的訪問
………………………………………………………………… 33
1.3.3 指針的指針
………………………………………………………………… 36
1.4 簡化表達式
……………………………………………………………………… 38
1.4.1 邏輯表達式
………………………………………………………………… 39
1.4.2 綜合表達式
………………………………………………………………… 40
1.4.3 條件表達式
………………………………………………………………… 42
1.5 共性與可變性分析
……………………………………………………………… 42
1.5.1 分析方法
…………………………………………………………………… 42
1.5.2 建立抽象
…………………………………………………………………… 44
1.5.3 建立接口
…………………………………………………………………… 44
1.5.4 實現(xiàn)接口
…………………………………………………………………… 48
1.5.5 使用接口
…………………………………………………………………… 50
1.6 數(shù)組與指針
……………………………………………………………………… 51
1.6.1 數(shù)
組 ……………………………………………………………………… 51
1.6.2 數(shù)組的訪問形式
…………………………………………………………… 57
1.6.3 泛型編程
…………………………………………………………………… 60
1.7 數(shù)組的數(shù)組與指針
……………………………………………………………… 69
1.7.1 指向數(shù)組的指針
…………………………………………………………… 69
1.7.2 二維數(shù)組
…………………………………………………………………… 71
1.7.3 將二維數(shù)組作為函數(shù)參數(shù)
…………………………………………………… 73
1.8 字符串與指針
…………………………………………………………………… 77
1.8.1 字符常量
…………………………………………………………………… 77
1.8.2 字符串常量
………………………………………………………………… 81
1.8.3 指針數(shù)組
…………………………………………………………………… 92
1.9 動態(tài)分配內存
…………………………………………………………………… 99
1.9.1 malloc()函數(shù)
……………………………………………………………… 100
1.9.2 calloc()函數(shù)
……………………………………………………………… 101
1.9.3 free()函數(shù)
………………………………………………………………… 101
1.9.4 realloc()函數(shù)
……………………………………………………………… 103
第2章 程序設計技術……………………………………………………………… 105
2.1 函數(shù)指針與指針函數(shù)
…………………………………………………………… 105
2.1.1 函數(shù)指針
…………………………………………………………………… 105
2.1.2 指針函數(shù)
…………………………………………………………………… 108
2.1.3 回調函數(shù)
…………………………………………………………………… 112
2.1.4 函數(shù)指針數(shù)組
……………………………………………………………… 119
2.2 結構體
………………………………………………………………………… 120
2.2.1 內存對齊
…………………………………………………………………… 121
2.2.2 內含基本數(shù)據(jù)類型
………………………………………………………… 124
2.2.3 內置函數(shù)指針
……………………………………………………………… 130
2.2.4 嵌套結構體
………………………………………………………………… 134
2.2.5 結構體數(shù)組
………………………………………………………………… 138
2.3 棧與函數(shù)返回…………………………………………………………………… 142
2.3.1 堆
棧 …………………………………………………………………… 142
2.3.2 入棧與出棧
………………………………………………………………… 143
2.3.3 函數(shù)的調用與返回
………………………………………………………… 144
2.4 棧 ADT ………………………………………………………………………… 146
2.4.1 不完全類型
………………………………………………………………… 146
2.4.2 抽象數(shù)據(jù)類型
……………………………………………………………… 150
2.4.3 開閉原則(OCP) …………………………………………………………… 160
第3章 算法與數(shù)據(jù)結構…………………………………………………………… 165
3.1 算法問題
……………………………………………………………………… 165
3.1.1 排
序 …………………………………………………………………… 165
3.1.2 搜
索 …………………………………………………………………… 167
3.1.3 O 記法
…………………………………………………………………… 169
3.2 單向鏈表
……………………………………………………………………… 175
3.2.1 存值與存址
………………………………………………………………… 175
3.2.2 數(shù)據(jù)與p_next分離
………………………………………………………… 184
3.2.3 接
口 …………………………………………………………………… 190
3.3 雙向鏈表
……………………………………………………………………… 201
3.3.1 添加結點
…………………………………………………………………… 205
3.3.2 刪除結點
…………………………………………………………………… 208
3.3.3 遍歷鏈表
…………………………………………………………………… 210
3.4 迭代器模式
…………………………………………………………………… 213
3.4.1 迭代器與容器
……………………………………………………………… 213
3.4.2 迭代器接口
………………………………………………………………… 214
3.4.3 算法的接口
………………………………………………………………… 219
3.5 哈希表
………………………………………………………………………… 225
3.5.1 問
題 …………………………………………………………………… 225
3.5.2 哈希表的類型
……………………………………………………………… 229
3.5.3 哈希表的實現(xiàn)
……………………………………………………………… 231
3.6 隊列 ADT ……………………………………………………………………… 240
3.6.1 建立抽象
…………………………………………………………………… 240
3.6.2 建立接口
…………………………………………………………………… 240
3.6.3 實現(xiàn)與使用接口
…………………………………………………………… 243
第4章 面向對象編程……………………………………………………………… 252
4.1 OO 思想
……………………………………………………………………… 252
4.1.1 職責轉移
…………………………………………………………………… 252
4.1.2 OO 機制
…………………………………………………………………… 254
4.1.3 OO 收益
…………………………………………………………………… 255
4.2 類與對象
……………………………………………………………………… 256
4.2.1 對
象 …………………………………………………………………… 256
4.2.2 類
………………………………………………………………………… 258
4.2.3 封
裝 …………………………………………………………………… 262
4.3 繼承與多態(tài)
…………………………………………………………………… 268
4.3.1 抽
象 …………………………………………………………………… 268
4.3.2 繼
承 …………………………………………………………………… 269
4.3.3 職責驅動設計
……………………………………………………………… 272
4.3.4 多態(tài)性
…………………………………………………………………… 276
4.4 虛函數(shù)
………………………………………………………………………… 279
4.4.1 二叉樹
…………………………………………………………………… 279
4.4.2 表達式算術樹
……………………………………………………………… 280
4.4.3 虛函數(shù)
…………………………………………………………………… 288
4.5 狀態(tài)機
………………………………………………………………………… 292
4.5.1 有限狀態(tài)機
………………………………………………………………… 292
4.5.2 State模式
………………………………………………………………… 296
4.5.3 動作類
…………………………………………………………………… 306
4.6 框架與重用
…………………………………………………………………… 308
4.6.1 框
架 …………………………………………………………………… 308
4.6.2 契
約 …………………………………………………………………… 309
4.6.3 建立契約
…………………………………………………………………… 310
4.6.4 框架與重構
………………………………………………………………… 311
參 考 文 獻…………………………………………………………………………… 313