我眼中的“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();

Enter:12(Enter)

結果:a = 12、cには入力値がありません

getcharもバッファーされた入力であり、 '\ n'はまだバッファー内にありますが、空になっているので、cをもう一度入力します。

fflushを使用して入力ストリームをリダイレクトすることはできません。

fflush(stdin)は標準入力バッファーをフラッシュし、入力バッファー内容を破棄します
fflush(stdout)は標準出力バッファーをフラッシュし、出力バッファーの内容を標準出力デバイスに出力します

fflush()の機能は次のとおりです。括弧内に開いているファイルへのポインターある場合、出力バッファーの内容はポインターが指すファイルに書き込まれます。それ以外の場合、出力バッファーはクリアされます。

stdoutは、システムによって定義された標準出力ファイルポインターでデフォルトはscreenを参照しますこれは、バッファーの内容を画面に書き込むことを意味します。しかし、コードからは、バッファーに何が含まれるかを確認できないため、実際には何の影響もありません。

 

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()を使用します。



おすすめ

転載: blog.csdn.net/junzhu_beautifulpig/article/details/50326605