怎樣才叫 「精通」 C語言?


精通下棋的規則跟精通下棋是兩碼事,將前者縮寫為後者一般會引起歧義。


從高一時開始學習C,到現在已經十多年了,依然覺得自己還稱不上「精通」二字。事實上,在不同的階段,對「精通」總會有新的定義。很多時候,當你做了不同的項目、看了某篇博客、深入了解了某個開源項目的架構,或是看了Stackoverflow上的一篇回答,你都會覺得離「精通」又近了一步,但又覺得遙不可及。

我目前對「精通C語言」的定義可以簡單表達為:能夠正確的在項目中運用這門語言高效的完成所需的任務;使用這門語言時表達清晰、無歧義、易懂,不易出錯;了解這門語言的缺點和常見的陷阱,能夠及時發現也要能避免;能夠快速的了解和掌握其他項目的結構、風格、設計模式等,並且有能力修復、延續和擴充該項目;在需要的時候,能正確的處理C和彙編、編譯器、平台或是其他語言等之間的問題。

展開來講:

能夠正確的在項目中運用這門語言高效的完成所需的任務

正確的」這幾個字我認為很重要,要根據你的實際情況來做判斷,臨時性的問題可能用腳本就能解決,或者用像Python等語言就可以分分鐘解決的,有時就沒必要把C搬出來。如果僅僅是把C用來解決臨時性的問題的話,那麼一定是滿足了C的特點,比如追求性能,要處理的數據非常龐大,或者是資源有限等等。C是一門成熟高效的語言,要恰當的使用它才能事半功倍。

高效的」:很多C語言的小項目(1k-2k左右),從項目構思、需求分析、到畫出框圖、介面描述,然後從最簡單的main{return 0;}寫起一步步邊寫邊測,並且一直能夠保持-Wall=0的狀態,用最短的時間高質量的完成任務並交付,最終代碼有適當注釋,可讀性好。能連續敲打數百行代碼,且編譯後只有少量問題並且編譯修改幾次後,能很快達到零Warning狀態。(僅此一項技能,同一件事:有些人一個小時就能搞定,而且質量很高;有些人得花一個星期,而且代碼還各種問題。效率之差距可達數十倍之多)。

運用」:最好的詩人和作家都不一定能把新華字典辭海辭源背下來,他們只要能夠在需要的時候準確快速的找到他們要的典故、用法即可。C標準當然要熟,但除了常見的用法要了熟於心外,很多偏僻的用法只要做到知道有這回事,知道怎麼找即可

使用這門語言時表達清晰、無歧義、易懂,不易出錯;

說白了就是寫代碼的時候就要設身處地的為將來看代碼的人著想。

表達清晰

  • 變數名稱規範,有意義,長度合適。

  • 函數內部結構、流程要清晰。

  • 文件內部,介紹、includes、聲明、實現要清晰,內部函數和介面函數表達清晰

  • 項目內部,模塊劃分清晰,做到低耦合、高內聚。

無歧義:變數名,函數名等英文單詞的縮寫不能有歧義

易懂:不炫技,不「zuo」,沒有奇怪和偏門的用法,充分利用縮進,空格等方式使得複雜的句子別人一看就懂。難懂的地方,注釋要充分,不要吝嗇筆墨。

不易出錯:複雜的邏輯表達式和介面調用要利用縮進、回車等充分展開,避免調用順序錯誤導致BUG隱藏。以及所有類似的問題。

了解這門語言的缺點和常見的陷阱,能夠及時發現也要能避免;

這就要靠積累了,指針是C的寶也是最大的坑,是最容易出BUG的地方。一方面要能熟練掌握,另一方面也要思路清晰,儘早發現問題。很多時候充分利用一些靜態和動態分析工具,也能儘早的發現大部分問題(如valgrind等)。BUG埋的越深越久,查找的難度是指數級的增加的。

能夠快速的了解和掌握其他項目的結構、風格、設計模式等,並且有能力修復、延續和擴充該項目;

上面講如何寫代碼讓別人看的懂,這裡就要做到有效率的看懂別人的代碼並為己用。這是很現實的問題,不論是公司的歷史遺留項目,還是發現了一款能夠滿足自己項目需求的開源組件或是庫,你都要能讀懂別人的代碼。

很多時候,你還要沿著原作者的思路、縮進風格、代碼風格、設計模式等等繼續寫下去。很常見的,比如你要寫Linux驅動程序,你就要遵守Linux的縮進風格,了解類似的驅動的代碼和設備模型,完成自己的工作。最後很有可能還要做成補丁,寫commit comments,提交到郵件組,最終可能要反覆修改幾次,才能被主線接受。

多參與和研究一些優秀的C項目,就能很多優秀coder的良好的態度和風格就能影響到你,未來從頭開始一個項目時,很多東西就可信手拈來了。

在需要的時候,能正確的處理C和彙編、編譯器、平台或是其他語言等之間的問題。

有時你總會遇到這樣的問題,編譯出的代碼的行為和你想像的不一致。或是同樣的代碼在PC上運行正常,到設備上就段溢出了。這時你就需要查看反彙編代碼來查找問題到底出在哪裡,或是用gdbserver遠程連過去調試、或者是查看編譯器的哪個優化選項把代碼給搞砸了(比如前段時間的一個例子http://weibo.com/1164882944/C3cxuglI1)

有非常多的問題是在跨平台時遇到的,比如一個參考設計需要能在Win/Linux/Mac上編譯,那麼你的代碼的兼容性要很好。很常見的WinSock和Linux的socket這些底層庫要做兼容層等等。我現在基本要求自己儘可能的用C99的標準去實現C程序,這樣能夠做到非常好的兼容性,因為C並不是一門變化很快的語言。

----

歡迎補充

中國早期的程序員梁肇新曾在《編程高手箴言》 中提到,程序員的最高境界是 「手中無劍,心中也無劍」,也就是「人劍合一」的境界,在此共勉。


很簡單確很硬的標準:

別人用C/C++做東西,遇到了崩潰/泄漏他搞不定,來找你幫忙,就說明你精通了。


所謂的精通C語言,不僅在於了你說的語法層面,更是與C語言相關的一套東西,如*nix內核,網路,編譯,體系結構等。建議題主看完相關語法以及你說的《The standard C library》這本書後,可以看看CSAPP,現代操作系統,計算機體系結構,APUE等,後面就是實際項目的演練來達到你說的「精通」了。


我覺得既然要算精通,那至少應該把ISO-C99的標準文檔通讀一遍吧?


你這輩子用得到的部分你都精通,這就夠了。


很難的。C語言是很複雜的一個語言。有很多小東西都是800年不會用的,也沒什麼用,甚至從語言設計上講,理想狀態下就不應該存在。

所以,其實不用精通一個語言的。自己寫出來的程序跑得快跑得靠譜,容易被理解容易應付多變的用戶需求,這就比啥都強了。

雖然了解一個語言的邪門功能是常見的裝逼手段。自己挖坑自己填上,還是很能提供一些存在感的。


語言只是工具,看你用工具能做出好的東西,利用產品來體現出你對語言的認識


熟讀C語言標準。

用C作為主要語言開發N年以上(n待定),在多個平台和多種CPU架構下做過項目並相互移植過,知道且能控制語言從源代碼到二進位目標文件的每一個過程,知道一條語句可能會被編譯成什麼樣的彙編代碼,知道使用什麼樣的語句有利於編譯器優化。熟練使用常用的庫函數。

補充:有良好的代碼風格,其實這個很重要。

想到再寫。

說精通C語言不只是語言本身,還有語言依賴的工具鏈,語言的編譯過程,甚至一些演算法,計算機基礎知識,CPU的結構體系等等。因為C語言時偏向於硬體的,所以了解這些硬體相關知識也必不可少了。

另外肚子里沒那麼多別吹精通,遇到牛逼人面試會問死你的。


永遠不要說你精通了什麼。

怎麼算精通?

學無止境,有太多的知識了。

更何況除了舊知識還有新知識。

現在還記得一位教授的話,不要在簡歷上寫精通二字。


0 error(s), 0 warning(s)


我一直不覺得KR是本好的入門書。去找《C語言:現代方法》吧。


多年的面試經驗:

凡是敢在簡歷上寫「精通」xxx語言的, 最後都會被N個人用提前準備好各種必殺問題刁難,最後都很慘

每個面試官在看到「精通」xxx語言的時候,第一反應肯定是「看我不問倒你」

如果你準備好去面對這一切 那應該是精通了


你就算可以倒背字典也不一定能寫出一部小說


望題主保持單身,30歲時定能神功大成


N.E.V.E.R.


不說別的,隨隨便便能看懂nginx源碼,且能在基礎上做擴展開發,且代碼風格和nginx一致,這就能說明你c玩的很溜了。前面有人講什麼代碼風格還有什麼項目思想,那都是浮在表皮上的一群人蝦扯淡。


這種問題的答案可以很泛化。但我估計樓主需要的是精確式回答~~~本人斗膽以題答題——如果您能用C語言開發出一款象棋對戰程序,就可以算是C語言高手了。程序不需要太高的智能,能在扣扣業餘評測上三級即可


我是專門來看誰宣稱自己精通C語言的

---------------Update Start----------------

我以為我原來的回答很清楚了的(還自認為含蓄,幽默。。。其實我只是不想說的太激烈)。看到評論里提醒我在打醬油的留言,我才明白原來是很多人其實是不明白的。那麼我就匿名的補充下吧

1 知乎上應該沒有人認真的認為自己精通c語言。這年頭大牛這個詞不值錢,精通不是誰都能用的。

2 在快畢業的時候,問出了這個問題,應該也沒有機會精通c語言了。

3 我在篩簡歷的時候會這麼處理:對於高級職位,簡歷上寫精通c語言 c++語言的,忽略(有國際會議論文或同級別作品的除外)

以上為原回復包含的意思。

4 對於精通c語言,這個概念不同人的看法不一樣。我對這個概念理解如下:

精通c語言就是指精通c語言這門語言本身,精通c語言寫演算法,精通的是演算法。精通c語言寫網路協議,精通的是通信協議,能用c語言寫kernel的,精通的是操作系統。

能用隨便什麼語言實現一下C99或者隨便什麼完整的標準的front- end,應該可以算是對C語言本身的方方面面比較了解了,有語言改進的提案被標準或者某個方言接受,在某個方面應該是專家了。

5 對於精通c語言的人例子,一時想不出來。

我對C++的事情相對熟悉一點,給你舉一個類似的例子感受下吧。有家公司叫做Edison Desgin Group(Edison Design Group).這家公司名字又山寨,還只有五個人,看著很不起眼。可是其實他們都是C++標準委員會的成員,同時他們公司主營業務是賣(我認為)世界上最好的C++編譯器的front-end。(因為代碼是c寫的)

對於EDG的這幾位,我覺得可以在簡歷上寫精通了,但是其實他們絕對不會寫。

順便講一下,他們主頁的上還有一條很屌的FQA。

Q:你們那兒要人嗎?

A:不要。我們五個人挺好的,沒擴大的打算。

精通C語言的人,類似吧。。。我好像得了中年痴呆症,最近記憶非常不好,一時想不出來,請題主腦補。

6 精通的人可能真的很少吧。

我有幾年是在做一個商業軟體的C/C++的frontend。我們組參與制定了一個國家的C/C++的嵌入式國家標準,可是周圍也沒看到誰精通所有的。基本上也只能做到了解自己做到的那幾章標準。

如果非說牛人可能有一個我不認識的先輩。看cvs 提交log,這個哥們幾乎三個月左右寫了個C/C++的front-end,支持幾乎所有的常見的方言。可惜這哥們後來被調去做銷售還是行政管理了,學術上就沒啥建樹。不然這麼多年下來,精通應該算得上。

7 樓主問的是什麼叫精通,我就解釋下我理解的精通。就不偏題說推薦什麼書,怎麼學習了。反正經典也就那麼幾部。看標準更是看一會就要睡覺。不過這些都無所謂,別老惦記著精通的事兒就好了。

---------------Update End----------------


C語言就語言層面上講並沒有很多內容,除了用宏的技巧比較繁雜之外,其他的都很容易掌握。

精通C語言更多是在語言之外的東西,比如計算機原理,內存模型,系統優化這些。


推薦閱讀:

有沒有合適的學習路線來學習封裝在IDE下的原理?
如何開發中文演算法?
各種常見的編程語言最廣泛應用的領域分別是什麼?
為什麼C++不能返回數組?
現在有哪些比較大型的網站是用 Python 開發的?

TAG:編程語言 | 編程 | C編程語言 | 計算機科學 | C指針 |