『Linux从入门到精通』第 ⑨ 期 - 第一个小程序——进度条 | 认识缓冲区

简介: 『Linux从入门到精通』第 ⑨ 期 - 第一个小程序——进度条 | 认识缓冲区

0000000000000.png

目录


认识缓冲区

缓冲区的概念

如何证明缓冲区的存在

缓冲区的作用

认识 '\n' 与 '\r'

实现进度条小程序

part1

代码实现

实现效果

part2

代码实现

实现效果

part3

代码实现

实现效果


文章导读


本章主要内容有:理解缓冲区的概念、利用缓冲区的性质实现进度条的小程序。

本章学习目标:1.巩固 make/makefile 的使用;2.练习Linux下多文件操作;3.了解缓冲区概念。


正文


认识缓冲区


缓冲区的概念


缓冲区是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。


如何证明缓冲区的存在


让我们通过一段简单的代码观察到缓冲区的存在。

#include<stdio.h>
#include<unistd.h>
int main()
{
  printf("hello world");
  //sleep函数——Linux中的一个休眠函数
  sleep(3);
  return 0;
}

按照正常的逻辑,这段代码执行的结果应该是:先打印 " hello world " ,再休眠 3 秒。但是程序当执行后,我们观察到的却是先停留了 3 秒,又打印出 " hello world " 。

21.png


(拼手速截的图,小伙伴们可以手动尝试,感受更深)


在休眠的 3 秒期间,数据 " hello world " 并没有刷新出来(指的是没有打印在屏幕上),3 秒之后才出现在屏幕上。那么在休眠的三秒期间,数据 " hello world " 一定是被保存起来了,那么保存到哪里了呢?答案就是——缓冲区。

缓冲区有自己的刷新策略。一般系统默认程序结束后将缓冲区中的内容刷新出来,也可以我们手动去刷新,例如:

#include<stdio.h>
#include<unistd.h>
int main()
{
  printf("hello world");
  //刷新缓冲区
  fflush(stdout);
  sleep(3);
  return 0;
}


缓冲区的作用


我们为什么要引入缓冲区呢?


比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。


又比如,我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情。现在您基本明白了吧,缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。


认识 '\n' 与 '\r'


'\n' 可以说是我们的老朋友了,但是你真的了解他吗?


我们电脑输入内容时,是怎么确定要在哪个位置输入内容呢?那就是看光标在哪个位置。



'\r' 的作用是——回车;'/n' 的作用是——回车+换行;


回车:光标回到本行的开头位置;


换行:光标的列坐标不变,换到下一行;


同时,它俩还有一个相同的作用——刷新缓冲区。


例如:

#include<stdio.h>
#include<unistd.h>
int main()
{
  printf("hello world\r");
  sleep(3);
  return 0;
}


有的小伙伴可能会好奇,为什么没有打印出 "hello world" 呢?原因是 "hello world" 其实已经被打印出来了,只不过 '\r' 使光标回到了本行开头,而机器从光标所在位置向后显示内容,所以说 "hello world" 是被覆盖掉了。


至于为什么会显示 [hxy@...] 这一串内容,因为这是 Linux 中默认会显示的命令行提示符,同样,它也是从光标位置开始显示。

再来看看 '\n' :

#include<stdio.h>
#include<unistd.h>
int main()
{
  printf("hello world\n");
  sleep(3);
  return 0;
}

22.png23.png

到这里,我们已经认识了缓冲区与 '\r' '\n'。根据之前的小demo,我们可以完成一个简单的进度条小程序了。


实现进度条小程序


接下来我们就用刚刚学到的东西完成一个这样的进度条;

25.png

进度条的实现分为 3 个部分:

part1:条状加载图案;

part2:数字加载进度;

part3:加载动画;


part1


part1 部分实现的思路是:


1.定义一个数组,数组大小看个人喜好,但是需要注意预留一个位置给 '/0' ;


2.循环打印数组的全部内容。每次打印完毕,向数组内添加一个字符STYLE,造成进度条慢慢变长的效果;


3.使用 '\r' ,使每次打印数组内容时都能覆盖上次打印的内容。


代码实现


#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#define SIZE 101
#define STYLE '/'                                                                                                                 
void process()
{
   char bar[SIZE];
   memset(bar,'\0',sizeof(bar));
   int i =0;
   while(i<=100)
   {
     printf("[%-100s]\r",bar);
     fflush(stdout);
     bar[i++] = STYLE;
     //每过一秒加载一次
     sleep(1);
   }
   printf("\n");
}


实现效果


27.png


part2


part2 部分较为简单,只需在上述代码中稍加改动即可。


代码实现


#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#define SIZE 101
#define STYLE '/'                                                                                                                 
void process()
{
   char bar[SIZE];
   memset(bar,'\0',sizeof(bar));
   int i =0;
   while(i<=100)
   {
     printf("[%-100s] [%d%%]\r",bar,i);
     fflush(stdout);
     bar[i++] = STYLE;
     //每过一秒加载一次
     sleep(1);
   }
   printf("\n");
}


实现效果


28.png

29.png


part3


我们采用循环打印 " | / - \ " 这四个字符来模拟加载动画的效果。

1.定义一个字符数组 char* lable = " | / - \ "

2.用 lable[i%4] 控制打印的内容(i%4的作用是,控制 i 在区间 [0,3]);


代码实现


#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#define SIZE 101
#define STYLE '/'                                                                                                                 
void process()
{
   const char* lable = "|/-\\";
   char bar[SIZE];
   memset(bar,'\0',sizeof(bar));
   int i =0;
   while(i<=100)
   {
     printf("[%-100s] [%d%%][%c]\r",bar,i,lable[i%4]);
     fflush(stdout);
     bar[i++] = STYLE;
     //每过一秒加载一次
     sleep(1);
   }
   printf("\n");
}


实现效果


31.png32.png


到此为止,一个进度条小程序的实现就完成了,小伙伴们快实现自己的进度条样式吧。


目录
相关文章
|
1天前
|
运维 关系型数据库 MySQL
day03-Linux运维-Xshell优化和Linux系统命令入门(2)
day03-Linux运维-Xshell优化和Linux系统命令入门(2)
day03-Linux运维-Xshell优化和Linux系统命令入门(2)
|
1天前
|
运维 Linux Shell
day03-Linux运维-Xshell优化和Linux系统命令入门(1)
day03-Linux运维-Xshell优化和Linux系统命令入门(1)
day03-Linux运维-Xshell优化和Linux系统命令入门(1)
|
7天前
|
小程序 Java 编译器
性能工具之JMeter 微信小程序 WebSocket 脚本入门
【5月更文挑战第12天】性能工具之JMeter 微信小程序 WebSocket 脚本入门
12 1
|
7天前
|
Linux 芯片 Ubuntu
Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯
Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯
|
7天前
|
Ubuntu Linux
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-2
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-2
|
7天前
|
Linux 芯片
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-1
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-1
|
7天前
|
Linux C语言 Ubuntu
Linux驱动入门——编写第一个驱动
Linux驱动入门——编写第一个驱动
Linux驱动入门——编写第一个驱动
|
7天前
|
缓存 安全 Linux
Linux入门基本指令(2)
Linux入门基本指令(2)
13 0
|
7天前
|
存储 编解码 小程序
抖音小程序开发中遇见的坑点
在抖音小程序开发中,需注意10大坑点:遵守小程序限制与规范;解决兼容性问题;优化数据加载速度;适应分享功能限制;处理视频播放挑战;优化图片加载显示;管理资源文件;提升用户体验;考虑安全性;及时更新维护。通过测试、优化和遵循官方文档,可克服这些问题,打造优质小程序。
|
7天前
|
小程序 前端开发 API
小程序全栈开发中的多端适配与响应式布局
【4月更文挑战第12天】本文探讨了小程序全栈开发中的多端适配与响应式布局。多端适配涉及平台和设备适应,确保统一用户体验;响应式布局利用媒体查询和弹性布局维持不同设备的布局一致性。实践中,开发者可借助跨平台框架实现多平台开发,运用响应式布局技术适应不同设备。同时,注意兼容性、性能优化和用户体验,以提升小程序质量和用户体验。通过这些方法,开发者能更好地掌握小程序全栈开发。