1. 程式人生 > 其它 >C語言緩衝區(快取)詳解

C語言緩衝區(快取)詳解

1.概念
緩衝區又稱為快取,它是記憶體空間的一部分。也就是說,在記憶體空間中預留了一定的儲存空間,這些儲存空間用來緩衝輸入或輸出的資料,這部分預留的空間就叫做緩衝區。


緩衝區根據其對應的是輸入裝置還是輸出裝置,分為輸入緩衝區和輸出緩衝區。 
2.為什麼要引入緩衝區
比如我們從磁盤裡取資訊,我們先把讀出的資料放在緩衝區,計算機再直接從緩衝區中取資料,等緩衝區的資料取完後再去磁碟中讀取,這樣就可以減少磁碟的讀寫次數,再加上計算機對緩衝區的操作大大快於對磁碟的操作,故應用緩衝區可大大提高計算機的執行速度。

又比如,我們使用印表機列印文件,由於印表機的列印速度相對較慢,我們先把文件輸出到印表機相應的緩衝區,印表機再自行逐步列印,這時我們的CPU可以處理別的事情。

現在您基本明白了吧,緩衝區就是一塊記憶體區,它用在輸入輸出裝置和CPU之間,用來快取資料。它使得低速的輸入輸出裝置和高速的CPU能夠協調工作,避免低速的輸入輸出裝置佔用CPU,解放出CPU,使其能夠高效率工作。 
緩衝區的型別
緩衝區 分為三種類型:全緩衝、行緩衝和不帶緩衝。

1) 全緩衝
在這種情況下,當填滿標準I/O快取後才進行實際I/O操作。全緩衝的典型代表是對磁碟檔案的讀寫。

2) 行緩衝
在這種情況下,當在輸入和輸出中遇到換行符時,執行真正的I/O操作。這時,我們輸入的字元先存放在緩衝區,等按下回車鍵換行時才進行實際的I/O操作。典型代表是標準輸入(stdin)和標準輸出(stdout)。

3) 不帶緩衝
也就是不進行緩衝,標準出錯情況stderr是典型代表,這使得出錯資訊可以直接儘快地顯示出來。

ANSI C( C89 )要求快取具有下列特徵: 
當且僅當標準輸入和標準輸出並不涉及互動裝置時,它們才是全快取的。
標準出錯決不會是全快取的。

但是,這並沒有告訴我們如果標準輸入和輸出涉及互動作用裝置時,它們是不帶快取的還是行快取的,以及標準輸出是不帶快取的,還是行快取的。

大部分系統預設使用下列型別的快取: 
標準出錯是不帶快取的。
如果是涉及終端裝置的流,則它們是行快取的;否則是全快取的。

我們經常要用到標準輸入輸出流,而ANSI C對stdin、stdout和stderr的快取特徵沒有強行的規定,以至於不同的系統可能有不同的stdin、stdout和stderr的快取特徵。目前主要的快取特徵是:stdin和stdout是行快取;而stderr是無快取的。 
緩衝區的大小
如果我們沒有自己設定緩衝區的話,系統會預設為標準輸入輸出設定一個緩衝區,這個緩衝區的大小通常是4096個位元組的大小,這和計算機中的分頁機制有關,因為程序在計算機中分配記憶體使用的就是分頁與分段的機制,並且每個頁的大小是4096個位元組,因此通常情況下緩衝區的大小會設定為4096個位元組的大小。
緩衝區的重新整理(清空)
下列情況會引發緩衝區的重新整理:
緩衝區滿時;
行緩衝區遇到回車時;
關閉檔案;
使用特定函式重新整理緩衝區。

 

在c語言程式執行視窗,如果程式中有scanf()、getc()等型別函式時,在視窗敲入一系列的字元資料時,這些字元資料只是存入快取區並沒有寫入到scanf()、getc()等函式中所對應的 ‘ 物件 ’ 內,當緩衝區進行重新整理後才會進入這些函式對應的 ‘ 物件’內。

為什麼在視窗內敲入這一系列字元時,能從視窗看到輸入內容?

按之前印表機例子來說,將要列印的資料存入快取區,解放cpu(不用一直讀寫一個數據放入印表機中,列印時間要比cpu讀寫一次時間長的多,有了快取cpu可以一次讀一批資料到快取,印表機從快取裡面拿資料進行列印,而cpu可以去進行別的任務),而我們在視窗中打出一個字元就會顯示一個字元,這是提高互動性(就像印表機沒有快取時,cpu在記憶體中讀一個數據,印表機列印一個數據一樣),並沒有重新整理快取區所以沒有寫進scanf()、getc()所對應的物件中。