2009-08-10 59 views
5

我假設大多數C++編譯器都是用匯編寫的。這使得他們完全不同的語言(我可能是錯的)。這就是說,如果我要爲普通老C創建一個cout樣式函數,我該怎麼做呢? cout有一些非常令人印象深刻的功能,利用這個片段,例如:在C中創建一個cout函數?

// endl not only prints a new line but also flushes the stream 
cout << "Hello World!" << endl; 

這一點我敢肯定轉化爲在C:

printf("Hello World!\n"); 
fflush(1);     //stdout = 1 

業務的下一個訂單,該<<運營商。在C++中,這很容易(操作符重載),但我想不出在C中做到這一點的單一方法。

+2

不知道從哪裏開始就這一個...簡短的答案是,C++語言被定義爲允許這樣的語法,並且C語言不是。 - 但是你的問題可以從「如何爲C擴展語言編寫編譯器?」一直到「如何使用特殊語法的C風格宏複製自定義庫中的iostream功能?」 – 2009-08-10 04:37:46

+0

@Conspicuous編譯器:我知道你說什麼。這就是我將其標記爲假設的原因。這並不重要,我只是好奇而已。 – Kredns 2009-08-10 04:40:31

+4

大多數C++編譯器都是用C或C++編寫的 - 而不是彙編。 – 2009-08-10 04:54:48

回答

5

這是正確的,因爲C沒有運算符重載,所以不能更改<的行爲<運算符,它總是會進行一點點移位,所以沒有辦法用C++中的精確語義編寫'cout',C語言。主要編寫g ++(GNU C++編譯器) in C。

4

C實際上是C++編譯器和標準庫的一種流行的實現語言(C++本身,實際上也是 - 一種有時稱爲自託管或引導語言的概念),您可以研究一個豐富的,複雜的C++標準庫(加上擴展)here(對不起,這是gcc 3 - 找不到一個gcc 4源代碼樹就像在線瀏覽一樣容易,儘管你可以很容易地下載那些來源並在本地機器上研究它們)。我個人建議先寫一本好書,比如this one--一旦你掌握了C++ iostreams的所有晦澀的角落和裂縫,那麼源代碼將對你更有意義(如一本獎金,這本書還帶你通過本地導遊 - 堅持你的帽子!)。

8

它可能有助於思考如何在「< <」操作符語法和「運算符< <」函數語法之間進行轉換。你的C++示例等同於該位的C++代碼:

operator<< (operator<< (cout, "Hello World!"), endl); 

,你應該在這裏注意到的第一件事是,有沒有實際COUT很多聰明的。巧妙的是運算符< <函數 - 具體而言,運算符的運算符版本是將流對象(這是cout是什麼,但其他許多事物也是)作爲其第一個參數。或者,更確切地說,運算符函數的範圍將流​​對象作爲第一個參數,並將特定的事物作爲第二個參數 - 對於可以放入cout流的每種類型的對象,都有一個函數。您也可以在該語法中看到C++技巧之一;運行在流對象上的運算符總是返回它們給出的流對象,從而允許鏈接這種性質。

爲了將C++代碼放入期望C語言函數語法的連接器和系統ABI中,大多數C++編譯器都會「調整」函數名稱,以便在其中編碼它們所具有的參數類型。 (當然,「< <」不是一個有效的類C函數名稱。)因此,如果您查看生成的程序集中的這一位函數,您會發現兩個函數的名稱是彼此不同 - 他們會有後綴指示參數類型。你可以做這樣的事情手動:

operator_lshift__stream__endl(
    operator_lshift__stream__string(cout, "Hello World!"), endl); 

有你已經得到的東西,你可以用C實現

相關問題