轉載自:http://soft.chinabyte.com/database/47/12481547.shtmlhtml
下面介紹緩衝區的知識。緩存
1、什麼是緩衝區函數
緩衝區又稱爲緩存,它是內存空間的一部分。也就是說,在內存空間中預留了必定的存儲空間,這些存儲空間用來緩衝輸入或輸出的數據,這部分預留的空間就叫作緩衝區。post
緩衝區根據其對應的是輸入設備仍是輸出設備,分爲輸入緩衝區和輸出緩衝區。spa
2、爲何要引入緩衝區htm
咱們爲何要引入緩衝區呢?blog
好比咱們從磁盤裏取信息,咱們先把讀出的數據放在緩衝區,計算機再直接從緩衝區中取數據,等緩衝區的數據取完後再去磁盤中讀取,這樣就能夠減小磁盤的讀寫次數,再加上計算機對緩衝區的操做大大快於對磁盤的操做,故應用緩衝區可大大提升計算機的運行速度。內存
又好比,咱們使用打印機打印文檔,因爲打印機的打印速度相對較慢,咱們先把文檔輸出到打印機相應的緩衝區,打印機再自行逐步打印,這時咱們的CPU能夠處理別的事情。文檔
如今您基本明白了吧,緩衝區就是一塊內存區,它用在輸入輸出設備和CPU之間,用來緩存數據。它使得低速的輸入輸出設備和高速的CPU可以協調工做,避免低速的輸入輸出設備佔用CPU,解放出CPU,使其可以高效率工做。get
3、緩衝區的類型
緩衝區 分爲三種類型:全緩衝、行緩衝和不帶緩衝。
一、全緩衝
在這種狀況下,當填滿標準I/O緩存後才進行實際I/O操做。全緩衝的典型表明是對磁盤文件的讀寫。
二、行緩衝
在這種狀況下,當在輸入和輸出中遇到換行符時,執行真正的I/O操做。這時,咱們輸入的字符先存放在緩衝區,等按下回車鍵換行時才進行實際的I/O操做。典型表明是鍵盤輸入數據。
三、不帶緩衝
也就是不進行緩衝,標準出錯狀況stderr是典型表明,這使得出錯信息能夠直接儘快地顯示出來。
4、緩衝區的刷新
下列狀況會引起緩衝區的刷新:
緩衝區滿時;
執行flush語句;
執行endl語句;
關閉文件。
可見,緩衝區滿或關閉文件時都會刷新緩衝區,進行真正的I/O操做。另外,在C++中,咱們可使用flush函數來刷新緩衝區(執行I/O操做並清空緩衝區),如:
cout<<flush; p="" cout<<endl;<="" endl控制符的做用是將光標移動到輸出設備中下一行開頭處,而且清空緩衝區。="" 將顯存的內容當即輸出到顯示器上進行顯示="">
至關於
cout<<」\n」 <<flush;< p="">
5、實例演示
一、文件操做演示全緩衝
建立一個控制檯工程,輸入以下代碼:
#include using namespace std; int main() { //建立文件test.txt並打開 ofstream outfile("test.txt"); //向test.txt文件中寫入4096個字符’a’ for(int n=0;n<4096;n++) { outfile<<'a'; } //暫停,按任意鍵繼續 system("PAUSE"); //繼續向test.txt文件中寫入字符’b’,也就是說,第4097個字符是’b’ outfile<<'b'; //暫停,按任意鍵繼續 system("PAUSE"); return 0; }
上面這段代碼很容易理解,已經在代碼內部做了註釋。
編寫這段小代碼的目的是驗證WindowsXP下全緩衝的大小是4096個字節,並驗證緩衝區滿後會刷新緩衝區,執行真正的I/O操做。
編譯並執行,運行結果以下:
此時打開工程所在文件夾下的test.txt文件,您會發現該文件是空的,這說明4096個字符「a」還在緩衝區,並無真正執行I/O操做。敲一下回車鍵,窗口變爲以下:
此時再打開test.txt文件,您就會發下該文件中已經有了4096個字符「a」。這說明全緩衝區的大小是4K(4096),緩衝區滿後執行了I/O操做,而字符「b」還在緩衝區。
再次敲一下回車鍵,窗口變爲以下:
此時再打開test.txt文件,您就會發現字符「b」也在其中了。這一步驗證了文件關閉時刷新了緩衝區。
二、鍵盤操做演示行緩衝
先介紹getchar()函數。
函數原型:int getchar(void);
說明:當程序調用getchar()函數時,程序就等着用戶按鍵,用戶輸入的字符被存放在鍵盤緩衝區中,直到用戶按回車爲止(回車字符也放在緩衝區中)。當用戶鍵入回車以後,getchar()函數纔開始從鍵盤緩衝區中每次讀入一個字符。也就是說,後續的getchar()函數調用不會等待用戶按鍵,而直接讀取緩衝區中的字符,直到緩衝區中的字符讀完後,才從新等待用戶按鍵。
不知道您明白了沒有,再通俗一點講,當程序調用getchar()函數時,程序就等着用戶按鍵,並等用戶按下回車鍵返回。期間按下的字符存放在緩衝區,第一個字符做爲函數返回值。繼續調用getchar()函數,將再也不等用戶按鍵,而是返回您剛纔輸入的第2個字符;繼續調用,返回第3個字符,直到緩衝區中的字符讀完後,纔等待用戶按鍵。
若是您尚未明白,只能怨我表達能力有限,您能夠結合如下實例體會。
建立一個控制檯工程,輸入以下代碼:
#include using namespace std; int main() { char c; //第一次調用getchar()函數 //程序執行時,您能夠輸入一串字符並按下回車鍵,按下回車鍵後該函數才返回 c=getchar(); //顯示getchar()函數的返回值 cout<<c<<endl; p="" }<="" 0;="" return="" system(?pause?);="" 暫停="" }="" printf(?%c?,c);="" {="" while((c="getchar())!='\n')" 直到遇到回車符才結束="" 將每次調用getchar()函數的返回值顯示出來="" 循環屢次調用getchar()函數="">
這段小代碼也很簡單,一樣在代碼內部都有註釋。
getchar()函數的執行就是採用了行緩衝。第一次調用getchar()函數,會讓程序使用者(用戶)輸入一行字符並直至按下回車鍵 函數才返回。此時用戶輸入的字符和回車符都存放在行緩衝區。再次調用getchar()函數,會逐步輸出行緩衝區的內容。
好了,本人表達能力有限,仍是編譯運行程序,經過運行結果本身領會吧。
編譯運行程序,會提示您輸入字符,您能夠交替按下一些字符,以下:
您一直按下去,您就會發現當您按到第4094個字符時,不容許您繼續輸入字符。這說明行緩衝區的大小也是4K。
此時您按下回車鍵,返回第一個字符’a’,以下圖:
繼續敲一下回車鍵,將緩衝區的其它的字符所有輸出,以下圖:
三、標準錯誤輸出不帶緩衝
如錯誤輸出時使用:
cerr<<」錯誤,請檢查輸入的參數!」;
這條語句等效於:
fprintf(stderr, 」錯誤,請檢查輸入的參數!」);
好了,就說到這吧,祝您好運,但願能對您有所幫助