深入學習C語言知識點checklist

字符串
學習時間:1.5W(“W”周,下同)
知識點checklist
strlen()函數的返回值是什麼類型的?
字符串strlen()的值,是否和他佔據的內存空間相同?
你是否知道strcpy函數存在的潛在風險?如何避免?
如果一個字符串沒有字符串結束符,而調用str開頭的庫函數,會發生什麼?
Strcpy(),strcat(),strcmp(),strncpy(),strncat(),strncmp()內部到底是如何運行的?這些函數到底對源字符串和目標字符串做了些什麼?你是否觀察過它們運行時兩個字符串內存的變化?
上面這些函數使用時,各有哪些需要注意的地方?
你會幾種字符串查找操作?
c語言中有字符串這個數據類型嗎?
對字符串進行操作的時候,是否爲字符串結尾符預留存儲位置?不然的話容易造成非常訪問內存。
數組
學習時間:2W
知識點checklist
你肯定知道,定義“int a[10];”,a[10]這個元素是無效的。
你知道幾種數組初始化的方法?
數組和指針有千絲萬縷的聯繫而又不同,你是否對他們在不同情況下的使用進行過詳細的總結?
“int calendar[10][20];”,這是一個什麼樣的數組?它擁有10數組類型的元素,還是20個?
“int a[10];”,數組名a在本質上是一個什麼?你是否打印過a的值?
你知道幾種獲取數組某元素的方法?
指針和數組相同嗎?什麼時候相同?什麼時候不同?
用指針和下標訪問數組元素,那種方式更快?
結構體
學習時間:1W
知識點checklist
你知道什麼是位域結構體嗎?如何定義它?如何使用它?
你知道字節對齊對結構體佔用內存空間大小的影響嗎?如何計算結構體佔用內存的大小?

學習時間:1W
知識點checklist
你知道宏的本質是什麼嗎?函數?語句?類型定義?或者其他?
你知道語言設計者爲什麼設計宏嗎?這些原因目前是否仍然成立?
你會設計帶有參數的宏嗎?
你知道使用宏的參數的的時候的注意事項嗎?
你會設計帶有可變參數的宏嗎?
你知道使用宏有什麼劣勢嗎?
你有沒有更好的替代方案?
枚舉
學習時間:0.5W
知識點checklist
是否可以指定枚舉中各項的值?
如果不指定值,枚舉的第一個值是多少?
枚舉的值是否可以是負數?
定義枚舉的時候,你是否專門定義了枚舉的最小值和最大值?
Switch
學習時間:0.5W
知識點checklist
switch(c)中的c的數據類型有哪些?
你是否在所有的switch中都加了default語句?
是否在所有的case中都加了break語句(一般情況的做法)?如果你不加break,將會發生什麼?
Static
學習時間:1W
知識點checklist
static的三個主要作用是什麼?
static的修飾的局部變量是保存在什麼地方的?全局變量哪?
static修飾的全局變量和函數,在其他的文件中是否可以訪問?如何訪問?
你知道static是c語言中實現封裝和隱藏的利器嗎?你是否經常使用?
定義在不同源文件中的static全局變量,編譯器是否允許他們的變量名稱相同?他們在內存中的地址是否相同?函數那?
const
學習時間:1W
知識點checklist
你是否經常使用const來表明不能夠被更改的變量?
你是否經常使用const常量來代替宏?
下面四種情況,你知道是各表示什麼意思嗎?
int  i_value= 10;
const  int* pvalue = &i_value
int  const *pvalue = &i_valueint*  const  pvalue= &i_value
const  int* const  pvalue = &i_value
你知道const常量如何初始化嗎?
Sizeof
學習時間:1W
知識點checklist
對於字符數組,strlen和sizeof的值是否相同?
Sizeof本質上是函數還是宏?
Sizeof的返回值是什麼類型?
指針
學習時間:3W
知識點checklist
“int *p;”&p,p,*p他們的值分別表示什麼含義?
你定義的指針初始化了沒?
你理解指針的指針的概念嗎?你會使用嗎?
“int *pi_value; pi_value = 0x100000;” pi_value + 1的值是是多少?
你會定義函數指針嗎?
你會使用函數指針調用函數嗎?
關於指針和數組,請參見知識點數組。
動態分配內存
學習時間:1W
知識點checklist
動態分配的內存是保存在什麼地方的?
什麼情況下使用動態分配內存?
動態申請內存一定要釋放,否則會內存泄露。你是否使用過內存檢測工具?
函數
學習時間:1W
知識點checklist
如何查看函數在內存中的地址?
如何給一個函數指針賦值?
你是否會定義可變入參函數
你是否可以區分函數的形參與實參?
如何定義函數名,以準確的表達函數的用途?
你是否使用const來修飾函數入參和返回值,以表的特定的含義?
遞歸如何使用?
變量
學習時間:1W
知識點checklist
全局變量,局部變量,常量分別保存在內存中的什麼地方?
不同類型的變量,你是否知道其作用域?
全局變量和局部變量是否可以重名?你是否在這樣做?
局部變量在函數退出後是否有效,爲什麼?
全局變量爲什麼不允許定義在頭文件中?有何危害?
鏈接(linux)
學習時間:1W
知識點checklist
鏈接位於編譯過程的那個階段?
動態鏈接庫和靜態鏈接庫使用時有何區別?
如何對動態鏈接庫進行動態加載(不用重啓程序而加載鏈接庫)?
動態鏈接有何優點?
動態鏈接庫中是否定義了非static的全局變量?你是否知道這是一個非常危險的動作?
動態庫中的全局變量(非static)和函數(非static)是否可以和上層全局變量和函數重名?重名後會發生什麼事情?
運行時的數據結構(linux)
學習時間:1W
知識點checklist
你知道什麼是段的概念嗎?
可執行程序可以分爲幾個段?每個段保存的是什麼內容?
如何查看可執行程序各個段的大小?
當函數被調用時發生了什麼?
你有沒有試過程序的棧空間最大有多大?程序超過此大小會發生什麼?
你使用的系統的棧是向下生長的,還是向上生長的?
Include
學習時間:0.5W
知識點checklist
1、如何避免對同一頭文件的多次include?
聲明
學習時間:1W
知識點checklist
什麼是聲明,什麼是定義?
你是否會運用c語言聲明的優先級規則?
關於複雜度:
軟件的首要技術使命是管理複雜度。
優秀程序員的一個特質是將複雜的事情簡單化,而非將簡單的問題複雜化。所以,他們一般會選擇簡單的解決方案。
極盡機巧,複雜的解決方案,除了將新手搞得暈頭轉向之外,別無他用。
閱讀優秀程序員的代碼,是一種享受,你很少遇到思維的阻力,你可以盡情的享受簡單之美。
所以,對難以理解的語言特性,要慎用、少用,最好不用,而以簡單的解決方案替代之。但是,在做這些之前,你必須對這些知識點理解深刻。
如果你發現有什麼錯誤,請和我聯繫。
如果這些知識點你90%以上都不知道,或者理解不深刻——我希望你可以加入DS計劃,共同學習。
如果這些知識點你90%以上都知道,並且理解深刻——我希望你也可以加入DS計劃,成爲知識點專家,對新手進行指導。
如果你知道的比上面列出的還要多,或者還有你認爲非常重要的,建議你也分享出來,對上面列舉的內容進行優化。
原文地址:http://blog.csdn.net/chgaowei/archive/2009/10/27/4731498.aspx

=======================================================

1、知識點組織得不是很好,顯得有些凌亂,有些相關知識點被分割到了多個地方,有些不夠全面,從學習的角度來將,不是非常好。
例如開始就從字符串操作講起,我覺得不是很好。原因是字符串操作只是庫函數,對於c語言的字符串,我們開始只要知道是0結束就夠了,函數後面在慢慢學習。瞭解字符串函數最好的辦法,就是自己實現這些函數,然後跟源代碼進行比較,找出差距。
例如宏和Include,不應該分開,而應該作爲預處理統一學習。預處理主要包括宏替換、文件包含和條件編譯三部分,另外的一些慢慢再瞭解就可以了。
此外,我覺得應該把static、const這些限定詞和變量結合在一起學習,順便把其它限定詞auto、extern、register、 volatile、restrict、inline等整合在一起,從變量的類型(存儲格式)、生命週期、作用域、可視性、存儲分配等各種角度出發進行說明。
2、有些提問不是很恰當。
例如sizeof本質上是函數還是宏?因爲sizeof既不是函數,也不是宏,這麼提問容易讓人產生誤解。要想弄明白sizeof具體是什麼,至少要明白編譯的整個過程,弄明白編譯時和運行時的概念。
例如數組提到的定義int a[10]; a[10] 這個元素是無效的。這種說法並不完全正確,a[10]並非無效,如果真弄明白了具體含義,完全是可以這麼使用的(當然一般不推薦)。
3、學習時間的安排
像Switch、枚舉之類的,如果有人講解,一天就足夠了。而數組應該和指針放在一起,由於指針是c語言的難點之一,恐怕3周的時間都不一定足夠。
4、應該把c語言的學習當作當作一個系統,分成多個階段。
個人覺得分爲三個階段比較合適:
第一階段是c語言本身,主要是類型、操作符、表達式、語法結構、函數、指針、數組、結構等,想完全弄清楚這些其實很不容易。入門可以參照譚浩強的那本教科書,不過這本書只適合瞭解一下,不深入,而且裏面有些地方和例子都不是很好。還是推薦K&R的《The C Programming Language》,最好是英文原版的。這階段可以同時學習《數據結構》,嘗試實現一些鏈表、樹的操作。
第二階段是結合着實際情況,加深對函數以及相關知識的認識,試着編寫一些小軟件,實現一些小功能。可以和《APUE》一起學習,裏面講到的例子都可以自己寫一下。
第三階段是深入學習編譯原理、操作系統等知識,瞭解代碼是如何從文本文件一步一步變成可執行文件的,知道棧、堆分別是什麼,清楚程序的存儲空間佈局,庫函數和系統調用的區別等。這階段可以在某個方面深入下去,編寫一個比較大的軟件,例如一個簡單的網絡程序、數據庫系統或者編譯器等。
因此知識點中的鏈接、運行時的數據結構、結構體中的內存對齊等和其它知識點放在一起並不是很好,畢竟大部分其它大部分題目都是c語言本身的知識,而這些知識點不少都是要看具體實現的,甚至有些並沒有標準答案。
另外,還有一些題外話:
1、現在已經比較少使用c語言開發軟件了,c語言對開發者的要求比較高,c語言不是一天兩天就能掌握的,因此首先要弄清楚自己是否真的對技術感興趣,對技術有種刨根問底的衝動,而且願意爲此花功夫。如果僅僅是想搞搞應用,要快速實現某個功能,而不追求效率,不在乎具體實現方式,最好還是去學習更高級的語言。
2、 c和c++不是一個語言,所謂c++是c語言的超集也是不正確的,如果當初c++的名稱是d語言之類的,可能就不會有這麼多麻煩了。最主要兩者的指導思想是不一樣的,c語言默認其使用者什麼都懂,所以將一切的控制都交給開發者自己去完成,語言本身不作太多限制,給開發者最大的自由度。這麼做的好處和壞處都是非常明顯的,沒有誰比誰好的問題,只有是否適用的問題。
3、語言本身只是一個工具,將我們瞭解的計算機知識發揮、展示出來的工具,但基礎知識遠遠比語言本身更重要。如果認爲學好了一門語言,就是所謂的高手了,那是不切合實際的。當然語言本身也需要我們花費很大精力,畢竟掌握好一個工具,更能讓我們的工作事半功倍。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章