C語(yǔ)言是在B語(yǔ)言的基礎(chǔ)上發(fā)展起來(lái)的。
C的根源是ALGOL 60,1960年ALGOL 60是一種面向問(wèn)題的高級(jí)語(yǔ)言,離硬件比較遠(yuǎn),1963年的時(shí)候推出了CPL語(yǔ)言,CPL在ALGOL 60的基礎(chǔ)上更接近硬件一些,但很難實(shí)現(xiàn),1967年,對(duì)CPL語(yǔ)言做出了簡(jiǎn)化,推出了BCPL語(yǔ)言,1970年又對(duì)BCPL語(yǔ)言為基礎(chǔ),又做出了進(jìn)一步的簡(jiǎn)化,設(shè)計(jì)出了很簡(jiǎn)單的的而且接近硬件的BCPL語(yǔ)言簡(jiǎn)稱B語(yǔ)言(BCPL的第1個(gè)字母),并且用了B語(yǔ)言編寫的第1個(gè)UNIX操作系統(tǒng),在PDP 7上實(shí)現(xiàn),此時(shí)的B語(yǔ)言過(guò)于簡(jiǎn)單,功能有限,在1972-1973年間,D.M.Ritchie在B語(yǔ)言的基礎(chǔ)上設(shè)計(jì)出了C語(yǔ)言(BCPL的第2個(gè)字母),C語(yǔ)言保持了B語(yǔ)言的優(yōu)點(diǎn)(精煉,接近硬件)又克服了缺點(diǎn)(過(guò)于簡(jiǎn)單,數(shù)據(jù)無(wú)類型等)。它就經(jīng)受住了時(shí)間的考驗(yàn),在許多情況下仍然是最流行的編程語(yǔ)言之一。
Basic Combined Programming Language(BCPL),1967年由劍橋大學(xué)的Matin Richards在同樣由劍橋大學(xué)開發(fā)的CPL語(yǔ)言上改進(jìn)而來(lái)。BCPL最早被用做牛津大學(xué)的OS6操作系統(tǒng)上面的開發(fā)工具。后來(lái)通過(guò)美國(guó)貝爾實(shí)驗(yàn)室的改進(jìn)和推廣成為了UNIX上的常用開發(fā)語(yǔ)言。
BCPL有些類似于Fortran,也是典型的面向過(guò)程的高級(jí)語(yǔ)言。BCPL的語(yǔ)法更加靠近機(jī)器本身,適合于開發(fā)精巧,高要求的應(yīng)用程序,同時(shí)對(duì)編譯器的要求也不高。BCPL也是最早使用庫(kù)函數(shù)封裝基本輸入輸出的語(yǔ)言之一,這使得他跨平臺(tái)的移植性很好。BCPL的代碼用小寫字母書寫,有別于同時(shí)代的BASIC和PASCAL。BCPL對(duì)于字符串的支持很差,內(nèi)存管理也很糟糕。
BCPL本身并沒有被使用太長(zhǎng)時(shí)間。1970年,貝爾實(shí)驗(yàn)室的Ken Thompson在BCPL的基礎(chǔ)上改進(jìn)出了B語(yǔ)言,用于書寫UNIX。這個(gè)名字取自BCPL中的第一個(gè)字母。B語(yǔ)言使用的時(shí)間更短,三年后的1973年同樣是貝爾實(shí)驗(yàn)室的D.M.RITCHIE將B語(yǔ)言進(jìn)一步改進(jìn),并且取了BCPL中的第二個(gè)字母將其命名為C語(yǔ)言。而C語(yǔ)言和C++則在日后成為了最流行的高級(jí)語(yǔ)言。
B語(yǔ)言之父和C語(yǔ)言之父是同事,UNIX的作者
1964年,美國(guó)麻省理工、貝爾實(shí)驗(yàn)室、通用電氣準(zhǔn)備為GE-645大型機(jī)開發(fā)一套多人多任務(wù)操作系統(tǒng)MULTICS。
參與研發(fā)的一位貝爾實(shí)驗(yàn)室研究員肯·湯普森搞了一臺(tái)廢棄的DEC PDP-7計(jì)算機(jī),PDP-7字長(zhǎng)為18位,其標(biāo)準(zhǔn)主內(nèi)存為4K字(相當(dāng)于9千字節(jié)),可以升級(jí)到64K字(144 KB)。
DEC PDP-7
肯·湯普森伙同好友丹尼斯·里奇在上面研發(fā)了一個(gè)操作系統(tǒng)
丹尼斯·里奇
雖然這個(gè)操作系統(tǒng)比較簡(jiǎn)陋,但公認(rèn)是UNIX操作系統(tǒng)的雛形。已經(jīng)顯示出Unix的一些基本特征——簡(jiǎn)潔、高效、比當(dāng)時(shí)所有的操作系統(tǒng)都更注重交互性、對(duì)程序員友好。具備一個(gè)簡(jiǎn)陋的文件系統(tǒng),有特殊的文件類型及支持目錄和設(shè)備,甚至可以支持多任務(wù)。它的核心是用匯編寫的(匯編器也是肯·湯普森自己寫的),不具備可移植性。只支持兩個(gè)用戶。
這個(gè)系統(tǒng)除了使用匯編語(yǔ)言之外,還是用了一種在BCPL語(yǔ)言基礎(chǔ)上由肯·湯普森發(fā)明的B語(yǔ)言。叫B語(yǔ)言,就是把BCPL精簡(jiǎn)提煉的意思。
B語(yǔ)言不支持?jǐn)?shù)據(jù)類型和結(jié)構(gòu),接近底層。后來(lái)丹尼斯·里奇在B語(yǔ)言的基礎(chǔ)上增加了數(shù)據(jù)類型和結(jié)構(gòu)的支持,推出了C語(yǔ)言(意思是“BCPL”中排在B之后)。
肯·湯普森1970年借為貝爾實(shí)驗(yàn)室專利部開發(fā)一套文字處理系統(tǒng)的機(jī)會(huì),搞到了一臺(tái)PDP-11/20。他們把UNIX從PDP-7上移植了過(guò)來(lái),匯編寫的代碼沒什么可移植性,所以基本上就是在PDP-11上重寫了一次,讓C語(yǔ)言有了大顯身手的用武之地,也是第一次使用高級(jí)語(yǔ)言開發(fā)操作系統(tǒng)。
貝爾實(shí)驗(yàn)室成了Unix的第一個(gè)商業(yè)用戶,這是在1971年11月,在與系統(tǒng)配套的手冊(cè)中,該版本被稱做“First Edition”。
這么好用的東西在業(yè)界引起了極大反響,無(wú)論是UNIX還是C語(yǔ)言,成了當(dāng)時(shí)計(jì)算機(jī)科學(xué)界研究的熱門。兩位大神也從來(lái)不敝帚自珍,不但利用貝爾實(shí)驗(yàn)室無(wú)法限制UNIX版權(quán)大量郵寄這款操作系統(tǒng)給當(dāng)時(shí)的同仁,還經(jīng)常幫助他們解決安裝使用UNIX中遇到的問(wèn)題。
同時(shí),計(jì)算機(jī)科學(xué)家和工程師們也不斷對(duì)UNIX添磚加瓦,各路大神編寫了各種Unix版本和各種Unix-like操作系統(tǒng),其中有Linus Torvalds用C語(yǔ)言寫的linux。
B語(yǔ)言之父還是Go語(yǔ)言之父
后來(lái)肯·湯普森又在谷歌寫出了go語(yǔ)言代替c語(yǔ)言與Python/ target=_blank class=infotextkey>Python,谷歌的文化是提倡每周五天干工作事4天,剩余一天自己安排,go語(yǔ)言就是在這種情況下開發(fā)出來(lái)的。
Go的三個(gè)作者分別是:Robert Griesemer(羅伯特.格利茨默),Rob Pike(羅伯.派克)和 ken Thompson(肯.湯普森)。
.Robert在開發(fā)Go之前是Goole V8 、Chubby和HotSpot JVM的主要奉獻(xiàn)者;
.Rob主要是Unix 、UTF-8、 plan9的作者;
.ken主要是B語(yǔ)言、C語(yǔ)言的作者、Unix之父。
Go語(yǔ)言設(shè)計(jì)初衷
1、設(shè)計(jì)Go語(yǔ)言是為了解決當(dāng)時(shí)google開發(fā)遇到的問(wèn)題:
- .大量的C++代碼,同時(shí)又引入了JAVA和Python
- .數(shù)以萬(wàn)行的代碼
- .分布式的編譯系統(tǒng)
- .數(shù)百萬(wàn)的服務(wù)器
2、Google開發(fā)中的痛點(diǎn) :
- .編譯慢
- .失控 的依賴
- .每個(gè)工程師只是用了一個(gè)語(yǔ)言里面的一部分
- .程序難以維護(hù)
- .更新的花費(fèi)越來(lái)越長(zhǎng)
- .交叉編譯困難
3、如何解決當(dāng)前的問(wèn)題和痛點(diǎn)?
Go希望成為互聯(lián)網(wǎng)時(shí)代的C語(yǔ)言。多數(shù)系統(tǒng)級(jí)語(yǔ)言(包括Java和C#)的根本編程哲學(xué)來(lái)源于C++,將C++的面向?qū)ο筮M(jìn)一步發(fā)揚(yáng)光大。但是Go語(yǔ)言的設(shè)計(jì)者卻有不同的看法,他們認(rèn)為值得學(xué)習(xí)的是C語(yǔ)言。C語(yǔ)言經(jīng)久不衰的根源是它足夠簡(jiǎn)單。因此,Go語(yǔ)言也是足夠簡(jiǎn)單。
他們當(dāng)時(shí)設(shè)計(jì)Go語(yǔ)言的目標(biāo)是為了消除各種緩慢和笨重、改進(jìn)各種低效和擴(kuò)展性。Go是有那些開發(fā)大型系統(tǒng)的人設(shè)計(jì)的,同時(shí)也是為了這些人服務(wù)的,它是為了解決工程上的問(wèn)題,不是為了研究語(yǔ)言設(shè)計(jì);它還是為了讓我們的編程變得更舒適和方便。
C語(yǔ)言為什么仍被廣泛使用?
在今天,有許多編程語(yǔ)言可以讓開發(fā)者研發(fā)出比C更高效的應(yīng)用,這些語(yǔ)言擁有豐富的內(nèi)置庫(kù),可以簡(jiǎn)化與JSON、XML、UI、網(wǎng)頁(yè)、客戶端請(qǐng)求、數(shù)據(jù)庫(kù)鏈接、媒體操作等工作。盡管如此,C依然仍將長(zhǎng)期活躍在編程一線,為什么呢?
那讓我們一起來(lái)看看C語(yǔ)言都有哪些無(wú)與倫比的優(yōu)勢(shì)。
可移植性和高效
匯編語(yǔ)言的可移植性差,可C語(yǔ)言卻是一門可移植性非常好的語(yǔ)言。它盡可能地接近機(jī)器,同時(shí)它幾乎普遍適用于現(xiàn)有的處理器架構(gòu)。幾乎現(xiàn)有的每個(gè)架構(gòu)至少有一個(gè)C語(yǔ)言編譯器。如今,由于現(xiàn)代編譯器產(chǎn)生高度優(yōu)化的二進(jìn)制文件,用手寫的匯編來(lái)改進(jìn)它們的輸出并不是一件容易的事。
由于它的可移植性和效率高效,"其他編程語(yǔ)言的編譯器、庫(kù)和解釋器經(jīng)常用C語(yǔ)言實(shí)現(xiàn)"。像Python、Ruby和php這些解釋性語(yǔ)言的主要實(shí)現(xiàn)都是基于C語(yǔ)言,它甚至被其他語(yǔ)言的編譯器用來(lái)與機(jī)器通信。例如,C是Eiffel和Forth的中間語(yǔ)言。意味著這些語(yǔ)言的編譯器不需要為每個(gè)要支持的架構(gòu)生成機(jī)器代碼,而只是生成中間的C代碼,由C編譯器處理機(jī)器代碼的生成。
C語(yǔ)言也已成為開發(fā)人員之間交流的一種語(yǔ)言。正如Dropbox工程經(jīng)理、Cprogramming.com創(chuàng)建者Alex Allain所說(shuō):
C語(yǔ)言作為一門偉大的語(yǔ)言,可以讓大多數(shù)人以能接受的方式來(lái)表達(dá)編程中的常見想法。此外,C語(yǔ)言在使用中也有語(yǔ)法結(jié)構(gòu)也會(huì)出現(xiàn)在其他語(yǔ)言中,例如,用于命令行參數(shù)的argc和argv,以及循環(huán)結(jié)構(gòu)和變量類型,因此,即使對(duì)方不懂C語(yǔ)言,你也能找到一些共同點(diǎn)來(lái)與他們交談。
內(nèi)存操作
內(nèi)存管理和指針運(yùn)算是C語(yǔ)言的重要特征,使C語(yǔ)言成為系統(tǒng)級(jí)編程(操作系統(tǒng)與嵌入式系統(tǒng))的最佳搭檔。
在硬件/軟件邊界,計(jì)算機(jī)系統(tǒng)和微控制器將其外設(shè)和I/O引腳映射到內(nèi)存地址。系統(tǒng)應(yīng)用程序必須讀取和寫入這些自定義的內(nèi)存位置,以便與外界進(jìn)行通信。因此,C語(yǔ)言操作任意內(nèi)存地址的能力對(duì)于系統(tǒng)編程是必不可少的。
例如,一個(gè)微控制器可以這樣設(shè)計(jì):每當(dāng)?shù)刂?x40008001的第4位被設(shè)置為1時(shí),內(nèi)存地址0x40008000中的字節(jié)就會(huì)被通用異步接收/發(fā)送器(或UART,一種與外設(shè)通信的常見硬件組件)發(fā)送,并且在設(shè)置后,它將被外設(shè)自動(dòng)取消。下來(lái)演示一個(gè)C函數(shù)代碼,它通過(guò)該UART發(fā)送一個(gè)字節(jié):
#define UART_BYTE *(char *)0x40008000
#define UART_SEND *(volatile char *)0x40008001 |= 0x08
void send_uart(char byte)
{
UART_BYTE = byte; // write byte to 0x40008000 address
UART_SEND; // set bit number 4 of address 0x40008001
}
send_uart函數(shù)的第一行代碼可擴(kuò)展為:
*(char *)0x40008000 = byte;
這一行代碼是告訴編譯器將值是0x40008000解釋為一個(gè)指向char的指針,然后解除對(duì)該指針的定義(給出該指針?biāo)赶虻闹担ㄓ米钭筮叺?操作符),最后將字節(jié)值分配給該解除定義的指針。換句話說(shuō):把變量byte的值寫到內(nèi)存地址0x40008000。
將該函數(shù)的下一行代碼擴(kuò)展一下:
*(volatile char *)0x40008001 |= 0x08;
在這行代碼中,我們對(duì)地址0x40008001和數(shù)值0x08(二進(jìn)制的00001000,即第4位的1)進(jìn)行了or位運(yùn)算操作,并將結(jié)果存回地址0x40008001。換句話說(shuō):我們?cè)O(shè)置地址為0x40008001的字節(jié)的第4位。我們還聲明地址為0x40008001的值是易失性的。這就告訴編譯器,該值可能會(huì)被我們代碼外部的進(jìn)程所修改,所以編譯器在寫入該地址后不會(huì)對(duì)該地址的值做出任何假設(shè)。(在這種情況下,該字節(jié)在我們用軟件設(shè)置后就被UART硬件取消了)。這些信息對(duì)于編譯器的優(yōu)化器來(lái)說(shuō)是很重要的。例如,如果我們?cè)趂or循環(huán)中這樣做,而沒有指定該值是易失性的,編譯器可能會(huì)認(rèn)為該值在被設(shè)置后永遠(yuǎn)不會(huì)改變,并在第一個(gè)循環(huán)后跳過(guò)執(zhí)行該命令。
確定資源使用
開發(fā)人員進(jìn)行系統(tǒng)編程不能依賴的一個(gè)常見語(yǔ)言特性就是垃圾收集,甚至對(duì)一些嵌入式系統(tǒng)來(lái)說(shuō),只能進(jìn)行動(dòng)態(tài)分配。嵌入式應(yīng)用程序在時(shí)間和內(nèi)存資源方面非常有限。對(duì)于一些實(shí)時(shí)的嵌入系統(tǒng),它們無(wú)法承受垃圾收集器的非確定性調(diào)用。如果因?yàn)閮?nèi)存不足而不能使用動(dòng)態(tài)分配,那么擁有其他內(nèi)存管理機(jī)制就顯得尤為重要,比如將數(shù)據(jù)放在自定義地址中,就像C語(yǔ)言的指針?biāo)试S的那樣。那些嚴(yán)重依賴動(dòng)態(tài)分配和垃圾回收的語(yǔ)言不適用于資源緊張的系統(tǒng)。
Code Size
C語(yǔ)言有一個(gè)非常小的運(yùn)行時(shí),其代碼的內(nèi)存占用要小于其它語(yǔ)言。例如與C++相比,一個(gè)由C語(yǔ)言生成的二進(jìn)制文件,其體積大約是由類似的C++代碼生成的二進(jìn)制文件的一半。造成這種情況的主要原因之一是異常支持。
異常(Exceptions )機(jī)制是C++比C語(yǔ)言多出來(lái)的一個(gè)不錯(cuò)功能,如果異常不被觸發(fā)和巧妙的實(shí)現(xiàn),他們實(shí)際上是沒有執(zhí)行時(shí)間的開銷,但代價(jià)便是增加代碼體積。
下面讓我們以C++代碼為例:
// Class A declaration. Methods defined somewhere else;
class A
{
public:
A(); // Constructor
~A(); // Destructor (called when the object goes out of scope or is deleted)
void myMethod(); // Just a method
};
// Class B declaration. Methods defined somewhere else;
class B
{
public:
B(); // Constructor
~B(); // Destructor
void myMethod(); // Just a method
};
// Class C declaration. Methods defined somewhere else;
class C
{
public:
C(); // Constructor
~C(); // Destructor
void myMethod(); // Just a method
};
void myFunction()
{
A a; // Constructor a.A() called. (Checkpoint 1)
{
B b; // Constructor b.B() called. (Checkpoint 2)
b.myMethod(); // (Checkpoint 3)
} // b.~B() destructor called. (Checkpoint 4)
{
C c; // Constructor c.C() called. (Checkpoint 5)
c.myMethod(); // (Checkpoint 6)
} // c.~C() destructor called. (Checkpoint 7)
a.myMethod(); // (Checkpoint 8)
} // a.~A() destructor called. (Checkpoint 9)
該段代碼中的A類、B類和C類中的方法都被定義在了外部(例如在其它文件中)。因此,編譯器無(wú)法對(duì)它們進(jìn)行解析,也不知道是否會(huì)拋出異常。所以程序必須準(zhǔn)備處理從它們的任何構(gòu)造函數(shù)、析構(gòu)函數(shù)或其他方法調(diào)用中拋出的異常。解構(gòu)器不應(yīng)該拋出(做法非常糟糕),但用戶還是可以拋出,或者他們可以通過(guò)調(diào)用一些拋出異常的函數(shù)或方法(顯式或隱式)間接地拋出。
如果myFunction中的任何調(diào)用拋出了異常,堆棧解開機(jī)制必須能夠調(diào)用所有已經(jīng)構(gòu)建的對(duì)象的析構(gòu)器。堆棧解開機(jī)制的一個(gè)實(shí)現(xiàn)將使用這個(gè)函數(shù)的最后一次調(diào)用的返回地址來(lái)驗(yàn)證觸發(fā)異常的調(diào)用的 "檢查點(diǎn)編號(hào)"(這是簡(jiǎn)單的解釋)。它是通過(guò)利用一個(gè)輔助的自動(dòng)生成的函數(shù)(一種查找表)來(lái)實(shí)現(xiàn)的,當(dāng)該函數(shù)的主體拋出異常時(shí),該函數(shù)將被用于堆棧解繞,這將與此類似。
如果myFunction函數(shù)的任何一個(gè)調(diào)用拋出異常,C++的棧展開(stack unwinding)機(jī)制必須能夠調(diào)用所有已構(gòu)建對(duì)象的析構(gòu)器。棧展開機(jī)制的一個(gè)實(shí)現(xiàn)是將使用這個(gè)函數(shù)的最后一次調(diào)用的返回地址來(lái)驗(yàn)證觸發(fā)異常調(diào)用的 "檢查點(diǎn)編號(hào)"(這是簡(jiǎn)單的解釋)。它是通過(guò)利用一個(gè)輔助的自動(dòng)生成函數(shù)(一種查找表)來(lái)實(shí)現(xiàn),在該函數(shù)的主體拋出異常時(shí),該函數(shù)將被用于堆棧解繞,與下面這段代碼類似:
// Possible autogenerated function
void autogeneratedStackUnwindingFor_myFunction(int checkpoint)
{
switch (checkpoint)
{
// case 1 and 9: do nothing;
case 3: b.~B(); goto destroyA; // jumps to location of destroyA label
case 6: c.~C(); // also goes to destroyA as that is the next line
destroyA: // label
case 2: case 4: case 5: case 7: case 8: a.~A();
}
}
如果從case 1和9拋出異常,則沒有對(duì)象需要銷毀。對(duì)于case 3,則b和a必須被銷毀。對(duì)于case 6,c和a必須被銷毀。在所有情況下,銷毀順序必須得到尊重。對(duì)于檢查點(diǎn)2、4、5、7和8,只有對(duì)象a需要被銷毀。
這個(gè)輔助函數(shù)增加了代碼的體積。這是C++添加到C語(yǔ)言中的空間開銷的一部分。許多嵌入式應(yīng)用無(wú)法負(fù)擔(dān)這種額外的空間。因此,用于嵌入式系統(tǒng)的C++編譯器通常有一個(gè)禁用異常的標(biāo)志。在C++中禁用異常是不自由的,因?yàn)闃?biāo)準(zhǔn)模板庫(kù)嚴(yán)重依賴異常來(lái)告知錯(cuò)誤。使用這種修改過(guò)的方案,沒有異常,需要對(duì)C++開發(fā)人員進(jìn)行更多的培訓(xùn),以檢測(cè)可能的問(wèn)題或發(fā)現(xiàn)錯(cuò)誤。
C++的一個(gè)原則就是“開發(fā)者無(wú)需為不使用的東西付費(fèi)”。對(duì)于其他語(yǔ)言來(lái)說(shuō),二進(jìn)制體積的增加會(huì)變得非常糟糕,通過(guò)其它功能來(lái)增加額外開銷,雖然這些功能有用,但嵌入式系統(tǒng)卻負(fù)擔(dān)不起。雖然C語(yǔ)言不會(huì)給你提供這些額外功能,但他可以比其它語(yǔ)言擁有更緊湊的代碼足跡(code footprint ),占用更小的磁盤空間。
為什么要學(xué)習(xí)C語(yǔ)言
C語(yǔ)言并不難學(xué),作為一門老牌編程語(yǔ)言,有關(guān)它的教程跟學(xué)習(xí)資料非常多,那么學(xué)習(xí)C語(yǔ)言有哪些好處呢?
C語(yǔ)言是開發(fā)人員的通用語(yǔ)言,網(wǎng)上或者圖書里面的不少算法都是基于C語(yǔ)言實(shí)現(xiàn),這也為實(shí)現(xiàn)提供了最大的可移植性,開發(fā)者也會(huì)從中受益。
Understand the machine(用C語(yǔ)言思考)
當(dāng)我們與同事討論代碼的某些部分或其他語(yǔ)言的某些特征時(shí),我們最終會(huì) "用C語(yǔ)言說(shuō)話":"這部分是向?qū)ο髠鬟f一個(gè) "指針 "還是復(fù)制整個(gè)對(duì)象?這里會(huì)不會(huì)發(fā)生任何 "轉(zhuǎn)換"?等等。
在分析高級(jí)語(yǔ)言的一部分代碼的行為時(shí),我們很少討論(或思考)一部分代碼正在執(zhí)行的匯編指令。相反,在討論機(jī)器在做什么時(shí),我們可以用C語(yǔ)言描述(或想)得很清楚。
在許多有趣的C語(yǔ)言項(xiàng)目上工作
從大型數(shù)據(jù)庫(kù)服務(wù)器或操作系統(tǒng)內(nèi)核甚至是為了滿足個(gè)人樂(lè)趣而制作的小型家用嵌入式應(yīng)用,你都可以用C語(yǔ)言實(shí)現(xiàn),并且還可以在網(wǎng)上找到相關(guān)Demo。Daniel呼吁大家,不要停止自己喜歡做的事情,比如學(xué)習(xí)C語(yǔ)言,它古老但小巧,并且是一門經(jīng)過(guò)時(shí)間驗(yàn)證的編程語(yǔ)言。
當(dāng)下許多編程語(yǔ)言在其預(yù)設(shè)的用途上都要優(yōu)于C語(yǔ)言,但這并不意味著就能擊敗C,當(dāng)考慮性能優(yōu)先的時(shí)候,C依然是王者。世界正運(yùn)行在C語(yǔ)言驅(qū)動(dòng)的設(shè)備上,無(wú)論你是否意識(shí)到,你使用的諸多設(shè)備的的確確都用到了C語(yǔ)言。






