天天看點

我眼中的“helloworld”——緩沖區

前言:

        近日,在進行一個“私有雲”項目中,遇到了關于緩存輸出的問題,不免想到每一個學C語言的人寫的第一個程式“helloworld”。這個程式從初學者的角度來看,也就短短幾行,非常簡單,但再回首,這是一個不簡單的程式,可以說不是每一個人都會寫“helloworld”,更精确的說是寫對。真正讀懂“helloworld”是需要時間的累積的。

       今天在這裡主要介紹的是“helloworld”中的第六行printf("helloworld\r\n");

<pre name="code" class="html">#include <stdio.h>

int main(int argc,char **argv)
{
       printf("helloworld\r\n");
       return 0;
}
           

正文:

初學者可能會疏忽大意,将這句代碼敲成“printf("helloworld\n");”或是“printf("helloworld\r");”或是“printf("helloworld");”,這三種不同的寫法會有不

同的結果,感興趣的初學者可以自行嘗試一下,這裡不再示範結果。

         很多時候都會出現這樣一個情況,無論什麼語言,直接輸出無法顯示出來,從一定程度上這是因為是存在緩存中,這裡将做一個系統的總結:

(1)printf  \r  \n

printf  确實有緩沖區的問題

别人的東西:printf會把東西送到緩沖區,而如果緩沖區不重新整理到話,你便不會在螢幕上看到東西,而能導緻緩沖區重新整理到情況有這些:

1-- 強制重新整理 fflush;

fflush用于清空緩沖流,雖然一般感覺不到,但是預設printf是緩沖輸出的。fflush(stdout),使stdout清空,就會立刻輸出所有在緩沖區的内容。 fflush(stdout)這個例子可能不太明顯,但對stdin很明顯。

例:

A

int a,c;

scanf("%d",&a);

c=getchar();

輸入: 12(回車)

結果: a=12 ,c= '\n'

B

int a,c;

scanf("%d",&a);

fflush(stdin);

c=getchar();

輸入: 12(回車)

結果:a=12, c暫時未得到輸入值

再輸入c,因為getchar也是緩沖輸入,'\n'本還在緩沖區,但是被清空了。

fflush不能作用于重定向輸入流。

fflush(stdin)重新整理标準輸入緩沖區,把輸入緩沖區裡的東西丢棄

fflush(stdout)重新整理标準輸出緩沖區,把輸出緩沖區裡的東西列印到标準輸出裝置上

fflush()的作用是:如果圓括号裡是已寫打開的檔案的指針,則将輸出緩沖區的内容寫入該指針指向的檔案,否則清除輸出緩沖區。

stdout是系統定義的标準輸出檔案指針,預設情況下指螢幕,那就是把緩沖區的内容寫到螢幕上。可是從代碼中看不出緩沖區會有什麼内容,是以它實際上沒有起什麼作用。

2--放到緩沖區到内容中包含\r  \n ;

\r轉義是回車= 光标到達最左側(行首)(類似于控制螢幕或者從鍵盤的Enter鍵輸入)

\n是換行=移到下一行(控制“列印機”)

隻回車——列印的東西會覆寫同行以前的内容;隻換行——列印的東西會在下一行的先一個位置繼續。

.\r實際是回到行首。\n如果下一行已經有了一些内容的話它會在那些内容的後邊.因為一般情況下下一行是沒有資料的,很多時候\n也就成了\r\n作用一樣。

這麼看上去确實似乎有“對緩沖區強制重新整理”的功能

注:對于寫入檔案這一塊同樣有這樣的問題,這裡不再做詳細的講述,但是給出下面的參考連結:http://blog.csdn.net/a312024054/article/details/46946237

3--緩沖區已滿;

4--需要從緩沖區拿東西到時候,如執行scanf;

1)阻塞與非阻塞

A、阻塞函數:當該函數不執行完,函數所線上程就一直停止

B、阻塞調用與同步調用

同步調用:同步調用來說,很多時候目前線程還是激活的,隻是從邏輯上目前函數沒有傳回而已。

2)scanf、getchar、gets、fgets

這個連結中給了較好的例子以及比較,這裡就不再重複叙述。

http://blog.chinaunix.net/uid-24567872-id-87648.html

(2)php中的flush與ob_flush

flush:把資料從PHP的緩沖中釋放出來

ob_fflush:把不在緩沖中的或者說是被釋放出來的資料發送到浏覽器

是以當緩沖存在的時候,ob_flush()和flush()一般同時使用。

使用的順序是:先用ob_flush(),後用flush()。

繼續閱讀