很多朋友問我學了很久的C語言,可是看一些稍微大一點的代碼還是有一些懵圈,自己寫一些程序也是漏洞百出,該如何得到提升呢?
“ 你平時都看哪些關于C語言編程的書籍 ? ”
“ 有一本叫XXX的書怎么樣 ? 要不要買一本學習一下 ? ”
。。.。。.
每次遇到這些讀者提問,我都不知道從哪個層面跟他談這個話題,索性今天就從C語言學習這一塊開始吧。
對于C語言的學習與進階,這“四大名著”如果不提及實在是不太專業。它們都一把年紀了,這一方面也說明C語言經久不衰,另一方面證明確實都是經典之作。
重要的是bug菌對這幾本書平均都有1~2遍的閱讀,更是深有體會,至今留在身邊的書籍中就有它們的身影~
第一本經典之作,是還在讀書期間導師推薦給我的,《C專家編程》:
目錄 · · · · · ·第1章 C:穿越時空的迷霧
1.1 C語言的史前階段
1.2 C語言的早期體驗
1.3 標準I/O庫和C預處理器
1.4 K&R C
1.5 今日之ANSI C
1.6 它很棒,但它符合標準嗎
1.7 編譯限制
1.8 ANSI C標準的結構
1.9 閱讀ANSI C標準,尋找樂趣和裨益
1.10 “安靜的改變”究竟有多少安靜
1.11 輕松一下——由編譯器定義的Pragmas效果
第2章 這不是Bug,而是語言特性
2.1 這關語言特性何事,在Fortran里這就是Bug呀
2.2 多做之過
2.3 誤做之過
2.4 少做之過
2.5 輕松一下——有些特性確實就是Bug
2.6 參考文獻
第3章 分析C語言的聲明
3.1 只有編譯器才會喜歡的語法
3.2 聲明是如何形成的
3.3 優先級規則
3.4 通過圖表分析C語言的聲明
3.5 typedef可以成為你的朋友
3.6 typedef int x[10]和#define x int[10]的區別
3.7 typedef struct foo{ 。。. foo; }的含義
3.8 理解所有分析過程的代碼段
3.9 輕松一下——驅動物理實體的軟件
第4章 令人震驚的事實:數組和指針并不相同
4.1 數組并非指針
4.2 我的代碼為什么無法運行
4.3 什么是聲明,什么是定義
4.4 使聲明與定義相匹配
4.5 數組和指針的其他區別
4.6 輕松一下——回文的樂趣
第5章 對鏈接的思考
5.1 函數庫、鏈接和載入
5.2 動態鏈接的優點
5.3 函數庫鏈接的5個特殊秘密
5.4 警惕Interpositioning
5.5 產生鏈接器報告文件
5.6 輕松一下——看看誰在說話:挑戰Turing測驗
第6章 運動的詩章:運行時數據結構
6.1 a.out及其傳說
6.2 段
6.3 操作系統在a.out文件里干了些什么
6.4 C語言運行時系統在a.out里干了些什么
6.5 當函數被調用時發生了什么:過程活動記錄
6.6 auto和static關鍵字
6.7 控制線程
6.8 setjmp和longjmp
6.9 UNIX中的堆棧段
6.10 MS-DOS中的堆棧段
6.11 有用的C語言工具
6.12 輕松一下——卡耐基-梅隆大學的編程難題
6.13 只適用于高級學員閱讀的材料
第7章 對內存的思考
7.1 Intel 80x86系列
7.2 Intel 80x86內存模型以及它的工作原理
7.3 虛擬內存
7.4 Cache存儲器
7.5 數據段和堆
7.6 內存泄漏
7.7 總線錯誤
7.8 輕松一下——“Thing King”和“頁面游戲”
第8章 為什么程序員無法分清萬圣節和圣誕節
8.1 Portzebie度量衡系統
8.2 根據位模式構筑圖形
8.3 在等待時類型發生了變化
8.4 原型之痛
8.5 原型在什么地方會失敗
8.6 不需要按回車鍵就能得到一個字符
8.7 用C語言實現有限狀態機
8.8 軟件比硬件更困難
8.9 如何進行強制類型轉換,為何要進行類型強制轉換
8.10 輕松一下——國際C語言混亂代碼大賽
第9章 再論數組
9.1 什么時候數組與指針相同
9.2 為什么會發生混淆
9.3 為什么C語言把數組形參當作指針
9.4 數組片段的下標
9.5 數組和指針可交換性的總結
9.6 C語言的多維數組
9.7 輕松一下——軟件/硬件平衡
第10章 再論指針
10.1 多維數組的內存布局
10.2 指針數組就是Iliffe向量
10.3 在鋸齒狀數組上使用指針
10.4 向函數傳遞一個一維數組
10.5 使用指針向函數傳遞一個多維數組
10.6 使用指針從函數返回一個數組
10.7 使用指針創建和使用動態數組
10.8 輕松一下——程序檢驗的限制
第11章 你懂得C,所以C++不在話下
11.1 初識OOP
11.2 抽象——取事物的本質特性
11.3 封裝——把相關的類型、數據和函數組合在一起
11.4 展示一些類——用戶定義類型享有和預定義類型一樣的權限
11.5 訪問控制
11.6 聲明
11.7 如何調用成員函數
11.8 繼承——復用已經定義的操作
11.9 多重繼承——從兩個或更多的基類派生
11.10 重載——作用于不同類型的同一操作具有相同的名字
11.11 C++如何進行操作符重載
11.12 C++的輸入/輸出(I/O)
11.13 多態——運行時綁定
11.14 解釋
11.15 C++如何表現多態
11.16 新奇玩意——多態
11.17 C++的其他要點
11.18 如果我的目標是那里,我不會從這里起步
11.19 它或許過于復雜,但卻是惟一可行的方案
11.20 輕松一下——死亡計算機協會
11.21 更多閱讀材料
附錄A 程序員工作面試的秘密
附錄B 術語表
一聽名字就感覺這書比較高大上,看完就是C語言“磚家”了,太形象生動,書的目錄展示了此書的全貌,你會發現處處都是你感興趣的,當時買來一本天天啃,越看越覺得自己無知。
看完這本書,你會對C語言不再停留在簡單的語法上,會以更深入的視角去欣賞它,回頭想想這本書應該完完整整看過兩遍吧~
第二本《C和指針》
目錄 · · · · · ·第1章 快速上手
1.1 簡介
1.1.1 空白和注釋
1.1.2 預處理指令
1.1.3 main函數
1.1.5 rearrange函數
1.2 補充說明
1.3 編譯
1.4 總結
1.5 警告的總結
1.6 編程提示的總結
1.7 問題
1.8 編程練習
第2章 基本概念
2.1 環境
2.1.1 翻譯
2.1.2 執行
2.2 詞法規則
2.2.1 字符
2.2.2 注釋
2.2.3 自由形式的源代碼
2.2.4 標識符
2.2.5 程序的形式
2.3 程序風格
2.4 總結
2.5 警告的總結
2.6 編程提示的總結
2.7 問題
2.8 編程練習
第3章 數據
第4章 語句
第5章 操作符和表達式
第6章 指針
第7章 函數
第8章 數組
第9章 字符串、字符和字節
第10章 結構和聯合
第11章 動態內存分配
第12章 使用結構和指針
第13章 高級指針話題
第14章 預處理器
第15章 輸入/輸出函數
第16章 標準函數庫
第17章 經典抽象數據類型
第18章 運行時環境
附錄 部分問題答案
參考文獻
與這本書的經歷真的是跌宕起伏,最早結實這本書是在剛畢業那家公司的書架上,估計被部門其他大佬翻閱過了無數次,書非常的破,甚至膠裝都要掉了,于是在公司有事沒事就讀著,確實是本好書,后面就自己買了一本新的。當時的我學得非常的認真,在上面做了很多的筆記。不幸的是,就在前年搬家的過程中給弄丟了,這比丟錢包還心痛呀,希望他被同行的朋友撿到,日子過得不要太差就好,千萬別進廢品站~后來因為這本書的內容也挺熟了,就沒有再買新的,實在想翻就拿電子檔看看,不過還是比較費眼睛。第三本《C陷阱與缺陷》
目錄 · · · · · ·第0章導讀
第1章詞法“陷阱”
1.1=不同于==
1.2& 和 | 不同于&& 和 ||
1.3詞法分析中的“貪心法”
1.4整型常量
1.5字符與字符串
第2章語法“陷阱”
2.1理解函數聲明
2.2運算符的優先級問題
2.3注意作為語句結束標志的分號
2.4switch語句
2.5函數調用
2.6“懸掛”else引發的問題
第3章語義“陷阱”
3.1指針與數組
3.2非數組的指針
3.3作為參數的數組聲明
3.4避免“舉隅法”
3.5空指針并非空字符串
3.6邊界計算與不對稱邊界
3.7求值順序
3.8運算符&&、|| 和 !
3.9整數溢出
3.10為函數main提供返回值
第4章連接
4.1什么是連接器
4.2聲明與定義
4.3命名沖突與static修飾符
4.4形參、實參與返回值
4.5檢查外部類型
4.6頭文件
第5章庫函數
5.1返回整數的getchar函數
5.2更新順序文件
5.3緩沖輸出與內存分配
5.4使用errno檢測錯誤
5.5庫函數signal
第6章預處理器
6.1不能忽視宏定義中的空格
6.2宏并不是函數
6.3宏并不是語句
6.4宏并不是類型定義
第7章可移植性缺陷
7.1應對C語言標準變更
7.2標識符名稱的限制
7.3整數的大小
7.4字符是有符號整數還是無符號整數
7.5移位運算符
7.6內存位置0
7.7除法運算時發生的截斷
7.8隨機數的大小
7.9大小寫轉換
7.10首先釋放,然后重新分配
7.11可移植性問題的一個例子
第8章建議與答案
8.1建議
8.2答案
附錄APRINTF,VARARGS與STDARG
附錄BKoenig和Moo夫婦訪談
bug菌和一些朋友們都叫他“避坑指南”,也是公認的好書,第一次看完基本上你會處于一種不敢寫代碼的狀態,害怕自己稍不留神就寫了個bug。不過好在這本書比較輕薄,也不記得看過多少遍,自從接觸到這本書以后就開始關注和記錄平時學習和開發中容易出問題的編程點,必須一讀~最后一本面試經典《你必須知道的495個C語言問題》
目錄。。.。。.第1章 聲明和初始化
基本類型
1.1 我該如何決定使用哪種整數類型?
1.2 為什么不精確定義標準類型的大小?
1.3 因為C語言沒有精確定義類型的大小,所以我一般都用typedef定義int16和int32。然后根據實際的機器環境把它們定義為int、short、long等類型。這樣看來,所有的問題都解決了,是嗎?
1.4 新的64位機上的64位類型是什么樣的?
指針聲明
1.5 這樣的聲明有什么問題?char *p1, p2; 我在使用p2的時候報錯了。
1.6 我想聲明一個指針,并為它分配一些空間,但卻不行。這樣的代碼有什么問題?char *p; *p=malloc(10);
聲明風格
1.7 怎樣聲明和定義全局變量和函數最好?
1.8 如何在C中實現不透明(抽象)數據類型?
1.9 如何生成“半全局變量”,就是那種只能被部分源文件中的部分函數訪問的變量?
存儲類型
1.10 同一個靜態(static)函數或變量的所有聲明都必須包含static存儲類型嗎?
1.11 extern在函數聲明中是什么意思?
1.12 關鍵字auto到底有什么用途?
類型定義(typedef)
1.13 對于用戶定義類型,typedef 和#define有什么區別?
1.14 我似乎不能成功定義一個鏈表。我試過typedef struct{char *item; NODEPTR next;}* NODEPTR; 但是編譯器報了錯誤信息。難道在C語言中結構不能包含指向自己的指針嗎?
1.15 如何定義一對相互引用的結構?
1.16 Struct{ } x1;和typedef struct{ } x2; 這兩個聲明有什么區別?
1.17 “typedef int(*funcptr)();”是什么意思?
const 限定詞
1.18 我有這樣一組聲明:typedef char *charp; const charp p; 為什么是p而不是它指向的字符為const?
1.19 為什么不能像下面這樣在初始式和數組維度值中使用const值?const int n=5; int a[n];
1.20 const char *p、char const *p和char *const p有什么區別?
復雜的聲明
1.21 怎樣建立和理解非常復雜的聲明?例如定義一個包含N個指向返回指向字符的指針的函數的指針的數組?
1.22 如何聲明返回指向同類型函數的指針的函數?我在設計一個狀態機,用函數表示每種狀態,每個函數都會返回一個指向下一個狀態的函數的指針。可我找不到任何方法來聲明這樣的函數——感覺我需要一個返回指針的函數,返回的指針指向的又是返回指針的函數,如此往復,以至無窮。
數組大小
1.23 能否聲明和傳入數組大小一致的局部數組,或者由其他參數指定大小的參數數組?
1.24 我在一個文件中定義了一個extern數組,然后在另一個文件中使用,為什么sizeof取不到數組的大小?
聲明問題
1.25 函數只定義了一次,調用了一次,但編譯器提示非法重聲明了。
1.26 main的正確定義是什么?void main正確嗎?
1.27 我的編譯器總在報函數原型不匹配的錯誤,可我覺得沒什么問題。這是為什么?
1.28 文件中的第一個聲明就報出奇怪的語法錯誤,可我看沒什么問題。這是為什么?
1.29 為什么我的編譯器不允許我定義大數組,如double array[256][256]?
命名空間
1.30 如何判斷哪些標識符可以使用,哪些被保留了?
初始化
1.31 對于沒有顯式初始化的變量的初始值可以作怎樣的假定?如果一個全局變量初始值為“零”,它可否作為空指針或浮點零?
1.32 下面的代碼為什么不能編譯?intf(){char a[]=“Hello, world!”;}
1.33 下面的初始化有什么問題?編譯器提示“invalid initializers ”或其他信息。char *p=malloc(10);
1.34 char a[]= “string literal”;和char *p=“string literal”; 初始化有什么區別?當我向p[i] 賦值的時候,我的程序崩潰了。
1.35 char a{[3]}= “abc”; 是否合法?
1.36 我總算弄清楚函數指針的聲明方法了,但怎樣才能初始化呢?
1.37 能夠初始化聯合嗎?
第2章 結構、聯合和枚舉
結構聲明
2.1 struct x1{ };和typedef struct{ }x2; 有什么不同?
2.2 這樣的代碼為什么不對?struct x{ }; x thestruct;
2.3 結構可以包含指向自己的指針嗎?
2.4 在C語言中用什么方法實現抽象數據類型最好?
2.5 在C語言中是否有模擬繼承等面向對象程序設計特性的好方法?
2.6 為什么聲明extern f(struct x *p); 給我報了一個晦澀難懂的警告信息?
2.7 我遇到這樣聲明結構的代碼:struct name {int namelen; char namestr[1];};然后又使用一些內存分配技巧使namestr數組用起來好像有多個元素,namelen記錄了元素個數。它是怎樣工作的?這樣是合法的和可移植的嗎?
2.8 我聽說結構可以賦給變量也可以對函數傳入和傳出。為什么K&R1卻明確說明不能這樣做?
2.9 為什么不能用內建的==和!=操作符比較結構?
2.10 結構傳遞和返回是如何實現的?
2.11 如何向接受結構參數的函數傳入常量值?怎樣創建無名的中間的常量結構值?
2.12 怎樣從/向數據文件讀/寫結構?
結構填充
2.13 為什么我的編譯器在結構中留下了空洞?這導致空間浪費而且無法與外部數據文件進行“二進制”讀寫。能否關掉填充,或者控制結構域的對齊方式?
2.14 為什么sizeof返回的值大于結構大小的期望值,是不是尾部有填充?
2.15 如何確定域在結構中的字節偏移量?
2.16 怎樣在運行時用名字訪問結構中的域?
2.17 C語言中有和Pascal的with等價的語句嗎?
2.18 既然數組名可以用作數組的基地址,為什么對結構不能這樣?
2.19 程序運行正確,但退出時卻“core dump ”(核心轉儲)了,怎么回事?
聯合
2.20 結構和聯合有什么區別?
2.21 有辦法初始化聯合嗎?
2.22 有沒有一種自動方法來跟蹤聯合的哪個域在使用?
枚舉
2.23 枚舉和一組預處理的#define有什么不同?
2.24 枚舉可移植嗎?
2.25 有什么顯示枚舉值符號的容易方法嗎?
位域
2.26 一些結構聲明中的這些冒號和數字是什么意思?
2.27 為什么人們那么喜歡用顯式的掩碼和位操作而不直接聲明位域?
第3章 表達式
求值順序
3.1 為什么這樣的代碼不行?a[i]= i++;
3.2 使用我的編譯器,下面的代碼int i= 7; printf(“%d ”, i++ * i++); 打印出49。不管按什么順序計算,難道不該是56嗎?
3.3 對于代碼int i=3; i=i++; 不同編譯器給出不同的i值,有的為3,有的為4,哪個是正確的?
3.4 有這樣一個巧妙的表達式:a^= b^= a^= b; 它不需要臨時變量就可以交換a和b的值。
3.5 可否用顯式括號來強制執行我所需要的計算順序并控制相關的副作用?就算括號不行,操作符優先級是否能夠控制計算順序呢?
3.6 可是&&和||操作符呢?我看到過類似while((c = getchar()) != EOF && c != )的代碼
3.7 是否可以安全地認為,一旦&&和||左邊的表達式已經決定了整個表達式的結果,則右邊的表達式不會被求值?
3.8 為什么表達式printf(“%d %d”, f1(), f2()); 先調用了f2?我覺得逗號表達式應該確保從左到右的求值順序。
3.9 怎樣才能理解復雜表達式并避免寫出未定義的表達式?“序列點”是什么?
3.10 在a[i] = i++;中,如果不關心a[]的哪一個分量會被寫入,這段代碼就沒有問題,i也的確會增加1,對嗎?
3.11 人們總是說i=i++的行為是未定義的。可我剛剛在一個ANSI編譯器上嘗試過,其結果正如我所期望的。
3.12 我不想學習那些復雜的規則,怎樣才能避免這些未定義的求值順序問題呢?
其他的表達式問題
3.13 ++i和i++有什么區別?
3.14 如果我不使用表達式的值,那我應該用i++還是++i來做自增呢?
3.15 我要檢查一個數是不是在另外兩個數之間,為什么if(a b c)不行?
3.16 為什么如下的代碼不對?int a=1000, b=1000; long int c=a * b;
3.17 為什么下面的代碼總是給出0?double degC, degF; degC= 5.0 / 9 * (degF - 32);
3.18 需要根據條件把一個復雜的表達式賦給兩個變量中的一個。可以用下面這樣的代碼嗎?((condition) ?a :b)= complicated_expression;
3.19 我有些代碼包含這樣的表達式。a ?b=c :d 有些編譯器可以接受,有些卻不能。為什么?
保護規則
3.20 “semantics of‘’change in ANSI C”的警告是什么意思?
3.21 “無符號保護”和“值保護”規則的區別在哪里?
第4章 指針
第5章 空指針
第6章 數組和指針
第7章 內存分配
第8章字符和字符串
第9章布爾表達式和變量
第10章C預處理器
第11章ANSI/ISO標準C
第12章標準輸入輸出庫
第13章庫函數
第14章浮點運算
第15章可變參數列表
第16章 奇怪的問題
第17章風格
第18章工具和資源
第19章系統依賴
第20章雜項
術語表
參考文獻
仔細看看這么詳細的目錄,估計沒幾個問題可以自信的給出答案吧,沒錯公司HR要研發部這邊出一套軟件筆試題目,基本那些C語言題目都會從這本書中抽取。
不過本書不建議大家集中時間認真的去讀,而是抽點時間逐個攻破,相信會有不少收獲,也更有看下去的欲望~
我手頭目前就這幾本有關C語言的書籍了,完全足夠日后的開發所需,雖然現在市面上又涌現了諸多教材,不過都有很高的相識度,甚至很多都是東拼西湊,知識的連貫性不夠~
當然這4本書籍我也不推薦大家馬上就去購買,搞技術的嘛,還是要多理性一點,畢竟我覺得不錯的,不一定是你適合的。
可以找一些電子檔,先閱讀一下相應的章節是不是真的感興趣,書籍作者的風格是不是真的符合你的口味。不然買了不看也是放在家里吃灰占地方,甚至有些朋友天天面對著一大堆還沒來得及看的書,會有一種深深的罪惡感,最終失去學習的動力。
“書不在多、新、厚,有神則明”~
來源:最后一個bug,作者:bug菌
版權歸原作者所有,如有侵權,請聯系刪除。
編輯:jq
-
C語言
+關注
關注
180文章
7598瀏覽量
136192 -
函數
+關注
關注
3文章
4306瀏覽量
62430 -
C++
+關注
關注
22文章
2104瀏覽量
73494 -
OOP
+關注
關注
0文章
14瀏覽量
8787
原文標題:毫無懸念的C語言"四大名著"
文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論