Makefile的通用模板 + 倒计时小程序(13)

文章目录

  • Makefile 的通用模板
    • 1. Makefile 的推导原则
    • 2. 设计 Makefile 的通用模板
    • 3. 通用模板代码(可以直接拿来用)
  • Linux 第一个系统程序-进度条(7-3.00.00)
    • 1. 补充回车与换行
    • 2. 行缓冲区
    • 3. 倒计时小程序

Makefile 的通用模板

1. Makefile 的推导原则

以程序的翻译作为例子来引出Makefile的推导原则。在Makefile中可以用警号(#)去注释

code:code.o    gcc code.o -o code     
code.o:code.s    gcc -c code.s -o code.o    
code.s:code.i    gcc -S code.i -o code.s    
code.i:code.c    gcc -E code.c -o code.i    .PHONY:clean    
clean:    rm -rf *.o *.i *.s code 

在这里插入图片描述

  • make时,code是依赖code.o的,可code.o文件在当前路径下存在吗?不存在,就向下去推导。
  • code.o是依赖code.s的,可code.s文件在当前路径也不存在,又向下推导,最终来到了code.c,发现在当前路径下存在该文件。
  • 就依次形成了code.i,code.s,code.o,code。所以make会进行依赖关系的推导,直到依赖文件是存在的
  • 这就类似于将依赖方法不断入栈,推导完毕,出栈执行方法,这就是makefile的推导原则

在这里插入图片描述


2. 设计 Makefile 的通用模板

  • 通用做法先将该路径下的所有.c文件全部编译成.o文件,再与动静态库进行链接,最终形成可执行程序,并不是直接将所有.c文件一股脑的形成可执行程序
    在这里插入图片描述

1. 第一代版本,并不具备通用性,只适用于code.c这一个源文件

1 code:code.o
2     gcc code.o -o code 
3 code.o:code.c
4     gcc -c code.c -o code.o
5 
6 .PHONY:clean 
7 clean:
8     rm -rf *.o code #下面的图片写错了

在这里插入图片描述

2. 第二代版本,用变量的形式去进行替换,但也不是很通用,只适用于编译一个文件

  1 BIN=code #可执行程序2 SRC=code.c #源文件3 OBJ=code.o4 CC=gcc #编译器5 RM=rm -rf #删除命令6 7 # $(变量)->内容,比如:$(BIN)->code 8 # 照着下面改即可9 $(BIN):$(OBJ)10     $(CC) $(OBJ) -o $(BIN)11 $(OBJ):$(SRC)12     $(CC) -c $(SRC) -o $(OBJ)13 14 .PHONY:clean15 clean:16     $(RM) $(BIN) $(OBJ)17 18 #code:code.o19 #   gcc code.o -o code                                                                                         20 #code.o:code.c                       21 #   gcc -c code.c -o code.o22 #                                       23 #.PHONY:clean              24 #clean:       25 #   rm -rf *.o code

在这里插入图片描述

3. 第三代版本,如果在当前目录下有一百个或一千个源文件呢?怎么保证你的代码写的更加通用呢?

在这里插入图片描述

  • 既然源文件从一个变成了100个,那赋值给变量也需要进行相应的修改。SRC=code.c$(shell ls *.c),把所有罗列出来的.c文件全部放到SRC里面
  • 如何验证变量SRC里面放置了100个源文件列表呢?用依赖方法:echo $(SRC),打印到显示器上
  • 命令前面带上@符号,可以不用回显命令执行的过程,只显示命令执行的结果
    在这里插入图片描述
  • 想将100个源文件放置到变量SRC也可以:SRC$(wildcard *.c)。这里的wildcard就相当于一个函数,两种用法是等价的
  • 源文件的变量(SRC)发生改变,则对应的OBJ也要发生变化。OBJ=code.oOBJ=$(SRC:.c=.o),这是Makefile自己的语法,要求将SRC所有的源文件的.c换成.o,再赋值给OBJ,这个对于SRC和源文件是没有影响的
    在这里插入图片描述
  • 接着就是依赖关系($(BIN):$(OBJ))+ 依赖方法(gcc $(OBJ) -o $(BIN))。这里的依赖方法还有另外一种写法:gcc $^ -o $@$^$(OBJ)$@$(BIN)
    在这里插入图片描述
  • 根据Makefile的推导原则,当前路径下并没有.o文件,会向下推导。因此要形成.o文件,依赖关系(%.o:%.c)+ 依赖方法($(CC) -c $<
  • 这里的%符号就是Makefile中的通配符,%.o%.c分别匹配所有的.o.c文件。$<就是把%.c中的文件一个一个的拿出来交给对应的命令,再被gcc一个一个的编译成同名.o文件
    在这里插入图片描述
  • 一个依赖关系后面是可以跟多个依赖方法的
    在这里插入图片描述

3. 通用模板代码(可以直接拿来用)

BIN=code #可执行程序    
SRC=$(wildcard *.c)    
#SRC=$(shell ls *.c) #源文件列表放到变量SRC中    
OBJ=$(SRC:.c=.o)    
CC=gcc #编译器    
RM=rm -rf #删除命令    $(BIN):$(OBJ)    @#gcc $(OBJ) -o $(BIN) 虽然加了警号,但不带@,也会进行命令回显    @$(CC) $^ -o $@ #加上@符号不让命令回显    @echo "链接 $^ 成 $@"    
%.o:%.c    @$(CC) -c $<    @echo "编译... $< 成 $@"    .PHONY:clean                                              
clean:                                     @$(RM) $(BIN) $(OBJ)    .PHONY:test    
test:                                                                                                              @echo $(BIN)                            @echo $(SRC) #不会让命令进行回显    @echo $(QBJ)    

Linux 第一个系统程序-进度条(7-3.00.00)

1. 补充回车与换行

在这里插入图片描述

回车和换行是两个动作,回车:先回到开头,换行:新启一行

2. 行缓冲区

通过有没有带\n的变化来引出行缓冲区的存在

#include<stdio.h>    
#include<unistd.h>    int main()    
{    printf("hello world");    sleep(2);    return 0;    
}           
  • 发现了一个现象:当字符串没带\n时,hello world不会立即显示出来。当带了\n则会立即显示出来hello world
  • 程序执行永远是从上至下依次执行,那肯定是先打印(printfhello world,再去sleep,可结果好像是sleep了再打印?
  • 其实printf这条语句已经执行完了,字符串是被存储到了缓冲区(在内存处)中,而printf打印是将字符串打印到显示器上
  • 只不过显示器的刷新策略是:行刷新(带上\n,就会将缓冲区的字符串刷新到显示器上)。不带\n,要么程序结束时进行刷新,要么手动强制进行刷新
  • 手动强制进行刷新,可以用到函数fflush,它的参数类型是FILE*FILE* stdin(键盘)FILE* stdout(显示器),传入参数fflush(stdout)可立即刷新
    在这里插入图片描述
#include<stdio.h>    
#include<unistd.h>    int main()    
{    printf("hello world\n");    sleep(2);    fflush(stdout);    return 0;    
}  

3. 倒计时小程序

  • 光标控制,当向光标所在位置写入一个字符后,光标会自动地向后移动。那就可以先往光标处打印9,再让光标回车到开头显示8,将这个过程循环往复,直至光标处显示0
    在这里插入图片描述
  • 为了解决上面的问题,可以用到回车符(\r),因为显示器的刷新策略,还得进行手动强制刷新:fflush(stdout)
    在这里插入图片描述
  • 但是当程序从两位数开始倒计时(cnt = 10),就会依次打印10,90,80,...。这是因为显示器它只认字符,比如当你往显示器打印1234时,并不是打印整数1234,而是一个字符一个字符的打印1,2,3,4
  • 这也是为啥显示器叫字符设备的缘故,printf("%d\n", 1234)printf打印要对这个整数进行格式化,格式化是将这个整数转成字符再进行输出
  • 所以从两位数倒计时,cnt必须占两个字符(printf("%2d\r", cnt),只不过格式化输出定长控制的时候,不足对应的位置默认是右对齐的(空格在左边),所以2前面得加个负号,就能居左对齐
int main()
{int cnt = 15;while(cnt >= 0){printf("%-2d\r", cnt);fflush(stdout);cnt--;sleep(1);}printf("\n");return 0;
}

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

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

相关文章

【ArcGIS】水文分析与流域划分

【ArcGIS】水文分析与流域划分 一、基础数据处理1、下载数据2、拼接DEM数据3、填充洼地4、流向分析5、流量分析6、河网生成&#xff08;栅格计算器&#xff09;7、河网分级8、河流链接&#xff08;提取子流域的关键&#xff09; 二、多个小流域提取1、捕捉倾泻点2、集水区&…

【C++】简单工厂模式/工厂方法模式/抽象工厂模式对比

目录 一、简单工厂模式&#xff08;Simple Factory Pattern&#xff09;二、工厂方法模式&#xff08;Factory Method Pattern&#xff09;三、抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;四、三者对比总结五、选择建议如果这篇文章对你有所帮助&#xff0c…

博图SCL中CONTINUE语句详解:高效循环控制案例

博图SCL中CONTINUE语句详解&#xff1a;高效循环控制利器 在博图&#xff08;TIA Portal&#xff09;的SCL&#xff08;结构化控制语言&#xff09;编程中&#xff0c;CONTINUE语句是优化循环流程的强大工具。它允许您**跳过当前循环迭代的剩余代码&#xff0c;直接进入下一次…

django HttpResponse 加返回码

在Django框架中&#xff0c;HttpResponse对象是用来构造HTTP响应并将其发送回客户端的。当你创建一个HttpResponse对象时&#xff0c;你可以指定一个返回码&#xff08;或状态码&#xff09;&#xff0c;这是HTTP响应的一部分&#xff0c;用来表示请求的处理结果。状态码是三位…

【俄语图片文字识别】批量识别俄语图片文字,识别俄语图片文字的操作步骤和注意事项

场景&#xff1a;在俄语学习&#xff0c;俄语工作中经常遇到一些文字图片&#xff0c;如何将韩语图片文字从图片上扣下来&#xff0c;我们可以直接复制粘贴&#xff0c;提高我们的工作效率 我们会用到一款小工具&#xff1a; 软件操作步骤&#xff1a; 第一步、打开软件 第二…

关于AB PLC的ethernet/IP 通信 c++搭建

1.下载开源的libplctag库 2.通过Cmake-gui生成工程文件 3.编译生成对应的Debug 4.配置VS studio 源码 #include "libplctag.h" #include <cstring> #include <iostream> #include <thread> int main() { plc_tag_set_debug_level(PLCTAG_DEB…

实验分享|自研局部DIC-GPU算法与开源GPU算法对比实验

1实验背景 数字图像相关法DIC是材料力学领域研究的关键技术&#xff0c;其中局部DIC凭借亚像素级精度、全场测量等优势&#xff0c;成为材料局部变形分析的优选方案。传统CPU计算难以应对局部DIC数万个子区并行计算需求&#xff0c;新兴GPU算法一定程度提高了计算效率&#xf…

P2066 机器分配

P2066 机器分配 - 洛谷 题目描述 总公司拥有高效设备M台&#xff0c;准备分给下属的N个分公司。各分公司若获得这些设备&#xff0c;可以为国家提供一定的盈利。问&#xff1a;如何分配这M台设备才能使国家得到的盈利最大&#xff1f;求出最大盈利值。其中M⩽15&#xff0c;N…

Vue 复制页面内容

方法 1&#xff1a;使用 document.execCommand(copy) 在用户触发的事件中 这种方法适用于用户触发的事件&#xff08;如点击按钮&#xff09;&#xff0c;因为这是 execCommand(copy) 的唯一允许场景。 <template><button click"copyToClipboard">复制…

暑期前端训练day1

js——记忆函数 2025-06-19 day1 一、记忆函数Ⅰ&#xff1a; 链接&#xff1a;https://leetcode.cn/problems/memoize/?envTypeproblem-list-v2&envIdGR5hbGen (1) 题意&#xff1a;给定一个函数&#xff0c;返回一个记忆版的函数&#xff0c;其中你只会包含三个可能输…

鸿蒙网络编程系列54-仓颉版实现Smtp邮件发送客户端

1. SMTP邮件发送客户端 在本系列的第4篇文章《鸿蒙网络编程系列4-实现SMTP邮件发送客户端》中&#xff0c;基于ArkTS语言在API9环境下使用TCPSocket对象演示了SMTP客户端的实现&#xff0c;并且通过腾讯邮件服务器执行了实际的邮件发送。不过&#xff0c;在2024年末&#xff0…

【慧游鲁博】【12】UI美化·图标选择与变换·动态交互·格式定义

文章目录 图标设计迭代过程初始版本问题分析优化措施 游览画卷美化原因当前效果展示美化步骤(1) 代码修改结构优化CSS&#xff08;优化样式&#xff09; (2) 图标选择&#xff08;4种方案&#xff09;(3) 交互优化 版本一版本二1. 修改HTML结构2. 新增CSS样式色彩控制技术性能优…

IMU介绍

IMU(Inertial Measurement Unit,惯性测量单元)是一种基于惯性原理的传感器,通过测量物体的加速度和角速度来获取运动状态信息。以下从技术原理、核心组件、应用场景及关键指标等方面展开详细解析: 一、IMU的技术原理与核心组件 1. 工作原理 惯性力学基础:利用牛顿第二定…

MOS管和比较器

目录 前言一、前置器件复习使用1.比较器工作特性2.光电二极管3.红外出水水龙头4.温控风扇工作原理 二、MOS管1.前置1.1 增强型MOS管1.2 耗尽型MOS管1.3 四种1.4 比较 2.基本结构3.导通条件4.开关电路的设计方法5.寄生电容问题6.寄生二极管不能忽略7.Nmos管做电源开关的注意事项…

从代码学习深度强化学习 - Double DQN PyTorch版

文章目录 前言理论篇:为什么需要 Double DQN?代码实现篇:构建一个 Double DQN 智能体2.1 项目设置与辅助函数2.2 环境 (Environment)2.3 DQN 的核心组件2.3.1 Replay Buffer (经验回放池)2.3.2 Q-Network (Q网络)2.3.3 The Double DQN Agent (Double DQN 智能体)训练与结果3…

四非鼠鼠计算机专业的保研分享

四非鼠鼠的计算机专业保研分享 1.前言 鼠鼠的本科学校是一所不怎么出名的四非院校&#xff0c;专业是计算机科学与技术。在写下这篇文章时&#xff0c;鼠鼠并不是为了炫耀什么&#xff0c;而是想把自己在保研路上的一些踩坑经历分享出来&#xff0c;尤其是写给那些和我一样&a…

【C++详解】STL-vector使用底层剖析和实现

文章目录 vector介绍vector和string的区别补充知识initializer_listemplace_back结构化绑定 vector的使用构造析构遍历修改insertfind流插入/流提取vector\<vector>(杨辉三角) vector模拟实现浅品STL源码构造函数拷贝构造多参数构造迭代器区间构造n个val初始化swapoperat…

MySql升级安装、socket 及密码重置

升级 项目需要使用Mysql8.0, 查看自己的ubuntu22.04上mysql版本为5.7&#xff0c; 使用以下命令自动升级到8.0版本。 sudo apt install Mysqlsock错误&#xff1a; Can’t connect to local MySQL server through socket 运行mysql -u -p 报以下错误&#xff1a; ERROR 200…

Python网络爬虫技术:从入门到实战

在当今数字化时代&#xff0c;网络爬虫技术已经成为数据挖掘和信息收集的重要工具。通过网络爬虫&#xff0c;我们可以高效地从互联网上获取大量有价值的数据&#xff0c;用于数据分析、市场研究、学术研究等多种场景。本文将带你从零开始&#xff0c;了解Python网络爬虫的基本…

偏微分方程初值问题求解

题目 问题 2. (a) u t + 3 u x − 2 u y = x ; u t + x u x + y u y = x ; u_t + 3u_x - 2u_y = x; \quad u_t + xu_x + yu_y = x; ut​+3ux​−2uy​=x;ut​+xux​+yuy​=x; u t + x u x − y u y = x ; u t + y u x + x u y = x ; u_t + xu_x - yu_y = x; \quad u_t + yu_…