欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言中的getchar()使用詳解

 更新時(shí)間:2022年01月16日 09:52:22   作者:lin飛子  
大家好,本篇文章主要講的是C語言中的getchar()使用詳解,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下

前言

近期我在重新學(xué)習(xí)C語言時(shí)候,我發(fā)現(xiàn)了一個(gè)嚴(yán)重的問題,getchar我居然不會(huì)用了....也不是說不會(huì)用,我發(fā)現(xiàn)了一個(gè)非常讓我困惑想不明白的問題??赡芪以诘谝淮谓佑|C語言時(shí)候,就沒有把這個(gè)概念弄清楚吧,以至于現(xiàn)在會(huì)不明白。

getchar困惑的點(diǎn)

我利用getchar函數(shù)輸入了一串字符ABCD,然后把這串字符給到ch,然后緊接著我打印這個(gè)ch,然后我得到了一個(gè)字符A,看到這里大家沒有感覺有什么問題對(duì)吧,當(dāng)然沒有問題,因?yàn)間etchar只會(huì)讀一個(gè)字符,自然就只讀到了A,然后打印時(shí)候也自然而然就只打印了這個(gè)A出來。

好的我們接著往下看

看到這個(gè)我不知道大家有沒有想到一個(gè)問題,反正我當(dāng)時(shí)就是因?yàn)檫@個(gè)問題所困惑很久的。

首先通過第一個(gè)例子,我們知道了,getchar是只會(huì)讀取一個(gè)字符

可是這個(gè)例子呢,我輸入了一串字符ABCDE,按理說他也只是讀取到一個(gè)字符,那就是這串字符中的第一個(gè)字符A,然后讀取到了之后把它給了變量ch, 然后來判斷這個(gè)ch等不等于EOF。

EOF是文件結(jié)束標(biāo)志,在鍵盤上也就是ctrl+z 大家可以自己打印一下然后對(duì)照ASCII碼看一下

很顯然,當(dāng)前這個(gè)里面根本就沒有ctrl+z,所以條件為真,然后執(zhí)行打印語句。

根據(jù)上面我們那段分析,然后應(yīng)該打印一個(gè)字符A對(duì)嗎,疑惑的事情發(fā)生了,它打印了ABCDE?。。∈堑?,完完整整打印出來了。

可能大家經(jīng)常見到這個(gè)類似程序,然后習(xí)以為常了,都覺得是應(yīng)該完完整整打印出來

好的,講到這里大家是不是就覺得很困惑了,為什么會(huì)這樣呢?

那我現(xiàn)在就好好給大家講一下了,原來這里面還涉及到了一個(gè)概念

緩沖區(qū)

緩沖區(qū)又稱為緩存,它是內(nèi)存空間的一部分。也就是說,在內(nèi)存空間中預(yù)留了一定的存儲(chǔ)空間,這些存儲(chǔ)空間用來緩沖輸入或輸出的數(shù)據(jù),這部分預(yù)留的空間就叫做緩沖區(qū)。

那么這個(gè)和我們的getchar又有什么聯(lián)系呢?

當(dāng)然有聯(lián)系,當(dāng)我們調(diào)用了getchar函數(shù)時(shí)候,這個(gè)函數(shù)內(nèi)部其實(shí)是這樣做的:

他此時(shí)會(huì)先從緩存區(qū)中讀一遍,此時(shí)讀完之后發(fā)現(xiàn),緩存區(qū)中沒有數(shù)據(jù),他就會(huì)等待外部輸入,光標(biāo)此時(shí)就會(huì)一閃一閃的~ 

當(dāng)我們外部輸入了字符之后,然后我們就會(huì)敲回車結(jié)束,這時(shí)候我們輸入的字符其實(shí)就直接全部存在了緩存區(qū)中。

假設(shè)我此時(shí)輸入了字符ABCD,然后回車結(jié)束,然后此時(shí)緩存區(qū)中就有了ABCD\n

注意,有意思的事情來了,還有\(zhòng)n ???哈哈哈哈接著往下看

緩沖區(qū)帶來的問題

大家仔細(xì)看一下有沒有發(fā)現(xiàn),為什么我getchar沒有輸入字符呢 ?

其實(shí)不是我沒有輸入字符,只是在我輸入完scanf的字符之后,回車結(jié)束這個(gè)scanf的輸入,然后奇怪的事情發(fā)生了,程序就直接結(jié)束了,是的,跳過了getchar輸入字符這個(gè)過程。

大家有沒有覺得奇怪?

這就是我剛才上面給大家提到的 \n

是這樣的,當(dāng)我此時(shí)調(diào)用了scanf函數(shù)之后,我外部輸入了 ABCD,然后輸入完ABCD之后呢我要結(jié)束輸入,然后我們就會(huì)去敲回車,注意??!這個(gè)回車其實(shí)也是一個(gè)字符,然后他也會(huì)連同我前面輸入的ABCD一起放到緩存區(qū),也就是說此時(shí)緩存區(qū)中就有了ABCD\n 

我們做一個(gè)小小的測(cè)試就知道了

看到這個(gè)打印的結(jié)果,大家明白了吧

getchar工作原理

原來調(diào)用getchar函數(shù)的時(shí)候,它其實(shí)是直接從緩存區(qū)中讀,如果緩存區(qū)中有數(shù)據(jù),他就會(huì)直接拿走第一個(gè),然后他的使命也就結(jié)束了。其實(shí)這里呢就是上面scanf在緩存區(qū)中拿走了ABCD,然后還剩下一個(gè) 10,這個(gè)10其實(shí)是\n ,是它在ASCII碼中的表示。于是這個(gè)剩下的\n就在緩存區(qū)中存下去了,然后他此時(shí)遇到了getchar函數(shù),然后getchar在緩存區(qū)中讀,發(fā)現(xiàn):誒,還剩一個(gè)\n,那么我就直接拿走,然后他的使命也就便結(jié)束了,所以就出現(xiàn)了不會(huì)等待我們外部輸入的那種情況了。

那么我們可以解決這個(gè)問題嗎?

解決緩沖區(qū)帶來的問題之清空緩存區(qū)

明白了緩沖區(qū)和getchar的聯(lián)系之后,其實(shí)我們想解決就很好辦了

我們只需要在getchar讀取之前在插入一個(gè)getchar函數(shù),也就是說讓他在下一次真正getchar讀取之前,我們先再用一個(gè)getchar函數(shù)讀一下那個(gè)緩存區(qū)剩下的\n,這樣下一次我們真正的getchar讀取時(shí)候,緩存區(qū)就空了。

好了getchar的工作原理我們徹底明白了,那么我們?cè)诨氐阶畛醯哪莻€(gè)疑惑上面。 

解決最初的困惑

第一次循環(huán):首先緩存區(qū)為空,光標(biāo)閃爍,然后等待我的輸入

我輸入了一個(gè)字符A,然后我繼續(xù)輸入了回車結(jié)束,那么我此時(shí)其實(shí)輸入了兩個(gè)字符,一個(gè)字符A,一個(gè)字符 \n,此時(shí)他們都被存放在了緩存區(qū)。然后緩存區(qū)有了數(shù)據(jù)之后,光標(biāo)此時(shí)不在閃爍,getchar函數(shù)便開始直接讀取,然后在這一次循環(huán)中,getchar函數(shù)讀取到了一個(gè)字符A,然后將它給到ch,然后條件表達(dá)式為真(不等于ctrl+z),所以執(zhí)行打印ch,然后打印出了一個(gè)字符A。

第二次循環(huán):這時(shí)候緩存區(qū)還殘留了一個(gè)\n,光標(biāo)不閃爍,getchar也不會(huì)等待外部輸入

那么此時(shí)getchar直接讀取到這個(gè)緩存區(qū)中的\n,繼續(xù)給到ch,然后表達(dá)式還是為真,所以繼續(xù)打印這個(gè)ch,此時(shí)因?yàn)閏h已經(jīng)是被換掉了\n,所以打印換行,光標(biāo)位置發(fā)生改變。

第三次循環(huán):緩存區(qū)為空,getchar讀取不到數(shù)據(jù),光標(biāo)閃爍,getchar等待外部輸入數(shù)據(jù)。

至此我們?cè)诮又驴?/p>

 第一次循環(huán):緩存區(qū)為空,getchar讀取不到緩存區(qū)的數(shù)據(jù),于是光標(biāo)閃爍,getchar等待外部輸入數(shù)據(jù)。

此時(shí)我輸入了一串ABC,然后回車結(jié)束輸入。此時(shí)緩存區(qū)中便有了字符ABCD\n,然后getchar讀取第一個(gè)字符A,然后將它給到ch,然后條件表達(dá)式為真,打印了ch,于是第一個(gè)A就出來了。

第二次循環(huán):緩存區(qū)還剩余BC\n,getchar直接讀取

此時(shí)getchar讀取到字符B,然后給到ch,條件表達(dá)式為真,繼續(xù)打印ch,此時(shí)便得到了AB。

第三次循環(huán):緩存區(qū)還剩余C\n,getchar直接讀取

然后還是一樣getchar讀取到C,然后給到ch,之后表達(dá)式為真,打印出來了ch,然后經(jīng)過這一次循環(huán)就得到了ABC

第四次循環(huán):緩存區(qū)還剩余一個(gè)\n,最后打印這個(gè)\n,于是光標(biāo)下一行。

最終結(jié)果就得到了ABC

然后我再次輸入 ctrl+Z

于是緩存區(qū)存在了ctrl+z(EOF),然后getchar去讀取,然后給到ch,然后表達(dá)式判斷,條件為假,ch==EOF,所以循環(huán)跳出,程序結(jié)束。

總結(jié)

getchar函數(shù)是直接從緩存區(qū)中讀取數(shù)據(jù),如果緩存區(qū)中有數(shù)據(jù),則直接讀取第一個(gè)數(shù)據(jù),如果沒有數(shù)據(jù),那么就光標(biāo)閃爍,等待外部輸入數(shù)據(jù)。

要非常注意的是,我們其他地方輸入的回車也會(huì)被存在緩存區(qū)當(dāng)成一個(gè)字符,然后后面getchar也會(huì)將其直接讀出,在這個(gè)地方很容易出錯(cuò)!!

到此這篇關(guān)于C語言中的getchar()使用詳解的文章就介紹到這了,更多相關(guān)C語言getchar()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言動(dòng)態(tài)內(nèi)存分配圖文講解

    C語言動(dòng)態(tài)內(nèi)存分配圖文講解

    給數(shù)組分配多大的空間?你是否和初學(xué)C時(shí)的我一樣,有過這樣的疑問。這一期就來聊一聊動(dòng)態(tài)內(nèi)存的分配,讀完這篇文章,你可能對(duì)內(nèi)存的分配有一個(gè)更好的理解
    2023-01-01
  • C語言 坐標(biāo)移動(dòng)詳解及實(shí)例代碼

    C語言 坐標(biāo)移動(dòng)詳解及實(shí)例代碼

    這篇文章主要介紹了C語言 坐標(biāo)移動(dòng)詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • C++無鎖數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)示例詳解

    C++無鎖數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)示例詳解

    這篇文章主要為大家介紹了C++無鎖數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • C語言的動(dòng)態(tài)內(nèi)存分配及動(dòng)態(tài)內(nèi)存分配函數(shù)詳解

    C語言的動(dòng)態(tài)內(nèi)存分配及動(dòng)態(tài)內(nèi)存分配函數(shù)詳解

    這篇文章主要為大家詳細(xì)介紹了C語言的動(dòng)態(tài)內(nèi)存分配及動(dòng)態(tài)內(nèi)存分配函數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C語言實(shí)現(xiàn)影院管理系統(tǒng)程序設(shè)計(jì)

    C語言實(shí)現(xiàn)影院管理系統(tǒng)程序設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)影院管理系統(tǒng)程序設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 基于C語言實(shí)現(xiàn)三子棋游戲的示例代碼

    基于C語言實(shí)現(xiàn)三子棋游戲的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C語言數(shù)組實(shí)現(xiàn)簡(jiǎn)單的三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • C語言實(shí)現(xiàn)漢諾塔(圖文詳解)

    C語言實(shí)現(xiàn)漢諾塔(圖文詳解)

    個(gè)人覺得漢諾塔這個(gè)遞歸算法比電子老鼠的難了一些,不過一旦理解了也還是可以的,其實(shí)網(wǎng)上也有很多代碼,可以直接參考。記得大一開始時(shí)就做過漢諾塔的習(xí)題,但是那時(shí)代碼寫得很長(zhǎng)很長(zhǎng),也是不理解遞歸的結(jié)果。今天重新來實(shí)現(xiàn)一下
    2021-08-08
  • c語言讀取csv文件和c++讀取csv文件示例分享

    c語言讀取csv文件和c++讀取csv文件示例分享

    這篇文章主要介紹了c語言讀取csv文件和c++讀取csv文件示例,需要的朋友可以參考下
    2014-03-03
  • VC MFC非模態(tài)對(duì)話框的實(shí)現(xiàn)方法

    VC MFC非模態(tài)對(duì)話框的實(shí)現(xiàn)方法

    這篇文章主要介紹了VC MFC非模態(tài)對(duì)話框的實(shí)現(xiàn)方法,有助于讀者加深對(duì)于模態(tài)對(duì)話框與非模態(tài)對(duì)話框的理解與運(yùn)用,需要的朋友可以參考下
    2014-07-07
  • C++萬能庫頭文件在vs中的安裝步驟(圖文)

    C++萬能庫頭文件在vs中的安裝步驟(圖文)

    這篇文章主要介紹了C++萬能庫頭文件在vs中的安裝步驟(圖文),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02

最新評(píng)論