GetChar緩存機制深入剖析
與緩存區(qū)相關(guān)最常見的操作就是字符的輸入與輸出操作getchar,getc,getch,getche,gets系列函數(shù)。
第一個例子(與getchar有關(guān)):
#include<stdio.h>
int main()
{
int ch;
ch=getchar();
ch=getchar();
printf("%d\n",ch);
return 0;
}
代碼如上,當輸入一個字符按下回車后程序沒有等待你二次輸入就結(jié)束了,而且無論輸入什么運行結(jié)果均是10,是不是很奇怪(反正我第一次遇到時感覺是很奇怪),更奇怪的是當你一次性輸入多個字符如abcd結(jié)果又正確的打印出了98,為什么呢?這就是緩沖區(qū)的原因。
解釋如下:getchar定義在stdio.h文件中,我們在stdio.h中可以找到其相關(guān)的定義:
#define getchar() getc(stdin)//即getchar等同于調(diào)用getc(stdin)
我們又找到getc的定義
#define getc(_stream) (--(_stream)->_cnt >= 0 \
? 0xff & *(_stream)->_ptr++ : _filbuf(_stream))
將其展開即得:
if(--(stdin)->_cnt>=0)
return 0xff&*(stdin)->ptr++;
else
return filbuf(stdin);
代碼譯如下stdin是標準輸入流,查看MSDN與stdio.h中可以看到定義如下:
Stdio.h中:
#define stdin (&_iob[0])
跟蹤即可得:
_CRTIMP extern FILE _iob[];
從上面代碼可得_iob是FILE結(jié)構(gòu)類型的,查看stdio.h中可以看到FILE結(jié)構(gòu)體定義如下:
struct _iobuf {
char *_ptr;
int _cnt;
char *_base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char *_tmpfname;
};
從FILE結(jié)構(gòu)中我們可以得到了上面getc宏定義中使用的_cnt,_ptr成員,但這些都是次要的,我們應(yīng)該不難發(fā)現(xiàn)有這樣幾個成員_bufsize,_base分別對應(yīng)的是緩沖區(qū)大小,緩沖區(qū)基地址,從這里得到一個顯而意見的結(jié)論就是getchar函數(shù)使用了緩沖機制。(_cnt對應(yīng)的是緩沖區(qū)的輸入的字節(jié)數(shù)目,_ptr對應(yīng)的是讀指針的位置)
getc宏定義詳解
--(stdin)->_cnt>=0
此句判斷是否緩沖區(qū)內(nèi)有數(shù)據(jù),有的話就減一(表示又讀了一個),并讀取數(shù)據(jù)return 0xff&*(stdin)->ptr++,讀完成后,將讀指針向前移一個位置【重要】
好了,講了這么多都是鋪墊,現(xiàn)在回到正題為什么會出現(xiàn)上述結(jié)果:)
出現(xiàn)上述結(jié)果追根結(jié)底還是由于getchar函數(shù)使用了緩沖(看了上面的,我想大家也知道了,確實使用了緩沖),當輸入一個字符按下回車后程序沒有等待你二次輸入就結(jié)束了,而且無論輸入什么運行結(jié)果均是10,這是因為當用戶輸入了一個字符后,并按下回車后,緩沖中會存入用戶輸入的字符以及換行鍵的ASCII碼(10 ~)【略去的回車的ASCII碼13,可能是為了跨平臺,在Linux下,回車后就是換行10,Windows下回車是先回車回到首行,再換行,即13 10】(執(zhí)行第一次getchar實際上是執(zhí)行g(shù)etc的else語句,填充緩存區(qū)后_cnt=2,_prt指向0位置,執(zhí)行完后_cnt=1,_prt指向1位置),第二次執(zhí)行g(shù)etchar時,調(diào)用getc不會再執(zhí)行else語句,執(zhí)行的是if語句,故第二次不再等待用戶輸入了,直接執(zhí)行,執(zhí)行后cnt=0,prt指向位置2,并返回ptr指向位置1時的結(jié)果,即10,由于10為換行鍵,當執(zhí)行遇到此時,會在執(zhí)行完后清空緩存,ptr重新指向了位置0,cnt=0。
當輸入abc的時候分析一樣,只不過掃行了第二個getchar后,cnt=2,ptr指向了位置2。
上一篇:operator new在C++中的各種寫法總結(jié)
欄 目:C語言
下一篇:C++中Operator類型強制轉(zhuǎn)換成員函數(shù)解析
本文標題:GetChar緩存機制深入剖析
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/4167.html
您可能感興趣的文章
- 01-10Assert(斷言實現(xiàn)機制深入剖析)
- 01-10c語言中g(shù)etch,getche,getchar的區(qū)別
- 01-10淺析C++中cout的運行機制
- 01-10c++異常處理機制示例及詳細講解
- 01-10Windows消息傳遞機制詳解
- 01-10Windows的鉤子機制詳解
- 01-10C++虛函數(shù)的實現(xiàn)機制分析
- 01-10Windows程序內(nèi)部運行機制實例詳解
- 01-10C++中的RAII機制詳解
- 01-10C++中的RTTI機制詳解


閱讀排行
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對數(shù)函數(shù)的表達式 c語言中對
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實現(xiàn)頁面的局部加載
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10C#中split用法實例總結(jié)
- 04-02jquery與jsp,用jquery
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文