人人做人人澡人人爽欧美,国产主播一区二区,久久久精品五月天,羞羞视频在线观看免费

當(dāng)前位置:蘿卜系統(tǒng)下載站 > 技術(shù)開發(fā)教程 > 詳細(xì)頁面

C++基礎(chǔ)解惑——淺析cout

C++基礎(chǔ)解惑——淺析cout

更新時間:2022-08-17 文章作者:未知 信息來源:網(wǎng)絡(luò) 閱讀次數(shù):

#include  
using namespace std; 
int main() 

    cout << "Hello, World!" << endl; 
    return 0; 


       由于以前學(xué)過C,所以這段代碼的其它部分在我看來都還算“正常”,然而cout卻很獨特:既不是函數(shù),似乎也不是C++特別規(guī)定出來的像if,for一類有特殊語法的“語句”。由于只是初步介紹,所以那本書只是簡單的說cout是C++中的“標(biāo)準(zhǔn)輸入輸出流”對象……這于我而言實在是一個很深奧的術(shù)語。這還沒完,之后又遇見了cin……因為不知底細(xì),從此使用它們的時候都誠惶誠恐,幾欲逃回C時代那簡明的printf(),畢竟好歹我可以說:我在調(diào)用的是一個函數(shù)。那有著一長串<<、>>的玩意,究竟算怎么回事呢?我一直想把它們當(dāng)作關(guān)鍵字,可偏偏不是,而且居然是用C++語言“做”出來的,呵!但printf()用多了就開始有人好心地批判我的程序“C語言痕跡過重”…… 
       后來隨著學(xué)習(xí)的深入,總算大概明白了cout/cin/cerr/...的鬼把戲:那些東東不過是變著法兒“哄人”,其實說到底還是函數(shù)調(diào)用,不過這函數(shù)有些特殊,用的是運算符重載,確切地說(以下還是以cout為例)是重載了“<<”運算符。我們現(xiàn)在就讓它現(xiàn)出函數(shù)的本來面目,請看Hello World!的等效版本: 

#include  
using namespace std; 
int main() 

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


       編譯運行,結(jié)果與經(jīng)典版無二。上面程序應(yīng)該更容易理解了:cout是一個iostream類的對象,它有一個成員運算符函數(shù)operator<<,每次調(diào)用的時候就會向輸出設(shè)備(一般就是屏幕啦)輸出東東。嗯,這里有一個問題:為什么函數(shù)operator<<能夠接受不同類型的數(shù)據(jù),如整型、浮點型、字符串甚至指針,等等呢? 
       我想你現(xiàn)在已經(jīng)猜到了,沒錯,就是用運算符重載。運算符函數(shù)與一般函數(shù)基本無異,可以任意重載。標(biāo)準(zhǔn)庫的設(shè)計者們早已經(jīng)為我們定制了iostream::operator<<對于各種C++基本數(shù)據(jù)類型的重載版本,這才使得我們這些初學(xué)者們一上來就享受到cout << "Hello, World!" << endl;的簡潔——等等,這一行是由兩個<<將"Hello, World"與"endl"操作符連接起來,那么我們的第二版Hello, World!似乎也應(yīng)該寫成: 
cout.operator<<("Hello, World!").operator<<(endl); 
才算“強(qiáng)等效”。究竟可不可以這樣寫?向編譯器確認(rèn)一下……OK,No Problem! 

       嗯,我們已經(jīng)基本上看出了cout的實質(zhì),現(xiàn)在不妨動動手,自己來實現(xiàn)一個cout的簡化版(Lite),為了區(qū)分,我們把我們設(shè)計的cout對象命名的myout,myout對象所屬的類為MyOutstream。我們要做的就是為MyOutstream類重載一系列不同類型的operator<<運算符函數(shù),簡單起見,這里我們僅實現(xiàn)了對整型(int)與字符串型(char*)的重載。為了表示與iostream斷絕關(guān)系,我們不再用頭文件iostream,而使用古老的stdio中的printf函數(shù)進(jìn)行輸出,程序很簡單,包括完整的main函數(shù),均列如下: 

#include         // 在C和一些古老的C++中是stdio.h,新標(biāo)準(zhǔn)為了使標(biāo)準(zhǔn)庫 
                                 // 的頭文件與用戶頭文件區(qū)別開,均推薦使用不用擴(kuò)展名 
                                 // 的版本,對于原有C庫,不用擴(kuò)展名時頭文件名前面要加c 

class MyOutstream 

public: 
    const MyOutstream& operator<<(int value) const;  // 對整型變量的重載 
    const MyOutstream& operator<<(char* str) const; // 對字符串型的重載 
}; 

const MyOutstream& MyOutstream::operator<<(int value) const 

    printf("%d", value); 
    return *this;                  // 注意這個返回…… 


const MyOutstream& MyOutstream::operator<<(char* str) const 

    printf("%s", str); 
    return *this;                  // 同樣,這里也留意一下…… 


MyOutstream myout;         // 隨時隨地為我們服務(wù)的全局對象myout 

int main() 

    int a = 2003; 
    char* myStr = "Hello, World!"; 
    myout << myStr << a << "\n"; 
    return 0; 


      我們已經(jīng)的myout已經(jīng)初具形態(tài),可以為我們工作了。程序中的注釋指出兩處要我們特別注意的:即是operator<<函數(shù)執(zhí)行完畢之后,總是返回一個它本身的引用,輸出已經(jīng)完成,為何還要多此一舉? 
       還記得那個有點奇異的cout.operator<<("Hello, World!").operator<<(endl)么?它能實現(xiàn)意味著我們可以連著書寫 
cout << "Hello, World!" << endl; 
而不是  
cout << "Hello, World!"; 
cout << endl; 
     為何它可以這樣連起來寫?我們分析一下:按執(zhí)行順序,系統(tǒng)首先調(diào)用cout.operator<<("Hello, World!"),然后呢?然后cout.operator<<會返回它本身,就是說在函數(shù)的最后一行會出現(xiàn)類似于return *this這樣的語句,因此cout.operator<<("Hello, World!")的調(diào)用結(jié)果就返回了cout,接著它后面又緊跟著.operator<<(endl),這相當(dāng)于cout.operator<<(endl)——于是又會進(jìn)行下一個輸出,如果往下還有很多<<算符,調(diào)用就會一直進(jìn)行……哇噢,是不是很聰明?現(xiàn)在你明白我們的MyOutstream::operator<<最后一行的奧妙了吧! 
       再注意一下main函數(shù)中最激動人心的那一行: 
        myout << myStr << a << "\n"; 
       我們知道,最后出現(xiàn)的"\n"可以實現(xiàn)一個換行,不過我們在用C++時教程中總是有意無意地讓我們使用endl,兩者看上去似乎一樣——究竟其中有什么玄妙?查書,書上說endl是一個操縱符(manipulator),它不但實現(xiàn)了換行操作,而且還對輸出緩沖區(qū)進(jìn)行刷新。什么意思呢?原來在執(zhí)行輸出操作之后,數(shù)據(jù)并非立刻傳到輸出設(shè)備,而是先進(jìn)入一個緩沖區(qū),當(dāng)適宜的時機(jī)(如設(shè)備空閑)后再由緩沖區(qū)傳入,也可以通過操縱符flush進(jìn)行強(qiáng)制刷新: 
cout << "Hello, World! " << "Flush the screen now!!!" << flush; 
       這樣當(dāng)程序執(zhí)行到operator<<(flash)之前,有可能前面的字符串?dāng)?shù)據(jù)還在緩沖區(qū)中而不是顯示在屏幕上,但執(zhí)行operator<<(flash)之后,程序會強(qiáng)制把緩沖區(qū)的數(shù)據(jù)全部搬運到輸出設(shè)備并將其清空。而操縱符endl相當(dāng)于<< "\n" << flush的簡寫版本,它先輸出一個換行符,再實現(xiàn)緩沖區(qū)的刷新。大概這是因為一般的輸出都是以換行結(jié)尾,而結(jié)尾處又是習(xí)慣進(jìn)行刷新的時期,方便起見就把兩者結(jié)合成了endl。讀者有興趣的話,回去也可以為我們的MyOutstream實現(xiàn)一個類似的myflush和myendl操縱符,相關(guān)的用于刷新C函數(shù)是fflush。 
       不過可能在屏幕上顯示是手動刷新與否區(qū)別看來都不大。但對于文件等輸出對象就不大一樣了:過于頻繁的刷新意味著老是寫盤,會影響速度。因此通常是寫入一定的字節(jié)數(shù)后再刷新,如何操作?靠的就是這些操縱符。 
        好了,說了這么多,C++的iostream家族與C的print/scanf家庭相比究竟有何優(yōu)勢?首先是類型處理更安全、智能,想想printf中對付int、float等的"%d"、"%f"等說明符真是多余且麻煩,萬一用錯了搞不好還會死掉;其次是擴(kuò)展性更強(qiáng):我要是新定義一個復(fù)數(shù)類Complex,printf對其是無能為力,最多只能分別輸出實、虛部,而iostream使用的<<、>>操作符都是可重載的,你只要重載相關(guān)的運算符就可以了;而且流風(fēng)格的寫法也比較自然簡潔,不是么?

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統(tǒng)下載排行

網(wǎng)站地圖xml | 網(wǎng)站地圖html
主站蜘蛛池模板: 镇康县| 虎林市| 营口市| 重庆市| 锦州市| 平阳县| 常州市| 平罗县| 蒲江县| 武山县| 安化县| 岱山县| 循化| 光泽县| 广丰县| 南投市| 宜宾市| 崇义县| 新营市| 龙井市| 崇文区| 中方县| 日喀则市| 安义县| 依兰县| 如皋市| 库伦旗| 平潭县| 虞城县| 永顺县| 韶山市| 广东省| 合肥市| 开鲁县| 陇川县| 清涧县| 昭通市| 广东省| 密云县| 青浦区| 鄂伦春自治旗|