Linux下进度条程序实现以及自动化构建工具makefile的实现和对回车键的理解

2023-09-18 21:27:39

在实现进度条之前我们要了解一些有关实现进度条的知识。例如回车和makefile的使用

自动化构建工具:makefile

makefile实现的目的就是可以进行自动化的编译与自动化清理,即实现好了makefile之后,仅仅使用make指令就可以直接完成程序的编译过程。

先看一看咱们实现makefile之后得到的效果截图:

这里make指令的过程就相当于代替了gcc test.c -o test.exe 这一条指令。然后就是就得到了可执行程序test.exe。

接下来进行清理: 此时就删除了新生成的可执行程序test.exe

makefile的实现

先将目光 聚集到前三行,这三行就相当于是C语言中typedef进行的重命名工作,但是vim中在使用时区别的就是形式上:$(typedef_name)。而这里需要了解一下依赖关系和依赖方法,看到有数据的第四行和第五行:$(dest):$(src),这里表示的含义就是:test.exe的实现是依赖于test.c,而$(dest)就被称作目标文件,$(src)被称作依赖文件。依赖的方法也就是将依赖文件变成目标文件的,也就是:cc $^ -o $@也就是编译的过程,而 $^ 和 $@有分别代表的是什么呢???

$^代表的是上一行的依赖文件(右边),$@代表的是上一行的目标文件(左边)。

但是有些过程是不需要依赖文件的,列入clean:的过程,仅仅是进行可执行程序的删除功能,所以并不需要依赖什么文件去执行这一过程。

还有一点就是为什么编译文件时输入make指令就行,而清除的过程需要,make clean,这其实就关乎于你makefile中的实现顺序,因为我是先实现编译的过程,所以就可以省略make后面的文件名,加上也行:

所以这里不用太在意谁先谁后。


最后再谈谈.PHONY:clean这一行命令是干啥的???

先看一下下面的两个场景:

1.

当我在已经形成好了可执行程序test.exe之后,再次想要编译就拒绝了。

2.

而make clean命令就可以一直被执行,尽管已经删除了该文件,可是依旧可以一直执行该命令。其实这就与.PHONY的功能有关。(所以给文件编译也加上该行指令)

所以你会发现:.PHONY的作用就是(总是被执行的)也就是说,当执行到该命令时不会判断,而是始终执行(这里用到了判断,后面会进行概括)

如果你细心的话,将.PHONY:clean删除的话,所能够执行的效果是不是就不会总是被执行呢??其实还是会的,进行清除的时候不需要做任何的判断,但是编译一个文件需要,这取决于文件的新旧:

也就是说只有新文件才能被编译,旧文件(也就是被编译过的文件并不会进行二次编译的过程)

但是既然要判断新旧的话,那自然是少不了进行对比,只有进行对比才可以判断出文件的新旧,所以就引入了文件的时间属性:

文件的时间属性 

一个文件具有三种时间:

  1. Access time:文件的最近一次的访问时间
  2. Modify time:文件的最近一次的内容修改时间
  3. Change time:文件的最近一次属性修改的时间

可以用stat+file_name进行查看文件的三个时间属性:

Modify 

而我们对文件进行 ll(ls-l) 命令时查看到的是文件的什么时间呢??(可以采用控制变量的方法去逐一改变各个时间)

其实ll+文件的时候展开的其实就是Modify time,也就是文件最近一次的内容修改时间。

所以这里可想而知作为一个文件最具有代表性的时间肯定就是Modify time(文件最近一次内容修改的时间)

所以回归到问题,一个文件什么时候可以再次被进行编译呢??当然是一个新文件,也就是文件的Modify time进行更新过,也就是源文件可执行程序对比时间(Modify time)。

touch+一个现有文件: 更行文件的各个时间,如果想改变某一个特定时间就-a(访问)-m(内容)-c(属)。

Change

还有一点就是文件的属性时间是比较特别的,也就是不论什么时间改变的话,文件的属性时间都会陪同一起进行更改

 Assess

文件的访问时间也是一个特别的存在,访问文件可以说是对一个文件最频繁的操作,所以说,文件的Assess time经常会进行更改,但是实际上并不是这样。

我们知道文件是存放在硬盘当中,而硬盘又属于外设,所以相较于内设的访问效率会低很多,这就是为啥我们在打开文件时不直接在硬盘中进行而是将文件加载进入cpu,通过cou进行文件的访问,所以说,我们并不会实时的访问硬盘设备,也不会频繁的将文件加载进cpu,更不会没访问一次文件就更改一下文件的访问时间,什么时候更改可以说看你的计算机心情,每个计算机的心情肯定都不是一样的。

回车与换行

回车(\n):光标回到该行的起始位置处

换行(\r):光标换到下一行

回车换行(\n\r):光标进入下一行的行首位置处

其实windows下的回车键的功能就是执行的回车换行的功能

回车键(\r)的认识

但是还是得测试一下\r回车符(这里用到sleep休眠函数):

Test_1:

运行结果: 啥都没有输出


Test_2:

运行结果字符‘h’数量变少了而且接下来的输入会覆盖调字符串h


结论:回车符(\r)的作用是使得光标回到该行的起始位置处,并且如果当下还有输出的数据会将原输出的内容逐一覆盖掉,Test_1中什么数据都没有输出是因为输出的字符串太短以至于被命令行给覆盖(就是下面这玩意)

所以导致啥结果输出都没有。

换行键(\n)的认识.

换行键其实还有一个隐藏功能:对缓冲区的数据进行行刷新

其实我们在键盘上进行输入的数据会先进入输入缓冲区里,而输出的数据也同样会先进入输出缓冲区,并不是直接在终端显示出来。但是换行符(\n)的作用恰恰就是对缓冲区的数据进行行刷新,所以会直接显示在终端中。

Test_1:

执行结果会先将数据输出,然后休眠两秒再显示命令行


Test_2:

执行结果:先进行停顿两秒,再将缓冲区的数据打印到命令行中。


Test_3:

其实还有一种函数可以刷新缓冲区(流):fflush

我们缓冲区的数据其实默认放在流中,像输入缓冲区的数据就放在输入流(stdin),输出缓冲区的数据默认放在输出流(stdout)

执行结果:

所以相较于Test_1而言,该fflush可以满足不用输出不必要的换行符。

 

粗略实现进度条代码

其实实现进度条所用到的主要就是以上两大重点:makefile与换行键的使用。

同VS一样,也是使用不同的文件实现该进度条:


先看一下自动化构建工具makefile:

因为头文件会自动调用,所以在编译时就不需要编译头文件了。


主要就是看一下代码的实现了


这里其实是有很多可以改进的地方的,例如进度百分比可以用分数的形式 ,或者进度框里的字符换一下,卡顿一下等等

优化代码

这一版的优化就存在小数占比 

再次优化

这次的效果就是可以模拟加载卡顿的情况

最终实现的代码完整版 (会的话可以直接跳过前面看这个)

这次不仅布局上优化,而且还会卡顿一下 

更多推荐

解释什么是分布式数据库,列举几种常见的分布式数据库系统

1、什么是敏感信息和隐私保护?解释隐私保护的技术手段。敏感信息和隐私保护是指在收集、存储和使用个人数据时,需要采取一系列措施来保护这些数据的安全和机密性,防止数据被未经授权的第三方访问、使用或泄露。这些措施包括加密、访问控制、数据脱敏、数据加密、隐私政策等。在隐私保护的技术手段方面,常用的技术包括加密和访问控制。加密技

mysql自动删除过期的binlog

一、binlog_expire_logs_seconds配置项mysql8.0使用配置项binlog_expire_logs_seconds设置binlog过期时间,单位为秒。mysql旧版本使用配置项expire_logs_days设置binlog过期时间,单位为天,不方便测试。在8.0使用expire_logs_d

OPTEE Benchmark框架

安全之安全(security²)博客目录导读OPTEE调试技术汇总目录一、序言二、Benchmark框架三、Benchmark实现细节1、设计概况2、时间戳源3、调用时序图4、添加自定义时间戳5、构建并运行Benchmark6、限制和进一步措施一、序言本节中描述的特性依赖于上游不可用的Linuxkernelpatch,

conda手动下载虚拟环境中的包

一.下载导入tar安装包1.准备安装包安装包可从官网下载,或直接拷贝已有虚拟环境中的包【补充】关于虚拟环境中包的存储路径打开cmd,输入condaconfig--show查看pkgs_dirs属性的值C:\Users\XXX>condaconfig--showpkgs_dirs:-D:\program\anaconda

PostgreSQL 事务&并发&锁

文章目录PostgreSQL事务大家都知道的ACID事务的基本使用保存点PostgreSQL并发并发问题MVCCPostgreSQL锁机制表锁行锁总结PostgreSQL事务大家都知道的ACID在日常操作中,对于一组相关操作,通常要求要么都成功,要么都失败。在关系型数据库中,称这一组操作为事务。为了保证整体事务的安全性

软件设计模式系列之十二——外观模式

在软件设计中,经常会遇到需要与复杂子系统进行交互的情况。为了简化客户端与子系统之间的交互,提高系统的可维护性和可用性,外观模式应运而生。外观模式(FacadePattern)是一种结构型设计模式,它提供一个统一的界面,用于访问系统中的一组相关接口,从而隐藏了系统的复杂性。在本文中,我们将深入探讨外观模式,包括其定义、举

员工犯错,就应该受惩罚吗?

先说结论,惩罚肯定是不能有的。我们应该指导员工减少犯错的概率。在项目开发过程中,总会遇到项目成员犯错的场景。根据所犯错误是否具有共性特征,我把问题归为二类,不同类型的错误,采取不同的应对措施。第一类:有共性的问题。第二类:没有共性的问题。共性的定义:一个人多次或者多个人都犯过的错误。第一类:有共性的问题。对于有共性的问

vue3 - 使用reactive定义响应式数据进行赋值时,视图没有改变,值已经改变的解决方案

问题:在Vue3.0中我们使用reactive()定义的响应式数据的时候,当是一个数组或对象时,我们直接进行赋值,发现数据已经修改成功,但是页⾯并没有自动渲染成最新的数据;这是为什么呢?就如同官网所说的reactive存在一些局限性:(官方的描述)原因:原因就是reactive函数会返回一个Proxy包装的对象,所以当

网络安全深入学习第六课——热门框架漏洞(RCE— Weblogic反序列化漏洞)

文章目录一、Weblogic介绍二、Weblogic反序列化漏洞历史三、Weblogic框架特征1、404界面2、登录界面四、weblogic常用弱口令账号密码五、Weblogic漏洞介绍六、Weblogic漏洞手工复现1、获取账号密码,这是一个任意文件读取的漏洞1)读取SerializedSystemIni.dat文

面向对象的分析与设计(精品课程)第二章作业

面向对象的分析与设计(精品课程)第二章作业一.单选题(共4题,30.4分)二.多选题(共1题,7.6分)三.填空题(共5题,38分)四.简答题(共3题,24分)一.单选题(共4题,30.4分)(单选题)UML中的事物包括结构事物、分组事物、注释事物和()。A实体事物B边界事物C控制事物D动作事物(单选题)UML中的4种

Linux设备树OF操作函数

OF操作函数我们知道Linux内核使用设备树的形式去描述芯片硬件设备节点的各种属性,设备树的树形结构可以层次化的组织这些节点属性。设备树源码属于脚本格式的文件,Linux内核无法直接使用脚本格式,所以最终使用时需要将设备树源码编译为二进制的“.dtb”格式,最终Uboot将".dtb"格式设备树传递给Linux内核使用

热文推荐