Linux系统编程学习 NO.8 ——make和Makefile、进度条程序

news/2024/6/18 23:47:51 标签: 1024程序员节

前言

今天是1024程序员节,不知不觉离第一次写博客已经过去了一年了。在此祝各位程序员不写bug,不再秃头。

make和Makefile

什么是make和Makefile?

make和Makefile是软件开发时所用到的工具和文件。make是一个指令工具。Makefile是一个当前目录下的文件。make和Makefile可以提高我们在Linux下的开发效率。

简单演示

下面用一份c代码来进行演示。
在这里插入图片描述
在当前目录下新建一个Makefile文件,并写上相应的依赖关系与依赖方法。
在这里插入图片描述
接着使用一下make指令。
在这里插入图片描述

依赖关系和依赖方法的解释

这里使用一个生活中的例子来解释依赖关系和依赖方法。现在已经是10月23日了,月底来了,相信不少同学的钱包也已经见底了。这是该怎么办呢?当然是打电话给你的老爸要生活费。找老爸要生活费这一行为也需要对应的依赖关系和依赖方法。你打一个电话过去说,“爹啊,月底了我没钱了,你给我的xx上转1500元当做生活费。”。此时,这你打电话给你爹,首先声明的是依赖关系,要到生活费的前提必须是他是你爹。毕竟你总不能打电话给你舍友的爹要生活费吧。那么往你手机上转账的行为就是对应的依赖方法。你要生活费总不能只给你爹说,“爹啊!”。你只声明依赖关系却没有依赖方法,你的老爹也不会给你转账的。

make会自动推导Makefile的依赖关系

下面我写一个稍微复杂一点的场景来演示make自动推导Makefile的依赖关系。
在这里插入图片描述
在这里插入图片描述
上面的依赖关系的代码顺序可以随意交换,但是依赖关系的逻辑关系不能缺失,否则make无法自动推导依赖关系。

make的默认动作

make将文件的第一个依赖方法和依赖方法设置成为make指令的默认动作。
在这里插入图片描述

.PHONY

为什么make了之后不能接着make呢?
在这里插入图片描述
这是因为操作系统为了提高编译效率而是实现的机制。由于你的源文件的生成时间是大于可执行性程序的生成时间的。此时make就不会编译你的源文件。如果你修改了源文件,此时你的源文件的生成时间是小于你的可执行程序的。故make会生成新的可执行程序。
在这里插入图片描述
那么它是如何实现按的呢?这里需要引出一个概念即,一个文件的时间属性。一个文件的时间属性分为三种, Access时间(最近被访问时间)、Modify时间(修改时间)、Change时间(改变时间)。 几乎你对文件的任何操作都会修该Access时间。在介绍Modify时间和Change时间前,在这里再次提及一个概念。文件本质等于文件的内容加文件的属性。这里的Modify时间显示的是最近一次文件内容被修改的时间。而Change时间则表示最近一次文件属性被修改的时间。这里介绍一个指令stat,用于查看文件状态。

stat 文件名


在这里插入图片描述
为什么最近访问时间没有变呢?其实早期的linux系统的最近访问时间实惠随着你的操作而实时更新的。后来由于处于对性能的优化,最近访问时间不会随着访问而修改。因为文件是存储在磁盘上的,而磁盘属于外部设备。它的访问效率是比较低的,为了进一步优化性能所以最近访问时间默认情况下不会随着被访问而修改。那么我想要让他修改呢?那就是用touch命令。
在这里插入图片描述
只要修改源文件的最近修改时间,make就就可以通过依赖关系来进行在次编译。
在这里插入图片描述
所以make的对于是否可以再次编译的条件是源文件的最近修改时间小于可执行程序的最近修改时间。
如果我希望每次编译都执行呢?需要在Makefile文件中加入.PHONY来修饰,使它总是被执行。
在这里插入图片描述
但是这种写法并不好,因为有时候我们的一些编译问题还是需要我们手动清理后再编译才能解决的。这里建议.PHONY来修饰clean。

特殊符号

由于每次都要手写gcc命令比较麻烦,可以尝试使用特殊符号来代替对应的可执行程序和源文件。
在这里插入图片描述
这里的$@可以替换成的是:左边的内容, $^ 可以替换成:右边的内容。
在对应的方法前加上@符号可以不回显指令的内容。
在这里插入图片描述

进度条程序

经过了一段时间的Linux操作系统的学习,下面就带着大家用一个简单进度条程序来练练手吧。

前言

回车和换行的概念

这里需要提前知道一个概念,即回车和换行的概念。c语言中的’\n’就可以同时实现回车和换行的操作,但是它还有别的功能,且听为等会讲述。换行大家一定不会陌生,就是从一行跳转到下一行,c语言中,\n表示换行+回车(注:c语言没有单独换行的转义字符)。回车表示将光标移动到文档的开头,在c语言中,\r表示回车。
这里我举一个生活中的例子,在19/20世纪的欧洲,一些上层阶级往往会有当时比较潮流的科技设备,打字机。
在这里插入图片描述
在打字机上编写文字时,纸张是不断向上走的。这其实就是一个换行。每写一行文字,就需要手动将印章挪到每行的开头,这其实就是回车。

缓冲区的概念

下面我直接用代码举例
在这里插入图片描述
sleep函数是一个系统调用接口。当执行这个函数时,会休眠n秒。那么上面的代码输出结果是什么呢?答案是会先在显示器上打印hello linux,随后下一行休眠了一秒钟又输出了bash命令行。
在这里插入图片描述
如果不带上\n呢?结果会是什么呢?答案是当程序执行时,第一秒钟休眠了,随后在下一行中hello linux于bash同时输出在了一行。
在这里插入图片描述
这究竟是为什么呢?我相信在大家初步c语言学习的时候,一定听过一个概念就是c语言三大结构之一的顺序结构。代码是从main函数自上而下依次被执行的。那为什么是先休眠后输出呢?因为在sleep期间,程序的数据被暂时保存起来了。保存它的地方就是缓冲区。在这里进需要记住一个简单的概念,即缓冲区是一段被c语言所维护的内存空间。

下面介绍如何强制刷新缓冲区,使我们对应的printf语句先被执行。c程序默认会为用户打开三个输入输出流,标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。这里介绍一个函数fflush(),它接受一个文件流stream,会强制刷新这个流,使得缓冲区内的数据立刻被写到文件中(补充:Linux下一切皆文件,也包括显示器)。
在这里插入图片描述

实现一个进度条程序

10秒倒计时小程序

简单写一个10秒倒计时程序来为进度条程序做一个铺垫。
在这里插入图片描述
这里我就简单说一下程序的实现思路,当程序在屏幕上输出数字时,我们需要让它立刻被刷新出来并写入显示器文件。随后休眠一秒后,又会在显示上一个数字的位置,用上一个数字-1的值将它覆盖。因为使用了\r回车转义字符。这里的%-2d其实是输出格式控制。

进度条程序简易版

这里实现采取定义与生命分离的方式进行。这里创建三个文件,分别用于声明方法和实现方法以及测试方法。
在这里插入图片描述
先简单配置一下Makefile文件。
在这里插入图片描述
这里的:右边有两个.c文件,不过$^还是会默认带上这两个.c文件。.PHONY修饰clean表示该指令总是被执行。

第二步,在头文件中包含相关头文件以及声明函数方法。
在这里插入图片描述
第三步,实现进度条程序。定义一个字符串数组存储进度条的输出样式,为了让精度条执行时,有一个相应的动画效果。开辟一个数组来存储进度条的内容样式,通过循环来控制进度条在屏幕上的显示。每次回车打印完内容后将进度条的添加进度条内容,搭配上usleep就能达到控制进度条的速度。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

进阶版进度条

下面以模拟下载软件时的场景,带大家看一个关于回调函数版本进度条的实现。
首先,我们对原来的processbar.c进行一个修改。
在这里插入图片描述
使用回调函数的设计思路将进度条模块独立成回调函数,当下载时,download函数内部控制具体的进度条逻辑。主函数中只需要传一个回调函数就能使进度条跑起来。
在这里插入图片描述


http://www.niftyadmin.cn/n/5133734.html

相关文章

python检测序列中的元素是否满足严格升序关系

方法1 def lessThan1(seq):for index, value in enumerate(seq[:-1]):if value > seq[index1]:return Falsereturn True方法2 def lessThan2(seq):func lambda x, y: x < yreturn all(map(func, seq[:-1], seq[1:]))方法3 from operator import ltdef lessThan3(seq)…

这个故事有点长 - 舟山

这个故事有点长 - 舟山 &#x1f449;故事的开始 这是一个很长的故事&#xff0c;到底有多长呢&#xff1f;大概也就有六七年那么长吧。刚来上海时就一直想去看海&#xff0c;后来终于如愿以偿了&#xff0c;具体记不清了&#xff0c;只记得当时坐了地铁&#xff0c;又坐了几个…

Docker安装部署Elasticsearch+Kibana+IK分词器

Docker安装部署ElasticsearchKibanaIK分词器 Docker安装部署elasticsearch拉取镜像创建数据卷创建网络elasticsearch容器&#xff0c;启动&#xff01; Docker安装部署Kibana拉取镜像Kibana容器&#xff0c;启动&#xff01; 安装IK分词器安装方式一&#xff1a;直接从github上…

elasticsearch目录及配置参数说明

1.elasticsearch目录及其作用 bin 存放ES启动、关闭等脚本文件 存放执行文件&#xff0c;例如启动脚本、密钥工具等 config ES的配置文件所在的目录&#xff0c;其中有三个主要的配置文件 elasticsearch.yml是用于ES的最主要的配置文件 jvm.options用于配置ES JVM设置 l…

Linux 网络驱动实验(PHY芯片LAN8720)

目录 嵌入式网络简介嵌入式下的网络硬件接口 网络驱动是linux 里面驱动三巨头之一&#xff0c;linux 下的网络功能非常强大&#xff0c;嵌入式linux 中也常 常用到网络功能。前面我们已经讲过了字符设备驱动和块设备驱动&#xff0c;本章我们就来学习一下 linux 里面的网络设备…

提高抖音小店用户黏性和商品销量的有效策略

抖音小店是抖音平台上的电商模式&#xff0c;用户可以在抖音上购买各类商品。要提高用户黏性和商品销量&#xff0c;四川不若与众帮你整理了需要注意以下几个方面。 首先&#xff0c;提供优质的商品和服务。在抖音小店中&#xff0c;用户会通过观看商品展示视频和用户评价来选…

第一章 初识Android

一、Android简介 1.android系统架构 linux kernel&#xff08;Linux内核层&#xff09;&#xff1a;提供硬件底层驱动 libraries&#xff08;系统运行库层&#xff09;&#xff1a;提供了主要的特性支持&#xff0c;如SQLite库、Webkit库&#xff1b;还包含android runtime&…

Python——PyQt5以及Pycharm相关配置

PyQt5目录 常见的GUI框架一、安装pyqt5pip install pyqt5pip install pyqt5-tools二、Qt Designer三、在PyCharm中配置相关toolQtDisigner配置PyUIC配置PyRCC配置常见的GUI框架 Tkinter:Python内置的GUI框架,使用TCL实现,Python中内嵌了TCL解释器,使用它的时候不用安装额外…