Don"t Learn C the Wrong Way ?
各位 我跟我的朋友最近想瞭解一下 C 語言 The C programming language
看到一個教程是 Learn C The Hard Way 一開始看挺順的 但我後來發現在Hacker news上也有人在討論這們教程是否會讓新手走偏了方向 Don"t Learn C the Wrong Way我知道 著名的 KR 應該是講解使用在UNIX上的 C語言但到現在C語言用各式各樣的環境上 有單片機 ARM LINUX WIDOWS 還有各種 compiler
如果我只想學了C語言 用來理解 RUBY的實現 MRI 那這個門該怎麼入阿我有找到虎書 但目前連C語言的語法都不太懂 所以還沒能看下去 我知道一定很花時間研究這些 但有沒有一條稍微能邊摸邊走的學習路線阿 ?
來遲了。前面已經有靠譜的回答了。
如果題主確實對CRuby的實現感興趣,想從源碼深入了解它的話,那麼下面兩本書都可以參考:- 《Ruby Under a Microscope: An Illustrated Guide to Ruby Internals》
- 官方網站:http://patshaughnessy.net/ruby-under-a-microscope
- Pat Shaughnessy,2013年
- 主要基於CRuby(MRI)講解,兼容的版本大致從Ruby 1.9到Ruby 2.1;也有兩章分別介紹了JRuby與Rubinius的
- 這本其實已經相當新了,跟最新的MRI來對比讀也不會很落伍。
- 《Rubyソースコード完全解説》(Ruby源碼剖析,Ruby Hacking Guide)
- 官方網站:http://i.loveruby.net/ja/rhg/
- 青木峰郎,2002年
- 對應Ruby 1.7.3版。這是Ruby 1.9之前的版本,也就是還在用老的MRI的樹解釋器而不是Ruby 1.9之後的新的YARV位元組碼解釋器。
- 這本書從現在的角度看是比較過時了,但即便是現在的MRI,在解釋器之外的地方還是有不少繼承自以前的設計的。想了解歷史的話推薦閱讀。
- 官網公開了全文,可免費閱讀:http://i.loveruby.net/ja/rhg/book/(日文原版)
- 有非官方的中文和英文翻譯。
至於要掌握了多少C語言知識才可以去閱讀MRI的源碼,我覺得只要掌握最最基本的語法,理解了指針特別是多級指針的意思之後就可以開始讀了,不必拘泥於先把C給徹底精通了再開始。那樣還真是本末倒置了。
至於什麼風格的C,題主要是看當前最新版的Ruby源碼的話,看這main()的聲明:ruby/main.c at trunk · ruby/ruby · GitHubint
main(int argc, char **argv)
{
...
}
這是現代的C。再看看Ruby 1.8的時候同一函數的聲明:
int
main(argc, argv)
int argc;
char **argv;
{
...
}
…嗯這就是古老的KR風格的C。
能讀懂KR風格的C已然不是閱讀現在的MRI源碼的必要技能。掌握C99的常規知識就完全足夠了。我沒有讀過Zed大大的《Learn C The Hard Way》,無法評價此書。
C語言本身簡單而靈活,其實隨便找本什麼入門書都挺好——除了一些著名的糟糕書之外(咳咳Zed大大這本還算不上著名的糟糕書之列,想來再怎麼不好其實問題也不大大。很多知識都是慢慢邊用邊掌握的,也不用指望一本入門書把事情都說對。題主引用的那篇博文語氣比較激進,讀的時候也自己多帶著思考的好。Zed大大的書可以讀,KR2也可以自己讀讀感受下。
MRI的實現用了一些技巧,在實現編程語言的解釋器中很常見,但在教通用的C語言知識的書上多半不會專門教的。例如:- 通過setjmp() / longjmp()來實現非局部跳轉(non-local control flow)。MRI中拋異常、跳轉離開一個block等功能都是這樣實現的。
- 使用「帶標記的值」(tagged value)來節省內存和提高性能。所謂帶標記的值,從源碼上看似乎是個普通的指向對象的指針,但實際上只是個普通的整數然後帶上幾位標記來表面自己不是真的指針。這樣,某些特殊類型的對象就可以直接「嵌入在指針」里,構成所謂「立即對象」(immediate object),節省了存對象的內存開銷,並且減少了訪問對象的間接層。MRI里Fixnum、TrueClass、FalseClass、NilClass等類型都是這樣實現的。在較新的、支持Flonum的MRI上,一定範圍內的Float也採用這種技巧實現。
- 在對象頭裡掏空間。例如說對於短的String對象,其字元串內容會直接塞在對象頭裡而不額外申請一個數組來存放。這跟上一點是類似的思路。
這些都不算什麼奇技淫巧,也不算偏門的知識,但它們也不太會出現在一般教C語言基礎的書里。
只要掌握了C語言最基本的內容,在本回答開頭介紹的那兩本書的引導下,這些技巧都會覆蓋到,不是問題。要想加強自己對C語言與底層系統之間的對應關係的理解,我還是誠意推薦《Computer Systems: A Programmer"s Perspective (3rd Edition)》(CS:APP)。第2版也很好,國內有印刷質量非常高的影印版,強烈推薦。
MRI的詞法分析器是手寫的,而語法分析是用Bison生成的。這parse.y實在複雜,其它版本的Ruby要敢說自己能跑很多Ruby代碼(兼容性過得去)的,它們的語法分析器幾乎都是從這個parse.y改造生成而來的。沒錯,JRuby、Rubinius和IronRuby都不例外。所以如果對MRI的語法分析部分感興趣的話,這Bison是得找資料來學習一下的。
——沒興趣的話這塊不碰也罷嗯。直接把它當作黑魔法,取已經做完語法分析的AST來用也能做很多事。如果讀了開頭那兩本Ruby書覺得不過癮,想深入學習的話,請參考:- 學習編程語言與編譯優化的一個書單 - 編程語言與高級語言虛擬機雜談(仮) - 知乎專欄
- 《自製編程語言》集中討論帖
- [Garbage Collection][垃圾回收][自動無用內存單元回收]相關讀物
展望未來,CRuby或許有機會獲取一些IBM貢獻出來的高性能組件。請跳傳送門:如何評價 IBM 的 Ruby + OMR? - RednaxelaFX 的回答
最後,如果題主對MRI很感興趣,但在閱讀代碼的過程中遇到了困難,歡迎在知乎提問題來討論具體的方面。有本比較老的書, 叫做 &, 講ruby的大致實現的, 隨手看看就行. 也不是很需要C基礎.
不過說真的, 有了解ruby實現的時間, 不如想辦法讓自己的ruby寫的更好一些... 看&抖機靈
KR:UNIX(分化之前的正統)的 C譚浩強第三版以前:DOS 下 Borland 的 Turbo C 2.0 編譯器/運行庫的 80-90% 的功能譚浩強第四版:Visual C++ 6.0(CL 12.0)的 C 編譯器/運行庫的 60-70% 的功能不過,C語言除了少部分實戰中很難用到的東西,核心應該是非常簡單的吧。。需要什麼hard way么 用C理解腳本語言解釋器,用C理解OpenGL來入門C語言,我也覺得是本末倒置
那篇噴文也看了,噴字元串那段打臉用glibc的源碼不更好么網易公開課:編程範式
個人對ruby不太感興趣,不過我覺得Linux C編程一站式學習不錯,而且這本書在git上有免費電子檔。
推薦閱讀:
※為什麼很多語言的實現裡面的 Lexer 都沒有使用 DFA?
※基於表驅動實現的詞法分析的一點疑問?
※C/C++語言有哪些不是上下文無關的語法規則?
※應該如何理解「上下文無關文法」?
※為什麼Objective-C 和 Swift 語言在其他平台上沒有相應的編譯器?