Linux基础-Makefile的编写、以及编写第一个Linux程序:进度条(模拟在 方便下载的同时,更新图形化界面)

目录

一、Linux项目自动化构建工具-make/Makefile

​编辑

背景:

makefile小技巧:

二、Linux第一个小程序-进度条

先导:

1.如何利用/r,fflush(stdout)来实现我们想要的效果;

2.写一个倒计时:

进度条:

version1:一个普通的进度条

version2:具体的应用场景,模拟下载软件

version3:在未来,方便下载的同时,更新图形化界面

代码:version3:

processbar.c:

processbar.h:

Main.c:


进度条完整代码在文章末尾

一、Linux项目自动化构建工具-make/Makefile

如图:让我们简单的来看一下makefile具有什么功能

你可以随意创建一个可运行的代码

在Makefile中

mytest:test.cgcc -o mytest test.c
.PHONY:clean
clean:rm -f mytest

然后:

makefile是一个文件,make是一个命令。

背景:

1.会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力
2.一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
3.makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
4.make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
5.make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

依赖关系:

$表示:取内容 

code.exe依赖于code.c

$@---目标文件

$^----整个依赖文件列表

注意:在makefile内的注释是#

如图:我们在makefile中这样写到

code.exe:code.ogcc code.o -o code.exe
code.o:code.sgcc -c code.s -o code.o
code.s:code.igcc -S code.i -o code.s
code.i:code.cgcc -E code.c -o code.i
.PHONY:clean
clean:rm -f code.i code.s code.o code.exe

makefile从上往下识别,而识别到code.o时,code.o并不存在,就不会执行该命令,继续往下识别,知道识别到code.c时,执行code.c的命令,再倒序执行。

一定要把最终需形成的文件放置开头

makefile小技巧:

makefile支持变量:

在执行程序时,隐藏命令

在使用makefile时,依赖方法只能有一行吗?可以有多行

我们不想显示这些命令:


二、Linux第一个小程序-进度条

\r&&\n
回车概念
换行概念
老式打字机的例子

我们键盘上的Enter键就相当于回车+换行 \r\n

先导:

1.如何利用/r,fflush(stdout)来实现我们想要的效果;

如图:我在test.c和makefile文件中写入这样的代码

打印后程序休眠3s,结束程序

test.c:

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

makefile:

bin=test.exe
src=test.c$(bin):$(src)@gcc -o $@ $^@echo "complier &(src) to &(bin)..."
.PHONY:clean
clean:@rm -f $(bin)@echo "clean project..."

同上:

3s后再打印,程序退出同时,打印。(未打印时,不代表程序没执行,只是放于缓冲区了)

提问:printf和sleep哪个函数先运行?printf先运行,由于执行代码是从上至下。

一般只有缓冲区满的时候,程序结束的时候,才会刷新缓冲区,因此在这里我们用到fflush函数强制刷新。

查阅手册:

修改代码后:

2.写一个倒计时:

在test.c中写到:

#include<stdio.h>
#include<unistd.h>int main()
{int cnt = 10;while(cnt >= 0){printf("%d\r",cnt);fflush(stdout);--cnt;sleep(1);}printf("\n");return 0;
}

实际上当我们运行程序时,会出现一个问题,明明打印的是10 - 0,但是,却变成从10、90、80....

这是因为,打印在显示器上的都是字符,当10时是两个字符,而当变为9后,只有一个字符,0无法被覆盖,则会一直被打印,解决办法:%2d

执行这个代码后,就会直接覆盖两个字符。

#include<stdio.h>
#include<unistd.h>int main()
{int cnt = 10;while(cnt >= 0){printf("倒计时: %2d\r",cnt);fflush(stdout);--cnt;sleep(1);}printf("\n");return 0;
}

进度条:

version1:一个普通的进度条

processbar--processbar.c--processbar.h--Main.c

然后在makefile中写到:

 processbar:Main.c processbar.cgcc -o $@ $^.PHONY:cleanclean:rm -f processbar   

processbar.c--processbar.h--Main.c分别写到:

processbar.c--processbar.h--Main.c

processbar.c:

   #include"processbar.h"                                                                                                         #include<string.h>                                                                                                          #include<unistd.h>                                                                                                          #define Length 101                                                                                                          #define Style '#'                                                                                                          const char *lable = "|/-\\";                                                                                                          void Procbar()                                                                                                          {                                                                                                                                 char bar[Length];                                                                                                          memset(bar,'\0',sizeof(bar));                                                                                                          int len = strlen(lable);                                                                                                                               int cnt = 0;                                                                                                          while(cnt <= 100)                                                                                                          {                                                                                                          printf("[%-100s][%2d%%][%c]\r",bar,cnt,lable[cnt%len]);  fllush(stdout);                                                                             bar[cnt++] = Style;                                                                                               usleep(50000);                                                                                                               }                                                                                                                         printf("\n");                                                                                              }                                                                                                                        

usleep,相当于原来sleep的10^-6,因此在这里代表将原本的100s缩短为5s完成

之后会输出这样的结果:

当然这样还不够完美:

version2:具体的应用场景,模拟下载软件

在Main.c

#include"processbar.h"
#include<unistd.h>//download
void download()
{double filesize = 100*1024*1024;//100Mdouble current = 0.0;double bandwidth = 1024*1024*1.0;printf("download begin,current: %lf\n",current);while(current <= filesize){Procbar(filesize,current);//从网络中获取数据current += bandwidth;usleep(50000);}printf("\ndownload done, filesize:%lf\n",filesize);
}int main()
{//Procbar(100.0,56.9);//Procbar(100.0,1.0);//Procbar(100.0,99.9);//Procbar(100.0,100);download();return 0;
}

在processbar.c中:

#include"processbar.h"
#include<string.h>
#include<unistd.h>#define Length 101
#define Style '#'
const char *lable = "|/-\\";
void Procbar(double total,double current)
{char bar[Length];memset(bar,'\0',sizeof(bar));int len = strlen(lable);int cnt = 0;double rate = (current * 100.0)/total; int loop_count = (int)rate;while(cnt <= loop_count){printf("[%-100s][%.1lf%%][%c]\r",bar,rate,lable[cnt%len]);fflush(stdout);bar[cnt++] = Style;}printf("\n");
}

这样却是一行一行的输出:

其实是因为

最后:

更优processbar.c代码:

#include"processbar.h"
#include<string.h>
#include<unistd.h>#define Length 101
#define Style '#'
const char *lable = "|/-\\";
void Procbar(double total,double current)
{char bar[Length];memset(bar,'\0',sizeof(bar));int len = strlen(lable);int cnt = 0;double rate = (current * 100.0)/total; int loop_count = (int)rate;while(cnt <= loop_count){// printf("[%-100s][%.1f%][%c]\r",bar,rate,lable[cnt%len]);// fflush(stdout);bar[cnt++] = Style;}printf("[%-100s][%.1f%][%c]\r",bar,rate,lable[cnt%len]);fflush(stdout);
}

version3:在未来,方便下载的同时,更新图形化界面

Main.c:

#include"processbar.h"
#include<unistd.h>//download
void download(callback_t cb)
{double filesize = 100*1024*1024;//100Mdouble current = 0.0;double bandwidth = 1024*1024*1.0;printf("download begin,current: %lf\n",current);while(current <= filesize){cb(filesize,current);//从网络中获取数据current += bandwidth;usleep(50000);}printf("\ndownload done, filesize:%lf\n",filesize);
}int main()
{//Procbar(100.0,56.9);//Procbar(100.0,1.0);//Procbar(100.0,99.9);//Procbar(100.0,100);download(Procbar);return 0;
}

processbar.h:

#pragma once
#include<stdio.h>
#include<unistd.h>//void Procbar();
typedef void(*callback_t)(double ,double );
void Procbar(double total,double current);

再更新

#include"processbar.h"
#include<unistd.h>
double bandwidth = 1024*1024*1.0;
//download
void download(double filesize,callback_t cb)
{//double filesize = 100*1024*1024;//100Mdouble current = 0.0;printf("download begin,current: %lf\n",current);while(current <= filesize){cb(filesize,current);//从网络中获取数据current += bandwidth;usleep(50000);}printf("\ndownload done, filesize:%lf\n",filesize);
}int main()
{//Procbar(100.0,56.9);//Procbar(100.0,1.0);//Procbar(100.0,99.9);//Procbar(100.0,100);download(100*1024*1024,Procbar);download(10*1024*1024,Procbar);download(99*1024*1024,Procbar);download(900*1024*1024,Procbar);return 0;
}

最后:


代码:version3:

processbar.c:

#include"processbar.h"
#include<string.h>
#include<unistd.h>#define Length 101
#define Style '#'
const char *lable = "|/-\\";
void Procbar(double total,double current)
{char bar[Length];memset(bar,'\0',sizeof(bar));int len = strlen(lable);int cnt = 0;double rate = (current * 100.0)/total; int loop_count = (int)rate;while(cnt <= loop_count){// printf("[%-100s][%.1f%][%c]\r",bar,rate,lable[cnt%len]);// fflush(stdout);bar[cnt++] = Style;}printf("[%-100s][%.1f%][%c]\r",bar,rate,lable[cnt%len]);fflush(stdout);
}

processbar.h:

#pragma once
#include<stdio.h>
#include<unistd.h>//void Procbar();
typedef void(*callback_t)(double ,double );
void Procbar(double total,double current);

Main.c:

#include"processbar.h"
#include<unistd.h>
double bandwidth = 1024*1024*1.0;
//download
void download(double filesize,callback_t cb)
{//double filesize = 100*1024*1024;//100Mdouble current = 0.0;printf("download begin,current: %lf\n",current);while(current <= filesize){cb(filesize,current);//从网络中获取数据current += bandwidth;usleep(50000);}printf("\ndownload done, filesize:%lf\n",filesize);
}int main()
{//Procbar(100.0,56.9);//Procbar(100.0,1.0);//Procbar(100.0,99.9);//Procbar(100.0,100);download(100*1024*1024,Procbar);download(10*1024*1024,Procbar);download(99*1024*1024,Procbar);download(900*1024*1024,Procbar);return 0;
}

结语:

       随着这篇关于题目解析的博客接近尾声,我衷心希望我所分享的内容能为你带来一些启发和帮助。学习和理解的过程往往充满挑战,但正是这些挑战让我们不断成长和进步。我在准备这篇文章时,也深刻体会到了学习与分享的乐趣。

       在此,我要特别感谢每一位阅读到这里的你。是你的关注和支持,给予了我持续写作和分享的动力。我深知,无论我在某个领域有多少见解,都离不开大家的鼓励与指正。因此,如果你在阅读过程中有任何疑问、建议或是发现了文章中的不足之处,都欢迎你慷慨赐教。         你的每一条反馈都是我前进路上的宝贵财富。同时,我也非常期待能够得到你的点赞、收藏,关注这将是对我莫大的支持和鼓励。当然,我更期待的是能够持续为你带来有价值的内容,让我们在知识的道路上共同前行

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/424828.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ 红黑树(带头结点)

想必在看到这篇文章的时候&#xff0c;你一定是带着问题去搜索的&#xff0c;一定是对红黑树已经有了初步大致的认识&#xff0c;已经知道了红黑树的性质与普通红黑树的功能与如何代码实现&#xff0c;但是莫一天突然看到了带头结点的红黑树&#xff0c;肯定是对此有一些疑惑的…

匹配行最大值替换为最小值公式

好的!我们一步一步详细讲解这个公式的作用和如何实现你想要的功能。 ### 数据结构假设: - 你的数据在 A、B、C 列中,每一行都有值。 - 需要在 A 列和 B 列相同的行中,找到 C 列中的最大值,将其替换为最小值,其他值保持不变。 ### 公式: ```excel =IF(C2=MAX(IF(($A$2:$…

Clickhouse使用笔记

clickhouse官方文档&#xff1a;https://clickhouse.com/docs/zh/sql-reference/data-types/decimal 一&#xff0c;建表 create table acitivity_user_record ( id String DEFAULT generateUUIDv4(), -- 主键自增 activityId String, userId String, userName Nullable(Strin…

Git之误执行git rm -r解决方案(六十七)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

9月16日星期一今日早报简报微语报早读

9月16日星期一&#xff0c;农历八月十四&#xff0c;早报微语早读。 1、猫眼专业版数据&#xff1a;2024年中秋档票房破亿&#xff1b; 2、WTT澳门冠军赛&#xff1a;孙颖莎夺得女单冠军&#xff1b; 3、乐山夹江县&#xff1a;支持农村居民进城购房&#xff0c;每户补贴5万…

天融信把桌面explorer.exe删了,导致开机之后无windows桌面,只能看到鼠标解决方法

win10开机进入桌面&#xff0c;发现桌面无了&#xff0c;但是可以ctrlaltdelete调出任务管理器 用管理员权限打开cmd&#xff0c;输入&#xff1a; sfc /scanfilec:\windowslexplorer.exe 在运行C:\windows\Explorer.exe&#xff1b;可以进入桌面&#xff0c;但是隔离几秒钟…

Java多线程1

目录 1.简述进程与线程之间的主要差异。 2.描述进程间通信的常用方式。 3.详细说明线程间如何进行通信。 4.什么是原子性&#xff1f;请举例说明。 5.i 和 i--操作是否具有原子性&#xff1f;为什么&#xff1f; 1.简述进程与线程之间的主要差异。 进程和线程是计算机系统…

MYSQL基础-多表操作-事务-索引

1. 多表设计 概述 项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互关联&#xff0c;所以各个表结构之间也存在着各种联系&#xff0c;基本上分为三种&#xff1a; …

Python3时间模块使用

文章目录 python安装时间处理模块概述time 模块常用方法 datetime 模块常用方法 时间戳与 datetime 的相互转换时区处理使用 pytz 设置时区 实际应用场景日志时间处理时间差计算不同时区的时间转换 结论 在 Python 编程中&#xff0c;时间处理和时间格式转换是非常常见的需求&a…

美团图床设置教程

大厂图床&#xff0c;CDN加速 项目地址&#xff1a;https://github.com/woniu336/mt-img 使用方法 在mt.php填上你的token即可&#xff0c;然后打开index.html上传图片 获取token方法 注册https://czz.meituan.com/发布视频&#xff0c;上传封面&#xff0c;注意在上传封面后…

【退役之再次线上部署】Spring Boot + VUE + Nginx + MySQL

这篇博客写在凌晨 4 点 20 分&#xff0c;这个时候我刚线上部署完成 web 项目&#xff0c;自己写的全栈项目 这个点儿&#xff0c;也睡不着了&#xff0c;索性就写篇博客记录一下 一、踩坑实录 这个是 最重要的&#xff0c;所以写在前面 Nginx 配置文件 location location /a…

【更新】上市公司-供应链金融水平数据(2000-2023年)

上市公司供应链金融是指上市公司利用其产业链核心地位&#xff0c;通过整合金融资源&#xff0c;为供应链上下游企业提供包括融资、结算、风险管理等在内的综合金融服务。为了衡量上市公司的供应链金融水平&#xff0c;参考周兰等&#xff08;2022&#xff09;的研究方法&#…

基于Spring Boot的心理健康服务系统的设计与实现(毕业论文)

目    录 1 前言 1 1.1 研究目的与意义 1 1.2 国内外研究现状 1 1.3 论文结构 3 2 可行性分析 3 3 系统需求分析 4 3.1 用户需求分析 4 3.2 心理咨询师需求分析 5 3.3 管理员需求分析 6 3.4 业务流程分析 7 4 概要设计 9 4.1 系统结构设计 10 4.2 功能模块设计 10 4.2.1 管…

20Kg载重30分钟续航多旋翼无人机技术详解

一、机架与结构设计 1. 材料选择&#xff1a;为了确保无人机能够承载20Kg的负载&#xff0c;同时实现30分钟的续航&#xff0c;其机架材料需选用轻质高强度的材料&#xff0c;如碳纤维或铝合金。这些材料不仅具有良好的承重能力&#xff0c;还能有效减轻无人机的整体重量&…

计算机毕业设计Python深度学习垃圾邮件分类检测系统 朴素贝叶斯算法 机器学习 人工智能 数据可视化 大数据毕业设计 Python爬虫 知识图谱 文本分类

基于朴素贝叶斯的邮件分类系统设计 摘要&#xff1a;为了解决垃圾邮件导致邮件通信质量被污染、占用邮箱存储空间、伪装正常邮件进行钓鱼或诈骗以及邮件分类问题。应用Python、Sklearn、Echarts技术和Flask、Lay-UI框架&#xff0c;使用MySQL作为系统数据库&#xff0c;设计并实…

Gitlab 中几种不同的认证机制(Access Tokens,SSH Keys,Deploy Tokens,Deploy Keys)

前言 公司主要使用 Go 语言做项目&#xff0c;有一些 Gitlab 私有仓库需要引用&#xff0c;在做 CI 时&#xff0c;要自行配置权限以获取代码。 最近发现各个项目组在做 CI 遇到仓库权限问题时的解决方式不尽相同&#xff0c;有用 Project Token 的&#xff0c;有用 Deploy K…

unity3d入门教程五

unity3d入门教程五 13鼠标事件处理13.2鼠标跟随13.3鼠标拖拽&#xff08;选中对象&#xff0c;拖动对象&#xff09;13.4几个问题14.1事件函数14.2脚本的执行顺序14.3脚本的参数14.4引用类型的参数&#xff08;进行图片更换&#xff0c;人物换装&#xff09; 13鼠标事件处理 需…

自由流转--实例

一、自由流转的形态 流转能力打破设备界限&#xff0c;多设备联动&#xff0c;使用户应用程序可分可合、可流转&#xff0c;实现如邮件跨设备编辑、多设备协同健身、多屏游戏等分布式业务。 二、跨端迁移 在应用开发层面&#xff0c;跨端迁移指在A端运行的UIAbility迁移到B端上…

Linux操作系统如何添加新字体

在一个Linux操作系统及办公软件刚安装后&#xff0c;会发现缺少常用的“楷体_GB2312”和“仿宋_GB2312”字体。此时&#xff0c;只需要从其它电脑复制到或者从互联网上下载到这两个字体文件&#xff0c;然后导入到自己的电脑即可&#xff0c;再次打开办公软件就会看到这个字体已…

linux重要文件

/etc/sysconfig/network-scripts/ifcfg-eth1 网卡重启 /etc/init.d/network restart ifup ethname & ifdown ethname /etc/resolv.conf 设置Linux本地的客户端DNS的配置文件 linux客户端DNS可以在网卡配置文件(/etc/sysconfig/network/ifcfg-eth0 DNS2)里配置 也可以在/et…