做网站必须要公司才能做吗,天水网站建设惠普,wordpress不能自定义,简单做动画的网站#x1f4a1;Yupureki:个人主页 ✨个人专栏:《C》 《算法》《Linux系统编程》 #x1f338;Yupureki#x1f338;的简介: 目录 1. make/makefile 1.1 makefile基本语法 1.2 使用变量 1.3 伪目标 1.4 自动变量 1.5 基本用法 2. 第一个Linux程序:进度条 2.1 缓冲区初…Yupureki:个人主页✨个人专栏:《C》 《算法》《Linux系统编程》Yupureki的简介:目录1. make/makefile1.1 makefile基本语法1.2 使用变量1.3 伪目标1.4 自动变量1.5 基本用法2. 第一个Linux程序:进度条2.1 缓冲区初识2.2 进度条1. make/makefile我们在Linux中把源文件编译成可执行程序时需要手动输入命令让gcc/g编译但是这样就很麻烦假如我们有个很大的项目源文件众多一个一个打就很不舒服因此就引入了一个自动化执行命令的工具-makefilemake是 Linux/Unix 环境下一个非常实用的构建自动化工具。它通过读取一个名为Makefile或 makefile的文件自动判断大型程序中哪些部分需要重新编译并执行相应的命令来完成编译、链接等任务。简单来说make 帮助开发者管理项目构建过程避免每次都手动输入冗长的编译命令。1.1 makefile基本语法创建makefile使用touch创建makefile或者Makefile注意:不能带后缀名字只能是makefile或者Makefilemakefile基本语法Makefile 的核心是规则一个规则的基本格式如下目标: 依赖文件列表 TAB 命令目标通常是要生成的文件名也可以是伪目标如clean。依赖文件列表生成目标所依赖的文件多个文件用空格分隔。命令由一到多条 shell 命令组成每条命令前必须有一个 Tab 键开头不能用空格代替。如:test:表示要生成的目标文件test.cpp:表示依赖的文件(生成test需要test.cpp)下面的g test.cpp -o test 表示具体的指令(由你来定)在makefile编写完后在命令行中输入make就自动执行当前目录下的makefile文件内容了推导过程:makefile的推导推导过程自上而下test需要test.o而test.o不存在又需要test.s来创建......以此类推到test.cpp源文件然后从下到上推导1.2 使用变量可以定义变量来简化 Makefile在makefile的前面定义变量然后在具体方法中用$(变量名)来代替在执行的时候可以当作宏替换自动将$(C)替换为了g1.3 伪目标伪目标不代表实际文件用于执行一些特定操作如清理文件。需要用.PHONY声明执行make clean就会执行rm命令。1.4 自动变量make 提供了一些自动变量方便在命令中引用$表示规则中的目标。$表示第一个依赖文件。$^表示所有依赖文件去重。这有两个推导过程第一个推导过程的$^表示所有的依赖文件而hello依赖hello.o和main.o因此自动填入这两个文件。而$表示目标文件因此是hello第二个推导过程的$表示第一个依赖文件就是hello.c1.5 基本用法在命令行中执行make命令时如果不指定目标则默认执行 makefile 中的第一个目标。常用选项make target构建指定的目标如make clean。make -f 文件名指定使用的 Makefile 文件默认是Makefile或makefile。make -n打印出要执行的命令但不实际执行用于调试。make -j N并行执行 N 条命令加快构建速度。2. 第一个Linux程序:进度条2.1 缓冲区初识我们先来观察下面几种现象#include stdio.h #include unistd.h int main() { printf(hello world\n); sleep(3);//Linux中的sleep函数的库文件是unistd.h return 0; }我们发现在程序休息前就打印出了hello world那如果把\n去掉呢?我们发现程序休息前没有打印hello world而在程序结束后打印了那如果在printf后面强制刷新缓冲区会怎么样?我们发现在程序休息前就打印了这是因为我们printf打印hello world时并不是直接往显示器上打而是先存在一个缓冲区只有当满足一定条件时才会刷新而如果字符串带了\n或者\r则不会存在缓冲区内而是直接刷新到显示器上这就是行刷新为什么要设计缓冲区?最主要的原因:减少系统调用提升效率printf最终需要通过系统调用如write将数据发送给内核再由内核驱动显示到终端。系统调用的开销较大涉及上下文切换、权限检查等。如果每次输出一个字符或短字符串都立即执行系统调用那么频繁的调用会严重拖慢程序运行速度。缓冲区的作用将多次小数据合并成一次大数据块再通过一次系统调用发送出去。这样能大幅减少系统调用次数显著提升吞吐量。例如循环输出1000个字符如果每次putchar都立即刷新就需要1000次write而缓冲后可能只需几次甚至一次write。2.2 进度条我们要设计一种动态加载的下载进度条那么我们要先设计一个download函数每秒下载多少数据double total 1024.0;//总共1024MB数据 double speed 1.0;//一定时间内下载1MB数据 void DownLoad() { double current 0; while(current total)//循环知道下载完成 { FlushProcess(total, current);//刷新缓冲区 // 下载代码 usleep(3000); current speed;//一定时间内下载speed个数据 } printf(\ndownload %.2lfMB Done\n, current); }至于刷新我们知道如果不带\r和\n就会写到缓冲区内因此我们带上\r保证一个循环自动更新进度条对于具体的刷新函数我们需要传入一共要下载多少的数据和当前下载了多少数据进行比例计算这样不仅能以百分比显示下载进度还能计算填充多大的进度条void FlushProcess(double total, double current)//一共要下载多少数据现在下载了多少 { char buffer[NUM]; memset(buffer, 0, sizeof(buffer)); const char *lable|/-\\; int len strlen(lable); static int cnt 0; // 不需要自己循环,填充# int num (int)(current*100/total); // 11.0 / 1000(比例计算) int i 0; for(; i num; i) { buffer[i] STYLE;(根据比例填充进度条) } double rate current/total; cnt % len; printf([%-100s][%.1f%%][%c]\r, buffer, rate*100, lable[cnt]); cnt; fflush(stdout); }到了具体的main函数只需要调用download函数即可int main() { DownLoad(); DownLoad(); DownLoad(); DownLoad(); DownLoad(); DownLoad(); DownLoad(); DownLoad(); return 0; }测试: