網站首頁 編程語言 正文
printf緩沖區問題
以下內容在Linux測試,Window中進行試驗時現象可能會有不同。
一.引入
對于printf輸出函數具有緩沖區,是在使用sleep函數測試時發現的。
首先把測試問題復述一下:
簡單寫一個hello world的程序
#include <stdio.h>
int main()
{
printf("hello world\n");
sleep(5); //延遲5秒
printf("hello friend\n");
return 0;
}
輸出結果:
hello world 和hello friend的輸出中間間隔了5秒
當我們修改一下代碼后:將hello world后的\n換行符刪掉后
#include <stdio.h>
int main()
{
printf("hello world");
sleep(5); //延遲5秒
printf("hello friend\n");
return 0;
}
輸出結果:
這個輸出結果是: 光標先閃爍5s然后彈出hello worldhello friend
這里我們發現就會發現:當我們刪除字符‘\n’,函數sleep不再是語句間延遲,而是變成延遲整個程序。
這里出現的結果就很詫異 原來就一直沒注意過也沒有想過會存在這個問題 ,下面就深入理解一下printf。
二.深入理解printf
printf是一個行緩沖函數,并不會直接將數據輸出到屏幕,而是先放到緩沖區中,滿足一定的條件后,才會將緩沖區內容輸出。
設置緩沖區是為提高IO速度,減少CUP等待IO而浪費CPU資源。
如下5個條件可以刷新緩沖區:
- 緩沖區寫滿
- 寫入的字符中有‘\n’ , ‘\r’
- 調用fflush手動刷新緩沖區
- 調用scanf要從緩沖區中讀取數據時,也會將緩沖區內的數據刷新
- 程序結束時
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 Number\n",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 world\n");//
sleep(5); //延遲5秒
printf("hello friend\n");
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);
}
運行結果:
原文鏈接:https://blog.csdn.net/weixin_56935264/article/details/124760432
相關推薦
- 2022-06-22 Android開發保存QQ密碼功能_Android
- 2022-05-28 Entity?Framework?Core種子數據Data-Seeding_實用技巧
- 2022-05-12 小程序 onLaunch 與 onLoad 異步問題的解決方案
- 2022-05-22 asp.net?Core中同名服務注冊的實現代碼_實用技巧
- 2023-01-28 C#實現自定義單選和復選按鈕樣式_C#教程
- 2022-06-01 詳解Pandas中stack()和unstack()的使用技巧_python
- 2022-04-23 css3新特性transition初體驗
- 2022-10-17 Kotlin編程條件控制示例詳解_Android
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支