(9)Linux Git的介绍以及缓冲区

💭 前言

本章我们先对缓冲区的概念进行一个详细的探究,之后会带着大家一步步去编写一个简陋的 "进度条" 小程序。最后我们来介绍一下 Git,着重讲解一下 Git 三板斧,一般只要掌握三板斧就基本够用了。

缓冲区(Buffer)

先说一下 unistd.h 库中的 sleep 函数,它可以按照秒去休眠

我们先创建一个文件,并写一些代码:

#include <stdio.h>
#include <unistd.h>
 
int main(void) {
    printf("Helo,World!\n");  
    sleep(2);                 
 
    return 0;
} 

??这里是先运行printf还是sleep???

这还用思考?肯定打出 Helo, World,先运行A 处代码,然后运行 B 处代码休眠 2s

如果说:我们把\n给删了呢?

这里是休眠了2s后,才出现的hello world。怎么说???

 看样子是先执行 B 再执行 A 了,but……

然而实际上,无论你加不加 \n,代码都是从上往下先运行的,即先执行 printf 再执行 sleep!

代码没有任何的循环判断跳转什么的操作,那一定是 从上到下按顺序执行的,要坚信自己!

这就是所谓的 "顺序结构",也是我们的默认结构。

既然是从上到下按顺序执行,可是我们运行代码观察到的现象就是 sleep 先休眠 2s 然后打印啊。

真像:实际上,printf 已经先执行了,只是这个 "Helo,World" 没有立马被显示出来罢了!

当我们 sleep 时也没有显示,当我们 sleep 完甚至到程序退出后,这个 "Helo,World" 才显示出来。

这个时候如果打印的消息如果没有立即被显示出来,

在 sleep 执行期间它最后显示出来证明了它的存在,

但是 sleep 2s 内它并没有显示出来,那么问题来了 —— 这个 "Helo,World" 在哪?
没错,这就是就是  " 缓冲区 " !

对缓冲区的理解

什么是缓冲区?这个缓冲区在哪里?缓冲区其实说白了,就是一段内存空间。

既然是内存空间,那我们就能理解刚才举的例子里的 "Helo,World" 数据是放在了内存空间里。

只要在内存里就没有打印出来,所以我们 sleep 2s 时它一直在内存里 "躺平" 呢。

最后 return 退出的时候,这个数据才显示出来,所以才看到了我们刚才看到的现象

缓冲区的理解:就是一段内存空间。立马将内存中的空间显示出来 →刷新策略 

我们今天不探讨什么策略,就往显示器打印这个点来说,我们只关注一种策略 —— 行刷新 !

所谓的行刷新,就是你要输出的一个行字符串当中,看它是不是一个完整行,

如果是一个完整行,就会立马刷新出来;如果不是,就不刷新,让它去缓冲区一边凉快去,

等缓冲区变满了或者程序退出了,再或者碰到换行服务,再把它一块送出去。

那么,如何证明你一个文本是完整的一行呢?

这也很简单,只要你打印的内容包含 \n,包含反斜杠 n 在内的之前的所有内容成为一行。

不是直接把数据刷到我们外设上, 还是把数据先放到缓冲区里,只不过因为你有 \n,

它就立马根据刷新策略,把内容给你刷新出来,仅此而已。

如果我不想用 \n,我就想让我的数据立马刷新出去(立马显示出来)呢?

这里就说来话长了,我们不得不说一下 stdin、stdout 和 stderr 的知识。

 一般一个程序默认在启动的时候会默认打开三个输入输出流:

#include <stdio.h>
 
extern FILE* stdin;
extern FILE* stdout;
extern FILE* stderr;

 如何刷新呢?我们还可以通过 fflush() 去强制刷新:

#include <stdio.h>
 
int fflush(FILE* stream);

 如果你仔细观察你会发现它的参数和我们 stdin、stdout 和 stderr 类型是一样的,都是 FILE*

在没有 \n 时,我们通过 fflush 让它打印完立马给我刷新: 

运行结果如下:

 

此时的Hello world!是立刻就显示出来了。

实现一个简易 "进度条"

在实现简易 "进度条" 之前,我们还需要讲解一下回车和换行的概念。

思考:你认为回车和换行是一个概念吗?

  • 回车:将光标拨回到当前行的最开始(最左侧)
  • 换行:新起一行(并不影响光标的位置)

我们所理解的 "换行"  并不是这里的换行,想达到我们所理解的 "换行" 效果,

即新起一行并将光标拨回最开始位置,就需要:

先模拟 "倒计时"

代码演示:从 9 开始倒计时

运行结果:

由9一直倒数

开始实现简易进度条

 我们先创建一个空文件夹,并创建一个 process.c 文件:

然后我们形成一个 Makefile 文件:

然后我们打开刚才创建的 process.c 文件,我们实现出 '#' 的填充部分:

定义一个 process() 函数,用于实现进度条。我们假设 100 个单位,定义一个宏 TIMES 表示,然后创建 bar 数组存放,因为最后要存 \0 所以这里我们需要多预留一个位置给它,所以定义一个 TIMES+1 的宏,名曰 NUM。为了方便,我们索性使用 memset 将所有缓冲区空间设置为 \0。

然后开始我们的计数操作,创建一个 cnt 变量 while 它个 100 下,每次打印 bar 中的 1 个,然后用 # 填充 cnt 对应位置的 bar 元素。
运行结果如下:

emm,现在显然有两个问题亟待解决:

  • sleep 一秒,这是打印地是否有些太慢……
  • 这个进度条是否有些奇葩,哪有换行打的进度条雾草,太摩登了

我们先来解决第一个问题,看看 usleep 函数 

按照微秒为单位去休眠,我们 usleep(20000) ,能让它 2 秒内跑完。

20000μs=20ms=0.02s

然后我们刚才还讲解缓冲区概念,的时候还介绍了 fflush()  和 \r,在这里就派上用场了。

和刚才的倒计时一样,这里换行的主要原因还是我们 printf 用了 \n,我们修改一下写的代码:

运行结果如下:

 

不错,有个进度条的样子了。但好像没有给进度条预留一块空间啊,

现在的进度条是带着 [ ] 直接往后怼的,我们可以给 [ ] 预留 100 个 字符空间:

printf("[%100s]\r", bar);

虽然给 [ ] 预留空间了,但是是从右往左反过来打的。

为什么会这样呢?因为 C 语言默认的对齐方式是右对齐的,如果想让它左对齐,就要加 -

printf("[%-100s]\r", bar);

 

下面我们来加上 "百分比"

百分比不就是我们定义的 cnt 变量么?我们打印出来就行:

printf("[%-100s] [%d %%]\r", bar, cnt);

 

最后,我们再实现一下 "不断旋转的光标",就大功告成了。

想做到不断旋转的视觉效果,通过   | / - \ 这四个符号不断变化即可。

由于 \ 需要用转义才能表示,所以需要 \\ ,我们把它们存到变量中。

打印时,访问我们定义的变量即可,这里将  cnt % 4 就可以按顺序循环访问这四个字符了。

/* 不断旋转的光标:   | / - \   */
  const char* lable = "|/-\\";
 
  int cnt = 0;
  while (cnt <= TIMES) {
    printf("[%-100s] [%d%%] ... %c\r", bar, cnt, lable[cnt % 4]);  // 改成\r

运行结果如下:

翻过这座山,我们是------冠军!!!!!!!!!

Git 简单介绍

git 是什么?

git是一种代码管理器,写git程序的和写Linux系统的是同一个人,所以Linux可以直接和gitee或GitHub相关联!

GitHub: Let’s build from here · GitHub

Gitee - 基于 Git 的代码托管和研发协作平台

 这里使用gitee举例子:先在远端创建仓库

合法的

(我敲~这个为什么是倒着的啊???)

Linux下的gitee创建仓库

在创建好仓库后,复杂https的链接

使用指令: git clone 链接

即可将远端仓库克隆到本地
接下来的操作和Windows上的三板斧相似:

首先在本地仓库创建一份文件:

注意:是在本地仓库里面创建的。

git三板斧之add

 我们在当前目录下直接输入指令:

git add 文件名 或 git add .

前者是添加特定的文件到本地仓库
后者是将当前目录下所有文件提交

输入完这条指令后,文件就已经被添加到本地仓库了

那么怎样在本地仓库查看有哪些文件呢?

使用指令: git status

 

可以发现,本地仓库中还有test.c。没有被提交到远端仓库!

git三板斧之commit

请注意,在commit时一定要输入日志

 使用指令: git commit -m "日志"

日志一定不要乱写!
日志一定不要乱写!
日志一定不要乱写!
 

你的gitee或GitHub,就会去看日志! 

比如这里我可以这样写日志:、

输入此指令后,如果你是第一次输入,系统可能会让你输入邮箱和用户名密码,这时系统会将指令的格式给你显示出来,你只需要将格式中引号内的内容改成你的自己的邮箱或用户有即可!

或者你也可以事先输入好

user代表用户,.name代表配置用户的名称

git config --global user.name "你的用户名"

user代表用户,.email代表配置用户的邮箱

git config --global user.email "你的邮箱"

 这样就好了

git三板斧之push

在commit输入完日志后,输入指令:

git push 

将本地仓库的文件推送至远端仓库!

输入这条指令后,会显示这样的画面:

注:账号最好是输入下面红框里的:

我们登录gitee就会看到:

最后:

大家要维护好自己的gitee或GitHub
一年都百分之80都是小绿点会很加分的!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis权限管理体系(三): ACL 配置持久化

点击上方蓝字关注我 前面我们已经了解了ACL用户管理的用途及使用&#xff1a; Redis权限管理体系(一&#xff09;&#xff1a;客户端名及用户名 Redis权限管理体系(二&#xff09;&#xff1a;终于等来了Redis权限控制体系ACL 但因默认配置中ACL的配置未持久化&#xff0c;因此…

oracle怎样才算开启了内存大页?

oracle怎样才算开启了内存大页&#xff1f; 关键核查下面三点&#xff1a; 1./etc/sysctl.conf vm.nr_hugepages16384这是给了32G&#xff0c;计划sga给30G&#xff0c;一般需多分配2-4G sysctl -p生效 看cat /proc/meminfo|grep Huge啥结果&#xff1f; 这种明显是配了…

Go项目快速集成Swagger UI

swag Swag将Go的注释转换为Swagger2.0文档。我们为流行的 Go Web Framework 创建了各种插件&#xff0c;这样可以与现有Go项目快速集成&#xff08;使用Swagger UI&#xff09;。 目录 快速开始支持的Web框架如何与Gin集成格式化说明开发现状声明式注释格式 通用API信息API操…

【每日一题】【12.20】2828.判别首字母缩略词

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 1.题目链接 2828. 判别首字母缩略词https://leetcode.cn/problems/check-if-a-string-is-an-acronym-of-words/ 2.题目描述 今天…

RTDETR论文快速理解和代码快速实现(训练与预测)

文章目录 前言一、摘要二、论文目的三、论文贡献四、模型结构1、模型整体结构2、backbone结构3、neck结构4、混合编码器(neck) 五、RTDERT模型训练(data-->train)1、环境安装2、训练1、数据准备2、数据yaml文件3、训练代码4、训练运行结果 3、推理1、推理代码2、推理运行结果…

Nginx快速入门:安装目录结构详解及核心配置解读(二)

0. 引言 上节我们讲解了nginx的应用场景和安装&#xff0c;本节继续针对nginx的各个目录文件进行讲解&#xff0c;让大家更加深入的认识nginx。并通过一个实操案例&#xff0c;带大家来实际认知nginx的核心配置 1. nginx安装目录结构 首先nginx的默认安装目录为&#xff1a;…

原子学习笔记3——使用tslib库

一、tslib介绍 tslib 是专门为触摸屏设备所开发的 Linux 应用层函数库&#xff0c;并且是开源。 tslib 为触摸屏驱动和应用层之间的适配层&#xff0c;它把应用程序中读取触摸屏 struct input_event 类型数据&#xff08;这是输入设备上报给应用层的原始数据&#xff09;并进行…

Elasticsearch常见面试题

文章目录 1.简单介绍下ES&#xff1f;2.简单介绍当前可以下载的ES稳定版本&#xff1f;3.安装ES前需要安装哪种软件&#xff1f;4.请介绍启动ES服务的步骤&#xff1f;5.ES中的倒排索引是什么&#xff1f;6. ES是如何实现master选举的&#xff1f;7. 如何解决ES集群的脑裂问题8…

SpringBoot-XXLJOB提供动态API调度任务

目录 一、项目版本 二、XXL-JOB提供动态API controller层 service层 三、SpringBoot项目 pom model XxlJobUtil-工具类 XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线&…

Gateway网关-网关的cors跨域配置

目录 一、跨域 二、解决方案 三、实际测试 3.1 html调用接口 3.2 跨域问题复现 3.3 application文件中配置CORS 3.4 问题解决 一、跨域 跨域问题&#xff1a;浏览器禁止请求的发起者与服务端发生跨域ajax请求&#xff0c;请求被浏览器拦截的问题 跨域&#xff1a;…

第四节TypeScript 声明变量

1、typescript变量声明 变量是一种使用方便的占位符&#xff0c;用于引用计算机内存地址。 我们可以把变量看做存储数据的容器。 typescript变量的命名规则&#xff1a; 变量名称可以包含数字和字母。除了下划线_和美元$符号外&#xff0c;不能包含其它特殊字符&#xff0c…

基于Alpha-Beta剪枝树的井字棋人机博弈系统的实现

这篇文章讨论了算法的基本概念与特性&#xff0c;并介绍了五种常见的算法类型&#xff1a;分治法、动态规划、贪心算法、回溯法和分支限界法。文章以井字棋博弈中的Alpha-Beta剪枝树作为示例&#xff0c;详细解释了该算法的应用和原理。Alpha-Beta剪枝树是一种用于实现游戏AI的…

Python数据加密:保障信息安全的最佳实践

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 随着信息技术的发展&#xff0c;数据安全成为越来越重要的议题。在Python中&#xff0c;有多种方法可以用于数据加密&#xff0c;以确保敏感信息在传输和存储过程中不被泄露或篡改。本文将详细介绍Python中数据加…

智能优化算法应用:基于梯度算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于梯度算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于梯度算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.梯度算法4.实验参数设定5.算法结果6.参考文献7.MA…

服务器数据恢复-EMC存储raid5磁盘物理故障离线的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 一台emc某型号存储服务器&#xff0c;存储服务器上组建了一组raid5磁盘阵列&#xff0c;阵列中有两块磁盘作为热备盘使用。存储服务器在运行过程中有两块磁盘出现故障离线&#xff0c;但是只有一块热备盘激活&#xff0c;最终导致该ra…

文件操作入门指南

目录 一、为什么使用文件 二、什么是文件 2.1 程序文件 2.2 数据文件 2.3 文件名 三、文件的打开和关闭 3.1 文件指针 3.2 文件的打开和关闭 四、文件的顺序读写 ​编辑 &#x1f33b;深入理解 “流”&#xff1a; &#x1f342;文件的顺序读写函数介绍&#xff1a; …

系列十四(面试)、谈谈你对StackOverflowError的理解?

一、StackOverflowError 1.1、概述 StackOverflowError是栈内存溢出的意思。栈中主要存储的是8种基本数据类型 引用类型 实例方法&#xff0c;栈的空间也是有限的&#xff0c;当存储进栈中的容量大于栈的最大容量时&#xff0c;就会报StackOverflowError的错误。 1.2、案例 …

如何入门 GPT 并快速跟上当前的大语言模型 LLM 进展?

入门GPT 首先说第一个问题&#xff1a;如何入门GPT模型&#xff1f; 最直接的方式当然是去阅读官方的论文。GPT模型从2018年的GPT-1到现在的GPT-4已经迭代了好几个版本&#xff0c;通过官方团队发表的论文是最能准确理清其发展脉络的途径&#xff0c;其中包括GPT模型本身和一…

最详细手把手教你安装 Vivado2017.4

软件下载 官网可下载各个版本 百度网盘链接 Vivado2017.4 License 软件安装 解压缩安装包&#xff0c;双击运行安装程序 xsetup.exe&#xff1a; 忽略软件更新&#xff0c;点击 Continue&#xff1a; 点击 Next&#xff1a; 全部勾选 I Agree&#xff0c;点击 Next&#x…

从0到1打造一款WebStyle串口调试工具

Tip&#xff1a;No Ego Some programmers have a huge problem: their own ego. But there is no time for developing an ego. There is no time for being a rockstar. Who is it who decides about your quality as programmer? You? No. The others? Probably. But can …