首頁 > 軟體

C++詳細講解print緩衝區的重新整理

2022-05-21 13:00:03

printf緩衝區問題

以下內容在Linux測試,Window中進行試驗時現象可能會有不同。

一.引入

對於printf輸出函數具有緩衝區,是在使用sleep函數測試時發現的。

首先把測試問題複述一下:

簡單寫一個hello world的程式

#include <stdio.h>
int main()
{
    printf("hello worldn");
    sleep(5);  //延遲5秒
     printf("hello friendn");
    return 0;
}

輸出結果:

hello world 和hello friend的輸出中間間隔了5秒

當我們修改一下程式碼後:將hello world後的n換行符刪掉後

#include <stdio.h>
int main()
{
    printf("hello world");
    sleep(5);  //延遲5秒
     printf("hello friendn");
    return 0;
}

輸出結果:

這個輸出結果是: 遊標先閃爍5s然後彈出hello worldhello friend

這裡我們發現就會發現:當我們刪除字元‘n’,函數sleep不再是語句間延遲,而是變成延遲整個程式。

這裡出現的結果就很詫異 原來就一直沒注意過也沒有想過會存在這個問題 ,下面就深入理解一下printf。

二.深入理解printf

printf是一個行緩衝函數,並不會直接將資料輸出到螢幕,而是先放到緩衝區中,滿足一定的條件後,才會將緩衝區內容輸出。

設定緩衝區是為提高IO速度,減少CUP等待IO而浪費CPU資源。

如下5個條件可以重新整理緩衝區:

  1. 緩衝區寫滿
  2. 寫入的字元中有‘n’ , ‘r’
  3. 呼叫fflush手動重新整理緩衝區
  4. 呼叫scanf要從緩衝區中讀取資料時,也會將緩衝區內的資料重新整理
  5. 程式結束時

1. 緩衝區寫滿

printf函數的緩衝區大小為1024個位元組,當超出緩衝區的大小,緩衝區會被重新整理,將會列印出結果。

緩衝區大小為1024個位元組,這個大小是這樣得出,程式碼如下:

 #include <stdio.h>
 #include <stdlib.h>
 /*argc:命令列輸入引數個數,argv:命令列引數 
  *argv為字元指標陣列,argv[i]為指向第i個命令列引數內容的指標
  */
 int main(int argc, char **argv){ 
     int i;
     char a='a';
     if(argc != 2) //命令列引數為2,否則出錯
     {
         printf("Usage:%s Numbern",argv[0]); 
         return 0;
     }
     for(i=0;i<atoi(argv[1]);i++) //atoi:字元轉化為整數
     {
         printf("%c",a);
     }
     while(1);  //讓程式一直執行
 }

執行結果:

說明:在linux下,printf緩衝區大小為1024位元組。while(1)使程式一直執行,當緩衝區未滿時,不會輸出列印。

2. 寫入的字元中有‘n’,‘r’

測試程式碼:

#include <stdio.h>
int main()
{
    printf("hello worldn");//
    sleep(5);  //延遲5秒
     printf("hello friendn");
    return 0;
}

執行結果:

3. 呼叫fflush手動重新整理緩衝區

測試程式碼:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(void)
{
    printf("hello world");
    fflush(stdout);
    sleep(5);
    exit(0);
}

執行過程及結果:

這裡在printf語句結束後,使用fflush強制重新整理緩衝區,就先列印出來內容,再執行的 sleep語句。

4. 呼叫scanf要從緩衝區中讀取資料時,也會將緩衝區內的資料重新整理

這個我們可以理解為當我們從鍵盤輸入的時候,就會將資料內的資料自動重新整理。

5. 程式結束時

測試程式碼:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(void)
{
    printf("hello world");
    sleep(5);
    exit(0);
}

執行結果:

到此這篇關於C++詳細講解print緩衝區的重新整理的文章就介紹到這了,更多相關C++ print緩衝區內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com