一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - GetChar緩存機制深入剖析

GetChar緩存機制深入剖析

2020-12-26 16:05C語言教程網 C/C++

以下是對GetChar緩存機制進行了詳細的介紹,需要的朋友可以過來參考下

與緩存區相關最常見的操作就是字符的輸入與輸出操作getchar,getc,getch,getche,gets系列函數。

第一個例子(與getchar有關):

復制代碼 代碼如下:

#include<stdio.h> 
int main() 

    int ch; 
    ch=getchar(); 
    ch=getchar(); 
    printf("%d\n",ch); 
    return 0; 


代碼如上,當輸入一個字符按下回車后程序沒有等待你二次輸入就結束了,而且無論輸入什么運行結果均是10,是不是很奇怪(反正我第一次遇到時感覺是很奇怪),更奇怪的是當你一次性輸入多個字符如abcd結果又正確的打印出了98,為什么呢?這就是緩沖區的原因。

 

解釋如下:getchar定義在stdio.h文件中,我們在stdio.h中可以找到其相關的定義:

復制代碼 代碼如下:

#define getchar()         getc(stdin)//即getchar等同于調用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結構類型的,查看stdio.h中可以看到FILE結構體定義如下:

復制代碼 代碼如下:


struct _iobuf { 
        char *_ptr; 
        int   _cnt; 
        char *_base; 
        int   _flag; 
        int   _file; 
        int   _charbuf; 
        int   _bufsiz; 
        char *_tmpfname; 
        }; 

 

 


從FILE結構中我們可以得到了上面getc宏定義中使用的_cnt,_ptr成員,但這些都是次要的,我們應該不難發現有這樣幾個成員_bufsize,_base分別對應的是緩沖區大小,緩沖區基地址,從這里得到一個顯而意見的結論就是getchar函數使用了緩沖機制。(_cnt對應的是緩沖區的輸入的字節數目,_ptr對應的是讀指針的位置)

 

getc宏定義詳解

復制代碼 代碼如下:

--(stdin)->_cnt>=0 


此句判斷是否緩沖區內有數據,有的話就減一(表示又讀了一個),并讀取數據return 0xff&*(stdin)->ptr++,讀完成后,將讀指針向前移一個位置【重要】

 

好了,講了這么多都是鋪墊,現在回到正題為什么會出現上述結果:)

出現上述結果追根結底還是由于getchar函數使用了緩沖(看了上面的,我想大家也知道了,確實使用了緩沖),當輸入一個字符按下回車后程序沒有等待你二次輸入就結束了,而且無論輸入什么運行結果均是10,這是因為當用戶輸入了一個字符后,并按下回車后,緩沖中會存入用戶輸入的字符以及換行鍵的ASCII碼(10 ~)【略去的回車的ASCII碼13,可能是為了跨平臺,在Linux下,回車后就是換行10,Windows下回車是先回車回到首行,再換行,即13 10】(執行第一次getchar實際上是執行getc的else語句,填充緩存區后_cnt=2,_prt指向0位置,執行完后_cnt=1,_prt指向1位置),第二次執行getchar時,調用getc不會再執行else語句,執行的是if語句,故第二次不再等待用戶輸入了,直接執行,執行后cnt=0,prt指向位置2,并返回ptr指向位置1時的結果,即10,由于10為換行鍵,當執行遇到此時,會在執行完后清空緩存,ptr重新指向了位置0,cnt=0。

當輸入abc的時候分析一樣,只不過掃行了第二個getchar后,cnt=2,ptr指向了位置2。

延伸 · 閱讀

精彩推薦
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
主站蜘蛛池模板: 日韩视频第二页 | 精品视频一区二区三区 | 97色资源| 91综合精品网站久久 | 2022av小四郎的最新地址 | 99热久久国产精品这里 | 亚洲AV蜜桃永久无码精品红樱桃 | 加勒比一本大道香蕉在线视频 | 91视频完整版| 91香蕉视频在线播放 | 美女的隐私无遮挡的网页 | 精品91自产拍在线观看99re | 欧美三级小视频 | 娇妻终于接受了3p的调教 | 女同色图 | 草草视频在线免费观看 | 日本道色综合久久影院 | 国产精品久久久久一区二区三区 | 欧美美女被爆操 | 成人aaaa | 日本性爱 | 亚洲AV综合99一二三四区 | 日韩欧美综合在线二区三区 | 日韩高清在线高清免费 | 国产91一区二区在线播放不卡 | www一区二区| 涩涩屋视频在线观看 | 明星ai人脸替换脸忘忧草 | 久久久久久久久人体 | 办公室恋情在线观看 | 成人精品免费网站 | 欧美日韩亚洲国内综合网香蕉 | 欧美亚洲国产成人不卡 | 亚洲一区二区精品推荐 | 特黄特a级特别特级特毛片 特黄a级三级三级野战 | 古装一级毛片 | 91精品国产综合久久 | 男人吃奶动态图 | 糖心在线观看 | 99爱免费视频 | 欧美亚洲国产精品久久第一页 |