(盡管你可以在 Excel 中編寫光線追蹤程序但最好還是使用其他語言) https://m.toutiao.com/is/eXb3Ueb/ 以下為譯文: 為什么說C不是最好的語言?首先,這個世上沒有最好的編程語言。每種語言都有獨特的優(yōu)勢以及適用情況,所以盡管你可以在 Excel 中編寫光線追蹤程序,但最好還是使用其他語言。因此,我們都需要了解編程語言的限制,不要抱怨 Web 服務(wù)器不是用 Fortran 編寫的,也不要抱怨基本沒有任何應(yīng)用使用 Perl 或 C++作為內(nèi)部腳本語言。我認為 C 語言不太理想的方面包括以下幾點(除了 C 比較老,發(fā)展不快之外,當(dāng)然還與個人的喜好有關(guān))。 其次,有些時候,C 的語言不夠明確。比如,*可以是二進制乘法運算符、一元解引用運算符,也可用于聲明指針。 再者,有些情況不夠安全,例如越界訪問數(shù)組這種極其常見的錯誤都沒有運行時檢查,這一點連 Borland Pascal 都比不了,更不用說更現(xiàn)代的編程語言了(盡管你會為了提高性能關(guān)閉這個編譯選項)。此外,指針讓我們很難保持一切井然有序。再加上一些其他情況,比如調(diào)用函數(shù)不需要事先聲明原型,這樣很容易將錯誤類型的參數(shù)傳遞給函數(shù)。 最后,C 的標(biāo)準(zhǔn)庫非常有限。有些編程語言甚至擁有開箱即用的 Web 服務(wù)器(或者至少有構(gòu)建 Web 服務(wù)器所需的所有模塊),但 C 標(biāo)準(zhǔn)庫甚至連 Web 服務(wù)器的容器也沒有。 為什么我還是喜歡C?盡管如此,我還是十分喜歡 C,因為它是一種簡單的語言。從某種意義上說很簡單,很容易表達自己的想法以及期望。 舉個例子,假設(shè)兩個數(shù)組有兩個偏移量,其中一個可以為負數(shù),如果使用C語言編寫,則可以寫成: arr[off1 + off2] 如果是Rust,則需要寫成:
通常,C 的循環(huán)也比 Rust 的迭代器組合更為簡潔(當(dāng)然 Rust 也允許使用前一種方式,但 linter 并不滿意,它會建議你使用迭代器來代替)。類似地,memset和 memmove也是功能十分強大的工具。 在大多數(shù)情況下,你都可以預(yù)見到編譯的結(jié)果,即對象在內(nèi)存中的表示方式,以及如何通過不同的方式理解編譯后的結(jié)果(新版 C 標(biāo)準(zhǔn)中這一點變得更困難,這都要怪 C++,我稍后再詳細介紹)。另外,你也很清楚函數(shù)調(diào)用的結(jié)果等等。由于這個原因,C 被稱為可移植的匯編語言,所以我非常喜歡 C。 我們拿汽車做個類比,C 語言就像一輛跑車,擁有手動變速箱,可以提供最佳性能,但是如果你不熟悉離合器和掛擋操作,那么變速箱很容易被損壞,甚至可能損壞發(fā)動機,當(dāng)然,油門踩得過大也有可能沖出馬路。然而,與自動變速箱相比,這種車輛的發(fā)動機能量更大,而且你可以預(yù)測性能,還可以炫車技,這些在其他車輛上都是不可能的。 這與C++有什么關(guān)系?下面,我們來說一說 C++,其實我不討厭 C++。我不能否認,與 C 相比, C++ 擁有兩個優(yōu)點:
另一方面,C++ 有兩個特征,我非常不喜歡。 首先是這門語言的整體性質(zhì)。其他編程語言擁有的流行功能最終都會進入 C++。因此,每過幾年,C++標(biāo)準(zhǔn)就會添加一些新功能。最終,這門語言就變得有點怪異,沒人能夠完全掌握,而且許多功能都是抄襲的其他語言?;旧厦總€人在編寫代碼的時候,都會選擇一個 C++的子集,然后忽略其他功能的存在。另外,我們究竟應(yīng)該使用哪個 C++版本的功能,并沒有一套標(biāo)準(zhǔn)的方法。Rust 在包的范圍內(nèi)提供了版本管理。據(jù)我所知,C++也曾嘗試過引入“代際”的概念來實現(xiàn)同樣的功能,但沒有成功。我經(jīng)常聽到有人獨自編寫 C 編譯器,卻從來沒聽說過有人編寫 C++編譯器。 其次,實際上 C++不僅是多種語言,而且還是一種元語言(即模板)。我了解 C++的創(chuàng)建初衷,也同意它對于與類型無關(guān)的代碼的處理,比 C 預(yù)處理器更好。但實際上,它產(chǎn)生的代碼十分可怕,原本是“頭文件僅包含聲明,實現(xiàn)放在編譯好的代碼中”,變成了“頭文件包含所有項目會用到的代碼”。我不喜歡過于冗長的編譯時間,但這種方式只能讓情況更糟。 最后,我覺得 C++的出現(xiàn)反而給 C 帶來了約束以及不良影響。我不是在討論 C/C++,也不是指 C 與 C++的共通之處,我討論的是耦合對標(biāo)準(zhǔn)和編譯器都有不良影響。一方面,C++建立在 C 之上,從而得到了極大的發(fā)展;另一方面,如果 C++中沒有 C 遺留下來的大多數(shù)功能的話,情況可能會更好(當(dāng)然,C++曾設(shè)法通過淘汰的方式逐步放棄某些 C 功能,但對于舊功能的支持仍然存在)。但是,C++ 24 能夠在 C++ 21 的基礎(chǔ)之上,發(fā)展成為一門獨立的編程語言嗎?大多數(shù)過時的功能都可以拋棄嗎?我對此表示懷疑。 C++編譯器對C的影響實際上,C 語言被當(dāng)成了沒有某些功能的 C++。比如微軟的 C 編譯器直到2015 版才開始支持 C99 功能(即便如此,它還是以 bug 修復(fù) bug 的方式來支持兼容性,因為客戶可能會震驚地發(fā)現(xiàn)可變參數(shù)宏居然可以運行)。但是,無論是標(biāo)準(zhǔn)的編譯器還是其他編譯器中都可以看到相同的方法,這些都是相關(guān)的問題。 主要問題在于,C 和 C++標(biāo)準(zhǔn)都是根據(jù)編譯器開發(fā)人員的反饋而編寫的,而且大多數(shù)都是 C++開發(fā)人員(有些人對現(xiàn)實世界編程一無所知,而且他們還認為現(xiàn)實世界的做法與自己的觀點完全吻合,真是令人窒息的操作)。雖然我也沒有遵循標(biāo)準(zhǔn)的開發(fā)程序,但是我很確定 C99 及其后版本中令人討厭的諸多功能皆來自那些編譯器開發(fā)人員。他們只從 C++的角度出發(fā)考慮,而且還將這些功能強加給了 C,還美其名曰簡化編譯器。 當(dāng)然我指的是“未定義的行為”以及編譯器的處理方式。這已成為一大毒瘤(只要你的代碼依賴于二進制補碼算術(shù),就會被認定具有未定義的行為,編譯器會拋棄整塊代碼)。 在我看來,以下四種行為盡管不值得提倡,但前兩個也并非不可接受:
由于 C++比 C 更高級(盡管它由許多來自 C 的特性,但都不建議使用,應(yīng)該使用 reinterpret_cast<>代替類型轉(zhuǎn)換,用引用代替指針,等等),所以不要期待 C++程序員能夠像 C 程序員那樣理解底層代碼。當(dāng)然,由于 C++程序員占絕大多數(shù),C/C++的耦合也極其常見,所以 C 編譯器通常會進行擴展以支持C++,并使用 C++重寫,以適應(yīng)其復(fù)雜度。所以很不幸,你不得不使用 C++編譯器來編譯 C 編譯器(還好我們還有 LCC、PCC 和 TCC 等純 C 編譯器)。 總結(jié)總的來說,我喜歡C所處的中層位置,它既可以完成一些底層的實現(xiàn),例如輕松地操作內(nèi)存,同時又可以享受高級語言的好處。另一方面,我對C++強烈的不滿來自其在設(shè)計上的選擇,而且這些設(shè)計影響了C標(biāo)準(zhǔn)和編譯器。 至少我不可能用 C90 特別版取代 C90,并假裝原來的版本不存在。 原文鏈接: 聲明:本文由CSDN翻譯,轉(zhuǎn)載請注明來源。 《新程序員001:開發(fā)者黃金十年》 2001 年創(chuàng)刊,20 年技術(shù)見證 人人都是開發(fā)者 家家都是技術(shù)公司 |
|