(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,先运行 处代码,然后运行 B 处代码休眠
:

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

这里是休眠了2s后,才出现的hello world。怎么说???
看样子是先执行 B 再执行 了,but……
然而实际上,无论你加不加 \n,代码都是从上往下先运行的,即先执行 printf 再执行 sleep!
代码没有任何的循环判断跳转什么的操作,那一定是 从上到下按顺序执行的,要坚信自己!
这就是所谓的 "顺序结构",也是我们的默认结构。
既然是从上到下按顺序执行,可是我们运行代码观察到的现象就是 sleep 先休眠 然后打印啊。
真像:实际上,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都是小绿点会很加分的!
相关文章:
(9)Linux Git的介绍以及缓冲区
💭 前言 本章我们先对缓冲区的概念进行一个详细的探究,之后会带着大家一步步去编写一个简陋的 "进度条" 小程序。最后我们来介绍一下 Git,着重讲解一下 Git 三板斧,一般只要掌握三板斧就基本够用了。 缓冲区ÿ…...
华为云之ECS云产品快速入门
华为云之ECS云产品快速入门 一、ECS云服务器介绍二、本次实践目标三、创建虚拟私有云VPC1.虚拟私有云VPC介绍2.进入虚拟私有云VPC管理页面3.创建虚拟私有云4.查看创建的VPC 四、创建弹性云服务器ECS——Linux1.进入ECS购买界面2.创建弹性云服务器(Linux)——基础配置步骤3.创建…...
tcp 的限制 (TCP_WRAPPERS)
#江南的江 #每日鸡汤:青春是打开了就合不上的书,人生是踏上了就回不了头的路,爱情是扔出了就收不回的赌注。 #初心和目标:拿到高级网络工程师 TCP_WRAPPERs Tcp_wrappers 对于七层模型中是位于第四层的安全工具,他…...
如何保证架构的质量
1. 如何保证架构的质量: ①. 稳定性、健壮性(1). 系统稳定性: ①. 定义:a. 当一个实际的系统处于一个平衡的状态时,如果受到外来作用的影响时,系统经过一个过渡过程仍然能够回到原来的平衡状态.b. 可以说这个系统是稳定的,否则系统不稳定c. 如一根绳子绑着小球,处于垂直状态,…...
JavaWeb笔记之前端开发JavaScript
一、引言 1.1 简介 JavaScript一种解释性脚本语言,是一种动态类型、弱类型、基于原型继承的语言,内置支持类型。 它的解释器被称为JavaScript引擎,作为浏览器的一部分,广泛用于客户端的脚本语言,用来给HTML网页增加…...
SCAU:18063 圈中的游戏
18063 圈中的游戏 时间限制:1000MS 代码长度限制:10KB 提交次数:0 通过次数:0 题型: 编程题 语言: G;GCC;VC Description 有n个人围成一圈,从第1个人开始报数1、2、3,每报到3的人退出圈子。编程使用链表找出最后留下的人。输入格式 输入一个数n&a…...
.NET Core中鉴权 Authentication Authorization
Authentication: 鉴定身份信息,例如用户有没有登录,用户基本信息 Authorization: 判定用户有没有权限 使用框架提供的Cookie鉴权方式 1.首先在服务容器注入鉴权服务和Cookie服务支持 services.AddAuthentication(options > {options.DefaultAuthe…...
PyTorch深度学习实战(26)——卷积自编码器(Convolutional Autoencoder)
PyTorch深度学习实战(26)——卷积自编码器 0. 前言1. 卷积自编码器2. 使用 t-SNE 对相似图像进行分组小结系列链接 0. 前言 我们已经学习了自编码器 (AutoEncoder) 的原理,并使用 PyTorch 搭建了全连接自编码器,但我们使用的数据…...
Milvus实战:构建QA系统及推荐系统
Milvus简介 全民AI的时代已经在趋势之中,各类应用层出不穷,而想要构建一个完善的AI应用/系统,底层存储是不可缺少的一个组件。 与传统数据库或大数据存储不同的是,这种场景下则需要选择向量数据库,是专门用来存储和查…...
使用Docker部署Nexus Maven私有仓库并结合Cpolar实现远程访问
文章目录 1. Docker安装Nexus2. 本地访问Nexus3. Linux安装Cpolar4. 配置Nexus界面公网地址5. 远程访问 Nexus界面6. 固定Nexus公网地址7. 固定地址访问Nexus Nexus是一个仓库管理工具,用于管理和组织软件构建过程中的依赖项和构件。它与Maven密切相关,可…...
GEE-Sentinel-2月度时间序列数据合成并导出
系列文章目录 第一章:时间序列数据合成 文章目录 系列文章目录前言时间序列数据合成总结 前言 利用每个月可获取植被指数数据取均值,合成月度平均植被指数,然后将12个月中的数据合成一个12波段的时间数据合成数据。 时间序列数据合成 代码…...
【深度学习】语言模型与注意力机制以及Bert实战指引之二
文章目录 前言 前言 这一篇是bert实战的完结篇,准备中。...
计算机网络 网络层下 | IPv6 路由选择协议,P多播,虚拟专用网络VPN,MPLS多协议标签
文章目录 5 IPv65.1 组成5.2 IPv6地址5.3 从IPv4向IPv6过渡5.3.1 双协议栈5.3.2 隧道技术 6 因特网的路由选择协议6.1 内部网关协议RIP6.2 内部网关协议 OSPF基本特点 6.3 外部网关协议 BGP6.3.1 路由选择 6.4 路由器组成6.4.1 基本了解6.4.2 结构 7 IP多播7.1 硬件多播7.2 IP多…...
【MATLAB第83期】基于MATLAB的LSTM代理模型的SOBOL全局敏感性运用
【MATLAB第83期】基于MATLAB的LSTM代理模型的SOBOL全局敏感性运用 引言 在前面几期,介绍了敏感性分析法,本期来介绍lstm作为代理模型的sobol全局敏感性分析模型。 【MATLAB第31期】基于MATLAB的降维/全局敏感性分析/特征排序/数据处理回归问题MATLAB代…...
求奇数的和 C语言xdoj147
题目描述:计算给定一组整数中奇数的和,直到遇到0时结束。 输入格式:共一行,输入一组整数,以空格分隔 输出格式:输出一个整数 示例: 输入:1 2 3 4 5 0 6 7 输出:9 #inclu…...
全链路压力测试:解析其主要特点
随着信息技术的飞速发展和云计算的普及,全链路压力测试作为一种关键的质量保障手段,在软件开发和系统部署中扮演着至关重要的角色。全链路压力测试以模拟真实生产环境的压力和负载,对整个业务流程进行全面测试,具有以下主要特点&a…...
算法基础之约数个数
约数个数 核心思想: 用哈希表存每个质因数的指数 然后套公式 #include <iostream>#include <algorithm>#include <unordered_map>#include <vector>using namespace std;const int N 110 , mod 1e9 7;typedef long long LL; //long l…...
【ECharts】折线图
文章目录 折线图1折线图2折线图3示例 参考: Echarts官网 Echarts 配置项 折线图1 带X轴、Y轴标记线,其中X轴是’category’ 类目轴,适用于离散的类目数据。 let myChart echarts.init(this.$refs.line_chart2); let yList [400, 500, 6…...
java jdbc连接池
什么是连接池: Java JDBC连接池是一个管理和分配数据库连接的工具。在Java应用程序中,连接到数据库是一个耗时且资源密集的操作,而连接池可以通过创建一组预先初始化的数据库连接,然后将其保持在连接池中,并按需分配给…...
unity2d 关闭全局重力
UNITY2D项目默认存在Y轴方向重力,创建俯视角2D场景时可通过以下配置关闭 Edit > Project Settings > Physics 2D > General Settings > Gravity 设置Y0...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...
从零手写Java版本的LSM Tree (一):LSM Tree 概述
🔥 推荐一个高质量的Java LSM Tree开源项目! https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree,专为高并发写入场景设计。 核心亮点: ⚡ 极致性能:写入速度超…...
可下载旧版app屏蔽更新的app市场
软件介绍 手机用久了,app越来越臃肿,老手机卡顿成常态。这里给大家推荐个改善老手机使用体验的方法,还能帮我们卸载不需要的app。 手机现状 如今的app不断更新,看似在优化,实则内存占用越来越大,对手机性…...
Go 并发编程基础:select 多路复用
select 是 Go 并发编程中非常强大的语法结构,它允许程序同时等待多个通道操作的完成,从而实现多路复用机制,是协程调度、超时控制、通道竞争等场景的核心工具。 一、什么是 select select 类似于 switch 语句,但它用于监听多个通…...
