【Linux】-- 开发工具yum、vim、gcc、g++、gdb、make、makefile使用介绍(三)

简介: 【Linux】-- 开发工具yum、vim、gcc、g++、gdb、make、makefile使用介绍

五、make/Makefile

1.了解make/Makefile

(1)make

       make是一个解释makefile中指令的命令工具。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中。

(2)Makefile

       Makefile是Linux项目自动化构建工具,Makefile规定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。编译的安排就叫做构建。构建规则都写在Makefile文件里面,要学会如何Make命令,就必须学会如何编写Makefile文件。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率,makefile成为了一种在工程方面的编译方法。

       make是一条命令,makefile是一个文件,两者搭配使用,形成可执行程序,完成项目自动化构建。

2.如何写一个Makefile

与源文件同级,创建一个Makefile文件:

将编译InsertSort.c的命令写入Makefile中。其中,第一行叫做依赖关系,第二行叫做依赖方法:

1. InsertSort:InsertSort.c       #依赖关系
2.         gcc InsertSort.c -o InsertSort -std=c99     #依赖方法

第一行开始的InsertSort叫做目标,InsertSort.c叫做前置条件,gcc InsertSort.c -o InsertSort -std=c99是命令,命令前有Tab键:

执行make命令后,会自动执行Makefile文件中的命令:

但是此时想再make一下,会发现不让make了:

因为可执行文件已经是最新了。Makefile默认的目标是文件,如果目标不是真实存在的文件,而是一个命令呢,那么这个目标就是伪目标,伪目标没有依赖关系,只有依赖方法,如下clean就是一个伪目标,make就不会去检查是否存在一个叫做clean的文件,而是每次运行都执行对应的命令:

1. InsertSort:InsertSort.c
2.         gcc InsertSort.c -o InsertSort -std=c99
3. .PHONY:clean      #伪目标
4. clean:
5. rm -f InsertSort

其中:

由于make扫描Makefile文件时,默认只会形成一个目标依赖关系,一般是第一个,因此,现在执行make,并不能达到删除InsertSort可执行文件的目的,因为make会生成第一个目标也就是生成InsertSort可执行程序:

此时要执行非第一个目标时,需要make加上目标:

当把两个目标的顺序交换一下,会发现,执行make时就先执行clean命令:

这下直接make时,就不是编译生成可执行文件了, 而是执行clean命令,如果要生成可执行程序,必须执行make 加上目标:

也可以用$@表示目标文件,$^表示上一行的冒号后面的依赖文件列表:

六、进度条小程序

1.回车和换行

  • 回车:行不变,列回到当前行的最开始
  • 换行:列不变,行切换到下一行

例如,如下代码,当执行打印后,需要等待3秒才结束程序:

enter.c

1. #include<stdio.h>
2. 
3. int main()
4. {
5. printf("33333333\n");
6. sleep(3);
7. 
8. return 0;
9. }

Makefile

1. enter:enter.c
2.         gcc -o $@ $^
3. .PHONY:clean
4. clean:
5. rm -f enter

那么打印内容会在屏幕上出现3秒以后程序才结束:

如果不加\n,那么一开始就不会打印字符串,等待3秒后,才会打印出字符串:

 

这两个程序运行结果并不代表sleep先于printf执行,其实只是printf已经执行,但是数据没有被立即刷新到显示器上而已。当没有\n时,字符串会暂时保存到用户C语言级别的缓冲区当中,显示器设备的刷新策略就是行刷新(\n),即立即刷新。

如果想在不带\n的情况下,让数据立即刷新出来, 可以调用fflush接口,不过fflush的参数是文件流:

那么对于这个程序,应该给fflush传什么参数呢?

由于在C语言中的文件操作,系统会默认地帮我们把对应的文件以C语言的方式打开,并且会默认打开3个输入输出流:

为什么程序会默认打开着3个输入输出流呢?因为程序为了帮我们计算数据,就有数据源和数据结果,C语言为了避免我们麻烦,默认给我们打开了这3个输入输出流,供我们读写。

对于刚刚的程序,想让代码立即刷新出来,我们借助fflush函数,因为printf是向stdout打印,那么刷新也是向stdout刷新,所以将stdout作为fflush的参数:

再执行make clean;make,会发现先刷新字符串,但是再等了3秒程序才结束:

对于\r,仅回车,行不变,列回到当前行的最开始,由于没有\n,所以每次循环的打印结果不会被显示出来:

1. #include<stdio.h>
2. 
3. int main()
4. {
5. int count  = 5;
6. while(count)
7.         {
8. printf("%d\r",count);
9.                 count--;
10. sleep(1);
11.         }
12. 
13. return 0;
14. }

那么为了让打印结果显示出来,可以使用fflush:

但是结果就变成在这个位置倒计时:

 

假如将count初始化为10,执行结果就更离谱:

这是因为显示器是字符设备,凡是显示到显示器上面的内容都是字符,凡是从键盘读取的内容也都是字符。所以上面第一次打印的count值为10并不是数字10,而是字符'1'和字符'0'。再对count--时,count的值只有一个字符,比如9,所以只能覆盖到一个字符,因此字符'0'永远都不会动。要解决这个问题,可以输出2个字符,这样就会把字符'0'给覆盖了:

执行结果:

 

2. 实现进度条小程序

假如实现进度条小程序,在同一行打印'#',每次刷新就多打印一个'#',以下代码是实现不了的,因为显示器是行刷新,没有\n就刷新不出来进度条:

1. #include<stdio.h>
2. #include<string.h>
3. #include<unistd.h>
4. 
5. #define NUM 100
6. 
7. int main()
8. {
9. char bar[NUM+1];
10. memset(bar,'\0',sizeof(bar));
11. 
12. int i = 0;
13. while(i <= 200)
14.         {
15. printf("%s",bar);//没有\n,在显示器上显示不出来‘#’
16.                 bar[i] = '#';
17.                 i++;
18. sleep(1);
19.         }
20. 
21. return 0;
22. }

那么加了\n以后呢?虽然'#'可以打印出来,但是打印却变成了不在同一行显示'#',这不符合我们的要求:

 

所以考虑到使用fflush:

但是发现运行结果,是每隔1秒自动多打印n个'#':

这不符合我们的需求,我们需要每次增加一个'#'。可以加上\r

现在每次刷新增加一个#":

这下达到了我们的要求,但是有没有发现好像刷新的太慢了,那就把刷新间隔缩短一些:

这下快一些了 :

但是i的上限是200,程序要执行好久才能看到最终的执行结果,而且还刷屏,不好观察,将i的上限改为20:

执行结果发现,执行完毕时提示符[delia@VM-8-17-centos progressBar]$ 和进度条在同一行呢:

能不能把提示符去掉?可以在程序执行结束时,换行:

现在程序执行结束就换行了:

如果想让进度条被[ ]包起来呢?

发现进度条从右向左显示:

加上'-'就从左向右显示了:

执行结果如下:

想加上数字百分比呢?

执行结果如下:

想在结尾增加光标旋转呢?

执行结果如下:

 

假如想更换进度条颜色呢?比如换成绿色:

执行结果如下:

好啦,进度条做好啦。完整代码段:

1. #include<stdio.h>
2. #include<string.h>
3. #include<unistd.h>
4. 
5. #define NUM 100
6. 
7. int main()
8. {
9. char bar[NUM+1];
10. memset(bar,'\0',sizeof(bar));
11. 
12. const char *token = "|/-\\";
13. 
14. int i = 0;
15. while(i <= 100)
16.         {
17. printf("\033[32m[%-100s][%d%%] [%c]\r",bar,i,token[i%4]);
18. fflush(stdout);
19.                 bar[i] = '#';
20.                 i++;
21. usleep(50000);
22.         }
23. 
24. printf("\n");
25. return 0;
26. }
相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
4月前
|
NoSQL Linux 开发工具
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
本文介绍了yum 包管理工具、Vim 编辑器、gcc/g++ 编译器、gdb 调试器、编译原理及 Makefile 的使用,同时还配备了如何使用,以及图解。旨在帮助读者更好地理解和应用这些工具与技术。
217 0
|
10月前
|
Linux Android开发 开发者
linux m、mm、mmm函数和make的区别
通过理解和合理使用这些命令,可以更高效地进行项目构建和管理,特别是在复杂的 Android 开发环境中。
483 18
|
12月前
|
Linux 开发工具
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
【Linux快速入门(二)】Linux与ROS学习之编译基础(make编译)
371 0
|
22天前
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
248 1
二、Linux文本处理与文件操作核心命令
|
6天前
|
存储 安全 Linux
Linux卡在emergency mode怎么办?xfs_repair 命令轻松解决
Linux虚拟机遇紧急模式?别慌!多因磁盘挂载失败。本文教你通过日志定位问题,用`xfs_repair`等工具修复文件系统,三步快速恢复。掌握查日志、修磁盘、验重启,轻松应对紧急模式,保障系统稳定运行。
94 2
|
16天前
|
缓存 监控 Linux
Linux内存问题排查命令详解
Linux服务器卡顿?可能是内存问题。掌握free、vmstat、sar三大命令,快速排查内存使用情况。free查看实时内存,vmstat诊断系统整体性能瓶颈,sar实现长期监控,三者结合,高效定位并解决内存问题。
58 0
Linux内存问题排查命令详解
|
22天前
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
466 2
|
1月前
|
Unix Linux 程序员
Linux文本搜索工具grep命令使用指南
以上就是对Linux环境下强大工具 `grep` 的基础到进阶功能介绍。它不仅能够执行简单文字查询任务还能够处理复杂文字处理任务,并且支持强大而灵活地正则表达规范来增加查询精度与效率。无论您是程序员、数据分析师还是系统管理员,在日常工作中熟练运用该命令都将极大提升您处理和分析数据效率。
120 16
|
28天前
|
Linux
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
|
3月前
|
监控 Linux 网络安全
Linux命令大全:从入门到精通
日常使用的linux命令整理
685 14