# “解構 K&R C” 已死
> 原文:[Deconstructing K&RC Is Dead](http://c.learncodethehardway.org/book/krcritique.html)
> 譯者:[飛龍](https://github.com/wizardforcel)
我徹底失敗了。我放棄了多年以來嘗試理清C語言如何編寫的想法,因為它的發明是有缺陷的。起初,我的書中有一章叫做“解構 K&R C”。這一章的目的是告訴人們永遠不要假設它們的代碼是正確的,或者對于任何人的代碼,不管它有多出名,也不能避免缺陷。這看起來似乎并不是革命性的想法,并且對我來說它只是分析代碼缺陷和編寫更好更可靠代碼的一部分。
多年以來,我在寫這本書的這一塊時收到重挫,并且收到了比任何其它事情更多的批評和侮辱。不僅如此,而且書中這部分的批評以這些話而結束,“你是對的,但是你認為他們的代碼很爛這件事是錯的。”我不能理解,有一群被認為很聰明的人,他們的大腦中充滿理性,卻堅持“我可以是錯的,但是同時也可以是對的”的觀點。我不得不與這些學究在C IRC channels、郵件列表、評論上斗爭,這包括每一個它們提出一些怪異的、迂腐的刻薄意見的情況,需要我對我的文章進行更多的邏輯性修改來說服他們。
有趣的一點是,在我寫這部分之前,我收到了本書許多正面的評論。當時本書還在寫作中,所以我覺得確實需要改進。我甚至設置了一些獎金讓人們幫助改進。但可悲的是,一旦他們被自己的英雄蒙蔽,所崇拜的基調就發生了翻天覆地的變化。我變得十分令人討厭,只不過是嘗試教人們如何安全使用一個極易出錯的垃圾語言,比如C語言。這是我很擅長的東西。
這些批評者向我承認,他們不寫C代碼也不教授它,他們只是死記硬背標準庫來“幫助”其它人,這對我來說并不重要。我以一個開放的心態試圖解決問題,甚至設置獎金給那些有助于修復它的人,這也不重要。這可以使更多的人愛上C語言,并且使其它人入門編程,這更不重要。重要的是我“侮辱”了他們的英雄,這意味著我所說的話永遠地完蛋了,沒有人會再次相信我。
坦率地說,這是編程文化極為的黑暗、丑陋、邪惡的一面。他們整天在說,“我與你們同在”,但是如果你不屈服于大師們海量的學識,以及乞求他們準許你質疑他們所信奉的東西,你突然就會變成敵人。程序員費盡心機地把自己放在權力的寶座上,來要求別人贊許他們高超的記憶能力,或者對一些微不足道的瑣事的熟知,并且會盡全力消滅那些膽敢質疑的人。
這非常惡心,我對此也沒什么能做的。我對老程序員無能為力。但他們注定會失敗。它們通過標準化記憶所積累的學識,也會在咸魚的下一次翻身中蒸發掉。它們對考慮如何事物的運作方式,以及如何改進它們,或者將它們的手藝傳授給他人毫無興趣,除非這里面涉及到大量的阿諛奉承并讓他們覺得很爽。老程序員總會完蛋的。
他們向現在的年輕程序員施壓,我對此并不能做任何事情。我不能阻止無能程序員的誹謗,他們甚至根本不像專業的C程序員那樣。然而,我寧愿使本書有助于那些想要學習C語言以及如何編寫可靠的軟件的人,而不是和那些思維閉鎖的保守派做斗爭。它們貪圖安逸的行為給人一種感覺,就是他們知道更多迂腐的、可憐的小話題,就比如未定義行為。
因此,我刪除了書中的K&R C部分,并且找到了新的主題。我打算重寫這本書,但是并不知道如何去做。我猶如在地獄中,因為我自己非常執著于我覺得很重要的一些事情,但我不知道如何推進。我現在算是明白了這是錯的,因為它阻礙我將一些與C不相關的重要技巧教給許多新的程序員,包括編程規范、代碼分析、缺陷和安全漏洞的檢測,以及學習其它編程語言的方法。
現在我明白了,我將為這本書制作一些課程,關于編寫最安全的C代碼,以及將C語言代碼打破為一種學習C和編程規范的方式。我會卑微地說我的書只是一個橋梁,所有人應該去讀K&R C來迎合這些學究,并且在這些黃金法則的腳下頂禮膜拜。我要澄清我的C版本限制于一個固定的目的之中,因為這讓我的代碼更安全。我一定會提到所有迂腐的東西,比如每個書呆子式的,關于20世紀60年代的PDP-11電腦上空指針的要求。
之后,我會告訴人們不要再去寫別的C程序。這不會很明顯,完全不會,但我的目標是將人們從C帶到能更好地編程的其它語言中。Go、Rust或者Swift,是我能想到的能處理C語言主要任務新型語言,所以我推薦人們學習它們。我會告訴他們,他們的技能在于發現缺陷,并且對C代碼的嚴格分析將會對所有語言都有巨大的好處,以及使其它語言更易于學習。
但是C呢?C已經死了,它是為想要爭論A.6.2章第四段的指針未定義行為的老程序員準備的。謝天謝地,我打算去學習Go(或者Rust,或者Swift,或者其它任何東西)了。
- 笨辦法學C 中文版
- 前言
- 導言:C的笛卡爾之夢
- 練習0:準備
- 練習1:啟用編譯器
- 練習2:用Make來代替Python
- 練習3:格式化輸出
- 練習4:Valgrind 介紹
- 練習5:一個C程序的結構
- 練習6:變量類型
- 練習7:更多變量和一些算術
- 練習8:大小和數組
- 練習9:數組和字符串
- 練習10:字符串數組和循環
- 練習11:While循環和布爾表達式
- 練習12:If,Else If,Else
- 練習13:Switch語句
- 練習14:編寫并使用函數
- 練習15:指針,可怕的指針
- 練習16:結構體和指向它們的指針
- 練習17:堆和棧的內存分配
- 練習18:函數指針
- 練習19:一個簡單的對象系統
- 練習20:Zed的強大的調試宏
- 練習21:高級數據類型和控制結構
- 練習22:棧、作用域和全局
- 練習23:認識達夫設備
- 練習24:輸入輸出和文件
- 練習25:變參函數
- 練習26:編寫第一個真正的程序
- 練習27:創造性和防御性編程
- 練習28:Makefile 進階
- 練習29:庫和鏈接
- 練習30:自動化測試
- 練習31:代碼調試
- 練習32:雙向鏈表
- 練習33:鏈表算法
- 練習34:動態數組
- 練習35:排序和搜索
- 練習36:更安全的字符串
- 練習37:哈希表
- 練習38:哈希算法
- 練習39:字符串算法
- 練習40:二叉搜索樹
- 練習41:將 Cachegrind 和 Callgrind 用于性能調優
- 練習42:棧和隊列
- 練習43:一個簡單的統計引擎
- 練習44:環形緩沖區
- 練習45:一個簡單的TCP/IP客戶端
- 練習46:三叉搜索樹
- 練習47:一個快速的URL路由
- 后記:“解構 K&R C” 已死