這是一部C/C++語言的基礎語法教程,面向零基礎的初學者。C++是在C語言的基礎上做了部分修改和擴展的程序設計語言。本書的前半部分(1~19章)主要是C語言部分,而后半部分(20~31章)則是C++對C語言的擴展。
本書從實際工程需要出發,介紹一個C/C++從業人員所必須掌握的全部語法、核心概念和基本技能,消除了學習考試與實際工作之間的差距。書中不僅介紹函數、指針、結構體、類等基本語法,也介紹了傳值與傳地址、字符串、深拷貝與淺拷貝、動態創建對象、安全地使用指針、面向對象編程思想等核心概念。同時,書中還講解初級程序員所必須掌握的知識和技術,如單步調試、編碼規范、ANSI函數庫、文件操作、標準模板庫STL的使用。
本書配備免費的全套視頻教程、在線題庫及解析,可結合紙質教材同步使用,書中的近三百個示例的源碼,以及所有相關資料均可在http://afanihao.cn上獲取。
作為一個有十余年軟件開發背景的從業人員,作者在招聘面試中發現,現在的絕大多數應聘者往往缺少基本的語法基礎和實際的動手能力,更不用說對核心概念的理解了。這似乎表明現有的教材或教育方法,與實際的工作要求之間存在著比較嚴重的脫節。
因此,作者希望創建一套全新的、完整的、綜合性的教學體系,讓學員能夠打下牢固的語法基礎,建立對核心概念的正確認識,并掌握基本的動手能力。這套體系包含紙質教程、視頻教程、在線題庫、進階教程4大要素。
本書是目標體系的一個組成部分,它也可以獨立地使用。就這部紙質教材的特點來說,有以下幾點。
1. 主次分明
C/C++的語法繁多,有些語法是過時的,有些語法很難但工作中并不常用。為了避免給初學者帶來不必要的干擾,書中對非重點的章節采用星號標注,并顯式地說明這個章節是不重要的、或者是過時的、或者是第一遍學習的時候可以跳過的。
2. 引例
在開始講解每一章之前,通常會有一個引例,其作用是引起讀者對某個背景問題的思考。引例描述了一個語法產生的背景,使讀者自然而然地理解本章引入的新概念。
3. 鋪墊與銜接
本書各章節前后邏輯相承,一環連接一環。讀者只要按順序學習,就可以很容易地從最簡單的概念過渡到復雜的概念。最終的效果是,讀者會感覺整個學習過程中沒有太難的東西。值得強調的是,如果讀者不按順序學習,則學習難度會加倍。例如,如果讀者不學習第3、4、5章,則難以讀懂第8、9、10章。反之,如果按順序學習則可以不知不覺地通過。
本書在編排上注重銜接。例如,第19章起承上啟下的作用,使讀者可以很容易地從C語言的struct過渡到C++的class。
4. 動手能力
第16、17章中介紹了標準C函數庫的使用,第30章介紹了標準模板庫的使用,它們都是實際工作中所必須掌握、常用而且重要的知識。
同時,在正文及附錄中加強對讀者動手能力的培訓,強調良好的編碼規范,強調自己動手建立項目,并掌握調試技術。
5. 核心概念
C/C++中的核心概念包括“傳值與傳地址”“字符串”“深拷貝與淺拷貝”“動態創建對象”“安全地使用指針”“面向對象編程思想”等。實際上,如果不深刻理解這些核心概念,就無法寫出正確的程序。所以,本書在合適的位置講解了這些概念,使得讀者不必再搜尋別的輔導教材,就可以在學習基本語法的同時掌握這些核心概念。
6. 示例豐富
本書中給出了近三百個示例,為了保證示例的正確性,每個示例都經過作者驗證,并且可以在網站(http://afanihao.cn,可掃描二維碼)上獲取完整的示例源碼。
7. 豐富的配套資源
1) 在線題庫
使用在線題庫的方式提供習題,習題按四星級標注,一星為基本練習,三星最難,四星為工業級應用題。每題配備提示、答案或解析,使得讀者可以檢驗自己的思路是否合理。
2) 配套視頻
配套100集免費視頻教程,令學習更加高效和輕松。
3) 源代碼下載
近三百個示例源代碼免費共享,輕松編寫程序。
4) 進階學習
讀者在學習完本書的基本語法之后,可以選擇繼續學習進階類教程,使自己具備一個軟件開發從業人員的各項基本素質。
5) 答疑與討論區
以在線的形式提供答疑與討論區,具體信息請在http://afanihao.cn上獲取。
感謝我的父母、姐姐、哥哥,我的愛人和孩子,感謝他們對我的全力支持。
感謝邵動、邵字紅、石廣文、李新華、李特梅、姜滿如、沈鋒平、周建東、鄭宇、楊波參與了部分編寫工作。
感謝我的老師,張明鳳、王善良、周國林、辛燕君、王守玉、申文甲、王羽、王殿兵、郭全、晉宗華、胡振仙、鄒明光、顧秉林、朱小梅、李淑琴、張仰森等在我成長之路上對我的栽培。
感謝我的朋友,艾本仁、白建峰、陳剛、陳希、丁將、符汪洋、顧元凱、葛國鋒、關正偉、劉星、劉慶生、羅曉宇、裴勇、裴郊區、王浩、邵安馨、石天澤、王靜競、楊浩杰、楊猛、楊禹等給我的幫助。
感謝網友,涂兆昊(神奇的人魚)、李若滕、伊文斯、張松華(non)、李顯發(李小明)、李睿意(lry)、王浩然(連心線)、李顯(江南暮春)、盧阿旺(authur)、黃文海(ggev)、神奇海螺、黑夜的憂傷、李澤銘(角逐新夢想)、蔡萬成(by)、張強(玄白)、吳霄(stra)、崔祥祥、鄧志光等在本教程開發過程中所起的作用。
邵發
2015年8月于北七家
第1章開始學習C/C++
1.1開發平臺
1.2第一個程序
1.2.1代碼解析
1.2.2在Windows XP環境下的問題
1.2.3常見的問題
1.3代碼與程序
1.4C語言和C++語言
第2章控制臺輸入與輸出
2.1控制臺輸出
2.1.1輸出整數
2.1.2用變量表示整數
2.1.3指定顯示寬度
2.1.4輸出小數
2.1.5用變量表示小數
2.1.6指定小數點后的位置
2.2控制臺輸入
2.2.1輸入整數
2.2.2輸入小數
2.2.3一次輸入多個數
2.3注釋
2.4空白
2.5常見問題
2.6綜合例題
第3章變量與常量
3.1變量
3.1.1變量的定義
3.1.2變量的命名
3.1.3變量的賦值
3.2整型變量
3.2.1char / short / int類型
3.2.2unsigned無符號類型
3.2.3*bool布爾類型
3.2.4*enum枚舉類型
3.2.5*long long長整數類型
3.3浮點型變量
3.4數的進制表示
3.4.1數的十進制表示
3.4.2數的十六進制表示
3.4.3數的二進制表示
3.5變量與內存
3.5.1二進制存儲
3.5.2內存
3.5.3變量的大小
3.5.4變量在內存中的表示
3.5.5變量的地址
3.5.6理解變量的賦值
3.6const常量
3.7*字面常量
3.8常用類型的范圍
第4章數組
4.1引例
4.2數組的定義
4.2.1數組的命名
4.2.2數組的長度
4.3數組的基本使用方法
4.3.1數組的初始值
4.3.2訪問數組中的元素
4.3.3用sizeof取得數組的大小
4.4數組的內存視圖
4.5常見問題
4.6數組的使用實例
4.6.1實例1
4.6.2實例2
4.6.3實例3
4.6.4實例4
4.7多維數組
4.7.1二維問題的表示
4.7.2二維數組的定義
4.7.3二維數組的初始化
4.7.4二維數組的本質
第5章字符與字符數組
5.1字符是什么
5.2字符的表示
5.3字符的顯示
5.4字符常量
5.5字符數組
5.5.1輸出字符串
5.5.2輸入字符串
5.5.3理解結束符的作用
5.5.4字符串的截斷
5.5.5常見問題
5.6轉義字符
5.6.1轉義字符的概念
5.6.2轉義字符的使用舉例
第6章表達式與操作符
6.1算術表達式
6.2賦值表達式
6.2.1左值
6.2.2理解賦值運算
6.2.3賦值與算術運算合并
6.2.4等號串連的寫法
6.3關系表達式
6.4條件表達式
6.5邏輯表達式
6.6逗號表達式
6.7自增/自減操作符
6.8*位操作符
6.8.1按位表示
6.8.2位運算規則
6.8.3移位操作
6.8.4應用舉例
6.8.5例題: 把unsigned int整數轉為4個字節
6.9類型的轉換與提升
6.10優先級與結合順序
6.10.1使用括號
6.10.2常用的優先級
第7章語句
7.1什么叫語句
7.2if語句
7.2.1使用復合語句
7.2.2最簡形式if
7.2.3完全形式if…else if…else if…else
7.3switch語句
7.3.1匹配
7.3.2跳轉與執行
7.3.3注意事項
7.4for語句
7.4.1引例
7.4.2使用for語句
7.4.3變形1: 省略初始表達式
7.4.4變形2: 省略第二個表達式
7.4.5變形3: 省略后置表達式
7.4.6變形4: 全部置空
7.4.7存在break語句
7.4.8存在continue語句
7.5while語句
7.5.1變形: 條件判斷內置
7.5.2例題
7.6do…while語句
7.7綜合例題1
7.8綜合例題2
第8章函數
8.1引例
8.2初步認識函數
8.3函數的定義
8.3.1函數名
8.3.2參數列表
8.3.3返回值類型
8.3.4函數的實現
8.3.5return語句的用法
8.4函數的調用
8.4.1函數的調用過程
8.4.2參數的順序
8.4.3函數的傳值調用
8.4.4忽略返回值
8.4.5直接使用返回值
8.5全局變量和局部變量
8.6變量的作用域與生命期
8.6.1變量的作用域
8.6.2變量的生命期
8.7變量名重名問題
8.8函數聲明與函數定義
8.8.1函數的聲明
8.8.2函數聲明相關問題
8.9main函數
8.10參數的隱式轉換
8.11*函數名重載
8.12*重載函數的匹配
8.12.1精確匹配
8.12.2模糊匹配
8.13*參數的默認值
8.14*內聯函數
8.15*函數的遞歸調用
第9章指針
9.1內存地址的表示
9.2指針的概念
9.3星號操作
9.4指針與數組
9.4.1指針加減法
9.4.2指針與數組的轉換
9.5指針作為函數的參數
9.6數組作為函數的參數
9.7指針作為函數的返回值
9.8const指針
9.9void*型指針
9.10安全地使用指針
9.11*二重指針
9.12*二維數組與指針
9.12.1作為函數的參數
9.12.2二維數組與指針的轉換
第10章結構體
10.1引例
10.2結構體概述
10.3結構體的基本用法
10.3.1變量定義和初始化
10.3.2訪問結構體的成員
10.3.3定義結構體數組
10.4結構體的內存視圖
10.4.1結構體的成員
10.4.2對齊與填充
10.5結構體的更多用法
10.5.1結構體的賦值
10.5.2結構體指針
10.5.3作為函數的參數
10.5.4作為函數的返回值
10.5.5作為結構體的成員
10.6*結構體的特殊寫法
10.6.1沒有類型名
10.6.2函數內部的結構體類型
10.6.3緊湊的形式
10.6.4C語言中的struct定義
10.7結構體的命名
10.8傳值與傳地址
10.9*位字段bitfield
10.10實例
第11章*聯合體
11.1概念
11.2進一步理解union
11.3實例
11.4union的替代方案
第12章動態分配內存
12.1引例
12.2動態分配內存
12.3內存管理器與堆
12.4對象的生命期
12.5實例1
12.6實例2
12.7常見問題
第13章鏈表
13.1概念
13.2鏈表的構造
13.2.1頭節點與末節點
13.2.2鏈表頭的作用
13.2.3常見問題
13.3有頭鏈表
13.3.1概念
13.3.2定義一個有頭鏈表
13.3.3添加一個節點
13.3.4有頭鏈表的遍歷
13.3.5按順序插入節點
13.3.6查找和刪除節點
13.3.7和無頭鏈表的比較
第14章引用
14.1引用的定義
14.2與指針的區別
14.3簡單的例子
14.4作為函數的參數
14.5作為函數的返回值
14.6const引用
第15章字符串
15.1字符串的三種形式
15.2字符串常量的多行表示
15.3字符串與普通數據
15.4字符串的遍歷
15.5字符串長度
15.6字符串復制
15.7字符串比較
15.8字符串插入和刪除
15.8.1刪除字符
15.8.2插入字符
15.8.3插入和刪除的效率問題
15.9字符串的分割
15.10用數組還是用指針
第16章標準C函數庫
16.1stdio.h
16.2math.h
16.3time.h
16.3.1time_t
16.3.2struct tm
16.3.3time取得系統當前時間
16.3.4localtime得到年月日時分秒
16.3.5mktime構造時間
16.4stdlib.h
16.5string.h
第17章文件操作
17.1認識文件
17.2保存數據
17.2.1fopen打開文件
17.2.2fclose關閉文件
17.2.3fwrite寫入數據
17.3讀取數據
17.4數據的存儲格式
17.5存儲格式: 按字節存儲
17.5.1指針指向的對象
17.5.2RunLength Encoding存儲
17.6存儲格式: 文本化存儲
17.6.1fprintf按行格式化寫入
17.6.2fgets按行讀取
17.7文件的隨機訪問
17.7.1fseek隨機訪問
17.7.2文件位置指示器
17.7.3隨機訪問示例
17.7.4fseek的物理限制
17.7.5文件被重復打開的情況
17.8*文件打開模式
17.9*常見問題
第18章多文件項目及編譯過程
18.1extern
18.1.1extern聲明全局函數
18.1.2extern聲明全局變量
18.1.3深入理解extern
18.2多文件項目的生成
18.2.1第一階段: 編譯
18.2.2第二階段: 鏈接
18.2.3*用偽代碼表示整個過程
18.2.4全量編譯與增量編譯
18.3頭文件#include指令
18.3.1為什么需要頭文件
18.3.2使用頭文件
18.3.3#include指令的原理
18.3.4頭文件的重復包含問題
18.3.5頭文件里的內容
18.4宏定義#define指令
18.4.1#define一個數值
18.4.2#define一個算式
18.4.3幾個常見的宏定義
18.5條件編譯指令#if
18.5.1#if…#endif
18.5.2#ifdef…#endif
18.5.3解決頭文件重復包含的問題
18.6*main函數的參數和返回值
18.6.1main函數的參數
18.6.2main函數的返回值
18.7*static的用法
18.7.1static修飾變量
18.7.2static修飾函數
第19章面向對象編程
19.1面向對象設計的過程
19.2實例演示
19.2.1需求與設計
19.2.2寫出代碼框架
19.2.3實現各個函數接口
19.3封裝
第20章類
20.1類和成員變量
20.1.1了解訪問修飾符
20.1.2訪問修飾符的用法
20.2類和成員函數
20.2.1訪問修飾符的限制
20.2.2了解this指針
20.2.3this指針的用法
20.3變量名字的覆蓋
20.4命名規范
20.4.1類名的命名規范
20.4.2成員函數的命名規范
20.4.3成員變量的命名規范
20.5類的封裝
20.6類的分離式寫法
20.7*const對象與const函數
20.7.1const成員函數
20.7.2const版本與非const版本
第21章構造與析構
21.1引例
21.2構造函數
21.2.1重載構造函數
21.2.2構造函數的調用
21.3析構函數
21.3.1析構函數的調用
21.3.2在析構函數中釋放資源
21.4自動生成的構造/析構函數
21.5默認構造函數
21.6構造函數的初始化列表
21.6.1參數名與成員變量名可以相同
21.6.2成員本身也是class類型
21.6.3混合使用兩種初始化方式
21.6.4必須使用初始化列表的情形
21.7構造與析構的順序
21.8分離式寫法
21.9*無名對象
21.10*構造函數與類型轉換
第22章動態創建對象
22.1回顧malloc/free
22.2用new/delete創建/銷毀對象
22.3new/delete與malloc/free的區別
22.4為new指定初始化參數
22.5默認構造函數的必要性
22.6注意事項
第23章繼承
23.1引例
23.2繼承的概念
23.3訪問修飾符protected
23.4成員函數的重寫
23.5虛擬繼承
23.5.1父類指針指向子類對象
23.5.2虛函數virtual
23.5.3virtual析構函數
23.6繼承關系下的構造與析構
23.7*多重繼承
23.8*繼承函數與純虛類
23.9*以protected/private方式繼承
第24章拷貝構造函數
24.1定義
24.2拷貝構造函數的調用
24.3默認的拷貝構造函數
24.4定義拷貝構造函數
24.5深度拷貝
第25章靜態成員
25.1static定義全局變量
25.2static定義全局函數
25.3與普通成員的區別
25.4static語法的特點
25.5應用1: 實例計數
25.6應用2: 單例模式
第26章朋友成員
26.1引例
26.2類的朋友
26.3friend的語法
26.4實例
26.5進一步討論
第27章重載操作符
27.1引例
27.2算術操作符
27.2.1參數類型
27.2.2加法的互換性
27.3賦值操作符=
27.3.1賦以不同的類型
27.3.2深拷貝
27.3.3相關問題及注意事項
27.3.4檢查項列表
27.4自增操作符++與自減操作符--
27.5關系操作符
27.6邏輯操作符
27.7類型轉換操作符()
27.8元素操作符[]
27.9輸入輸出操作符>>與<<
27.10操作符new與delete
27.11小結
第28章內部類和名字空間
28.1內部類
28.1.1內部類的語法
28.1.2內部類和普通類的區別
28.1.3內部類的用途
28.1.4內部類的分離式寫法
28.1.5內部enum類型
28.2名字空間
28.2.1名字空間的定義
28.2.2分離式寫法
28.2.3using語句: 解除前綴
28.2.4名字空間里的其他類型
28.2.5名字空間的應用場景
第29章模板
29.1函數模板
29.2類模板
29.3模板參數
29.4實例
第30章標準模板庫
30.1一般使用方法
30.2向量vector
30.2.1at/front/back
30.2.2push_back/pop_back/resize/clear
30.2.3iterator/const_iterator
30.2.4insert/erase
30.3list
30.3.1push_back/pop_back/push_front/pop_front
30.3.2size/clear
30.3.3front/back
30.3.4iterator
30.3.5insert/erase
30.4string
30.4.1append/clear
30.4.2size/capacity/resize/clear/length
30.4.3at
30.4.4字符串比較
30.4.5字符串查找
30.4.6substr
30.4.7insert/replace
30.4.8string作為函數參數
30.5map
30.5.1使用[]插入數據
30.5.2使用insert插入數據
30.5.3查找
30.5.4遍厲
30.5.5刪除
30.6stack
30.7queue
第31章異常
31.1一個例子
31.1.1throw
31.1.2try…catch
31.2try的用法
31.3catch的用法
31.3.1匹配所有類型
31.3.2異常必須被捕獲
31.4throw的用法
31.5常見問題
31.5.1異常與錯誤的區別
31.5.2不在構造函數中拋出異常
31.5.3不在析構函數中拋出異常
31.5.4關于finally
附錄A用VC2008創建項目
附錄B有符號整數與無符號整數
附錄C枚舉類型
附錄DVC2008調試方法
附錄EVS2008常見問題匯總
附錄F字面常量
附錄GASCII碼表
附錄H位字段
附錄Itypedef的用法
附錄J編碼規范
附錄KC++與C語言的區別
附錄L二進制、十進制與十六進制