網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
printf緩沖區(qū)問題
以下內(nèi)容在Linux測(cè)試,Window中進(jìn)行試驗(yàn)時(shí)現(xiàn)象可能會(huì)有不同。
一.引入
對(duì)于printf輸出函數(shù)具有緩沖區(qū),是在使用sleep函數(shù)測(cè)試時(shí)發(fā)現(xiàn)的。
首先把測(cè)試問題復(fù)述一下:
簡(jiǎn)單寫一個(gè)hello world的程序
#include <stdio.h>
int main()
{
printf("hello world\n");
sleep(5); //延遲5秒
printf("hello friend\n");
return 0;
}
輸出結(jié)果:
hello world 和hello friend的輸出中間間隔了5秒
當(dāng)我們修改一下代碼后:將hello world后的\n換行符刪掉后
#include <stdio.h>
int main()
{
printf("hello world");
sleep(5); //延遲5秒
printf("hello friend\n");
return 0;
}
輸出結(jié)果:
這個(gè)輸出結(jié)果是: 光標(biāo)先閃爍5s然后彈出hello worldhello friend
這里我們發(fā)現(xiàn)就會(huì)發(fā)現(xiàn):當(dāng)我們刪除字符‘\n’,函數(shù)sleep不再是語(yǔ)句間延遲,而是變成延遲整個(gè)程序。
這里出現(xiàn)的結(jié)果就很詫異 原來就一直沒注意過也沒有想過會(huì)存在這個(gè)問題 ,下面就深入理解一下printf。
二.深入理解printf
printf是一個(gè)行緩沖函數(shù),并不會(huì)直接將數(shù)據(jù)輸出到屏幕,而是先放到緩沖區(qū)中,滿足一定的條件后,才會(huì)將緩沖區(qū)內(nèi)容輸出。
設(shè)置緩沖區(qū)是為提高IO速度,減少CUP等待IO而浪費(fèi)CPU資源。
如下5個(gè)條件可以刷新緩沖區(qū):
- 緩沖區(qū)寫滿
- 寫入的字符中有‘\n’ , ‘\r’
- 調(diào)用fflush手動(dòng)刷新緩沖區(qū)
- 調(diào)用scanf要從緩沖區(qū)中讀取數(shù)據(jù)時(shí),也會(huì)將緩沖區(qū)內(nèi)的數(shù)據(jù)刷新
- 程序結(jié)束時(shí)
1. 緩沖區(qū)寫滿
printf函數(shù)的緩沖區(qū)大小為1024個(gè)字節(jié),當(dāng)超出緩沖區(qū)的大小,緩沖區(qū)會(huì)被刷新,將會(huì)打印出結(jié)果。
緩沖區(qū)大小為1024個(gè)字節(jié),這個(gè)大小是這樣得出,代碼如下:
#include <stdio.h>
#include <stdlib.h>
/*argc:命令行輸入?yún)?shù)個(gè)數(shù),argv:命令行參數(shù)
*argv為字符指針數(shù)組,argv[i]為指向第i個(gè)命令行參數(shù)內(nèi)容的指針
*/
int main(int argc, char **argv){
int i;
char a='a';
if(argc != 2) //命令行參數(shù)為2,否則出錯(cuò)
{
printf("Usage:%s Number\n",argv[0]);
return 0;
}
for(i=0;i<atoi(argv[1]);i++) //atoi:字符轉(zhuǎn)化為整數(shù)
{
printf("%c",a);
}
while(1); //讓程序一直運(yùn)行
}
運(yùn)行結(jié)果:
說明:在linux下,printf緩沖區(qū)大小為1024字節(jié)。while(1)使程序一直運(yùn)行,當(dāng)緩沖區(qū)未滿時(shí),不會(huì)輸出打印。
2. 寫入的字符中有‘\n’,‘\r’
測(cè)試代碼:
#include <stdio.h>
int main()
{
printf("hello world\n");//
sleep(5); //延遲5秒
printf("hello friend\n");
return 0;
}
運(yùn)行結(jié)果:
3. 調(diào)用fflush手動(dòng)刷新緩沖區(qū)
測(cè)試代碼:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(void)
{
printf("hello world");
fflush(stdout);
sleep(5);
exit(0);
}
運(yùn)行過程及結(jié)果:
這里在printf語(yǔ)句結(jié)束后,使用fflush強(qiáng)制刷新緩沖區(qū),就先打印出來內(nèi)容,再執(zhí)行的 sleep語(yǔ)句。
4. 調(diào)用scanf要從緩沖區(qū)中讀取數(shù)據(jù)時(shí),也會(huì)將緩沖區(qū)內(nèi)的數(shù)據(jù)刷新
這個(gè)我們可以理解為當(dāng)我們從鍵盤輸入的時(shí)候,就會(huì)將數(shù)據(jù)內(nèi)的數(shù)據(jù)自動(dòng)刷新。
5. 程序結(jié)束時(shí)
測(cè)試代碼:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(void)
{
printf("hello world");
sleep(5);
exit(0);
}
運(yùn)行結(jié)果:
原文鏈接:https://blog.csdn.net/weixin_56935264/article/details/124760432
相關(guān)推薦
- 2022-05-27 C++?動(dòng)態(tài)規(guī)劃算法使用分析_C 語(yǔ)言
- 2022-10-18 pandas重復(fù)行刪除操作df.drop_duplicates和df.duplicated的區(qū)別_p
- 2024-03-03 layuiAdmin側(cè)邊欄菜單刷新保持當(dāng)前頁(yè)面
- 2023-10-14 【c++】四舍五入
- 2023-01-03 flutter中的布局和響應(yīng)式app方法示例_Android
- 2022-04-22 Element UI 表格操作列按鈕顯示不全
- 2023-01-09 解決python問題?Traceback?(most?recent?call?last)_pytho
- 2022-03-14 Prefix must be in canonical form
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支