撼不動的C語言!
譯文作者 | Serdar Yegulalp
譯者 | 布加迪
策劃 | 云昭
數(shù)十年來C語言一直可謂是編程界的扛把子。Linux、Windows、Mac和許多其他操作系統(tǒng)的內(nèi)核都能看到它的身影。C語言幾乎可以寫任何程序,在編程語言中的地位,德高望重。它甚至可能是有史以來最具影響力的語言。它的語法啟發(fā)了許多其他語言,包括Cpp、Csharp、Java、JavaScript、Go、Perl等等。
自1972年以來,C編程語言一直是構(gòu)建軟件的主力語言之一。但是過去50年以來,已經(jīng)涌現(xiàn)出數(shù)十種新語言,這些后輩語言的表現(xiàn)又如何?其中一些正在挑戰(zhàn)C的統(tǒng)治地位,而另一些正在不斷蠶食其地位。
撼山易,撼C語言難!在性能、裸機(jī)兼容性和普及性方面幾乎沒有語言能夠擊敗C。不過仍有必要看看C與一些主流語言相比表現(xiàn)如何。本文介紹了它與C++、Java、C#、Go、Python及最新的語言Carbon的詳細(xì)對比。
C與C++
C經(jīng)常與C++相比較;顧名思義,C++是作為C的擴(kuò)展而創(chuàng)建的。C++和C之間的差異很大,甚至可以說差異過大。
雖然C++在語法和方法上仍然酷似C,但提供了許多有用的功能,這些功能是C本身并不直接隨帶的:命名空間、模板、異常和自動內(nèi)存管理等。一般,需要頂級性能的項目(比如數(shù)據(jù)庫和機(jī)器學(xué)習(xí)系統(tǒng))通常用C++編寫,利用這些功能最大限度地發(fā)揮系統(tǒng)的性能。
此外,C++的步子比C邁得更大。即將發(fā)布的C++ 23帶來了更多的功能,包括模塊、協(xié)程和模塊化標(biāo)準(zhǔn)庫,以加快編譯和更多的代碼。相比之下,C標(biāo)準(zhǔn)的下一個計劃版本C2x卻沒增加多少功能,而是專注于保持向后兼容性。
問題在于,C++中的所有優(yōu)點也可能是缺點。軟件功能使用的C++越多,引入的復(fù)雜性就越大,結(jié)果處理起來就變得越困難。如果開發(fā)人員只關(guān)注C++的一小部分,可以避免它的許多陷阱。甚至一些公司想要完全避免這種復(fù)雜性,比如說,Linux內(nèi)核開發(fā)團(tuán)隊避免C++,雖然該團(tuán)隊將Rust視為未來增添內(nèi)核功能的語言,Linux的大部分仍將用C語言編寫。
C與Java
Java在幾十年間依舊是企業(yè)軟件開發(fā)的主力軍,也是整個開發(fā)界的主力軍。Java語法大量借鑒了C和C++。不過與C不同,Java默認(rèn)情況下并不編譯成本機(jī)代碼。相反,Java的JIT(即時)編譯器編譯Java代碼,以便在目標(biāo)環(huán)境中運行。JIT引擎根據(jù)程序行為在運行時優(yōu)化例程,從而實現(xiàn)了提前編譯的C無法實現(xiàn)的多種優(yōu)化。在適當(dāng)?shù)那闆r下,JIT編譯的Java代碼可以接近甚至超過C的性能。
而且,雖然Java運行時環(huán)境自動執(zhí)行內(nèi)存管理,但可以繞過這種處理。比如說,Apache Spark使用Java運行時環(huán)境的“不安全”部分來直接分配和管理內(nèi)存,并避免JVM垃圾回收系統(tǒng)的開銷,從而部分優(yōu)化了內(nèi)存中處理。
Java奉行“一次編寫,隨處運行”的理念,也使Java程序可以在對目標(biāo)架構(gòu)基本不需要調(diào)整的情況下運行。相比之下,雖然C已經(jīng)移植到許多架構(gòu)上,但任何特定的C程序可能仍需要定制,才可以在Windows與Linux上正常運行。
這種可移植性和強(qiáng)大性能的結(jié)合,加上龐大的軟件庫和框架生態(tài)系統(tǒng),使Java成為構(gòu)建企業(yè)應(yīng)用程序的首選語言和運行時環(huán)境。
Java比不上C的一個方面是,C從不旨在競爭:它靠近硬件運行,或者直接與硬件打交道。
C代碼被編譯成機(jī)器代碼,機(jī)器代碼由進(jìn)程直接執(zhí)行。Java被編譯成字節(jié)碼,字節(jié)碼是中間代碼,JVM解釋器隨后將它們轉(zhuǎn)換成機(jī)器碼。此外,雖然Java的自動內(nèi)存管理大體上是優(yōu)點,但C更適合必須最優(yōu)化使用內(nèi)存資源有限的程序,因為它的初始占用空間很小。
C與Go
Go語法很大程度上歸功于C,作為分隔符的花括號和以分號結(jié)尾的語句只是兩個例子。精通C的開發(fā)人員通常可以直接上手Go,即使考慮到新的Go功能(比如命名空間和包管理)。
確保代碼可讀是Go的指導(dǎo)設(shè)計目標(biāo)之一:讓開發(fā)人員在短時間內(nèi)盡快上手Go項目,并熟悉代碼庫。C代碼庫可能很難分析,因為它往往變成某個項目和團(tuán)隊所特有的一大堆宏指令和#ifdefs。Go的語法及內(nèi)置的代碼格式化和項目管理工具旨在防止這種根本性問題。
Go還有諸如goroutines(協(xié)程)和channels(通道)之類的附加功能,這些語言級工具用于處理組件之間的并發(fā)和消息傳遞。C需要這類功能由手工控制,或者由外部庫提供,但Go直接就提供,因此構(gòu)建需要它們的軟件要容易得多。
Go與C最大的底層區(qū)別在于內(nèi)存管理。默認(rèn)情況下,Go對象可實現(xiàn)自動管理和垃圾回收。對于大多數(shù)編程工作來說,這非常方便。但這也意味著任何需要確定性處理內(nèi)存的程序都將更難編寫。
Go確實包括unsafe包,用來避開Go的一些類型處理安全機(jī)制,比如讀寫使用Pointer類型的隨意內(nèi)存。但unsafe附有警告:用它編寫的程序“可能無法移植,且不受Go 1兼容性指導(dǎo)準(zhǔn)則的保護(hù)。”
Go非常適合構(gòu)建命令行實用程序和網(wǎng)絡(luò)服務(wù)等程序,因為它們很少需要這種細(xì)粒度的操作。但是低級設(shè)備驅(qū)動程序、內(nèi)核空間操作系統(tǒng)組件以及其他需要嚴(yán)格控制內(nèi)存布局和管理的任務(wù)用C來創(chuàng)建再好不過了。
C與Python
如今只要一談起軟件開發(fā),Python似乎總是避不開。畢竟,Python是“第二好的語言”,無疑是用途最廣泛的語言之一,擁有成千上萬的第三方庫。
Python強(qiáng)調(diào)更注重開發(fā)速度而不是執(zhí)行速度,這也是它與C最大的不同之處。一個程序可能需要一個小時才能用另一種語言(如C)組裝起來,但僅需幾分鐘內(nèi)即可用Python組裝起來。另一方面,該程序在C中執(zhí)行可能需要幾秒鐘,但在Python中運行可能需要一分鐘。
一個好的經(jīng)驗法則是,Python程序運行起來通常比C程序慢一個數(shù)量級。但是對于現(xiàn)代硬件上的許多任務(wù)來說,Python足夠快了,這是它得到采用的關(guān)鍵。
另一個主要區(qū)別是內(nèi)存管理。Python程序完全由Python運行時環(huán)境管理內(nèi)存,因此開發(fā)人員不必?fù)?dān)心分配和釋放內(nèi)存方面的細(xì)節(jié)。但開發(fā)人員的輕松是以“運行時性能”為代價。
編寫C程序需要嚴(yán)格注意內(nèi)存管理,但由此生成的程序?qū)兇獾臋C(jī)器速度而言卻堪稱標(biāo)準(zhǔn)。
談完區(qū)別,二者在底層卻有深層的聯(lián)系:參考Python運行時環(huán)境是用C編寫的。這讓Python程序可以包裝用C和C++編寫的庫。第三方庫組成的Python生態(tài)系統(tǒng)有相當(dāng)一部分(比如用于機(jī)器學(xué)習(xí)的第三方庫)都以C代碼作為核心。在許多情況下,這不是用C還是用Python的問題,而是涉及應(yīng)用程序的哪些部分應(yīng)該用C編寫、哪些部分應(yīng)該用Python編寫。
如果開發(fā)速度比執(zhí)行速度更重要,而且如果程序的大部分高性能部分可以被隔離到獨立的組件中(而不是分散在整個代碼中),那么純粹的Python庫或結(jié)合Python庫和C庫都是比單獨的C更好的選擇。但在其他方面,C仍占統(tǒng)治地位。
C與Carbon
C和C++的另一個最近的競爭者是Carbon,這是一種目前正在大力開發(fā)的新語言。
Carbon旨在成為C和C++的現(xiàn)代替代品,它有簡單的語法、現(xiàn)代工具和代碼組織技術(shù),以及解決C和C++程序員長期面臨的問題的方案。它還旨在提供與C++代碼庫的互操作性,因此可以增量遷移現(xiàn)有代碼。這一切都受到歡迎,因為與最近開發(fā)的語言相比,C和C++在過去的工具和流程顯得很原始很簡陋。
那么有何缺點呢?目前,Carbon是一個試驗項目,尚未準(zhǔn)備好用于生產(chǎn)環(huán)境。
甚至沒有一個切實可行的編譯器,只有在線代碼瀏覽器。Carbon還需要一段時間才會成為C或C++的實用替代品,如果真可以替代的話。
原文鏈接:
??https://www.infoworld.com/article/3402023/why-the-c-programming-language-still-rules.html???