??爆笑教程,只送有緣人????《看表情包學Linux》
?? 寫在前面:本章我們先對緩沖區(qū)的概念進行一個詳細的探究,之后會帶著大家一步步去編寫一個簡陋的?"進度條" 小程序,過程還是挺有意思的,雖然實現(xiàn)的過程表現(xiàn)得非常沙雕,但它是本 Linux 專欄中第一個小程序。在講解進度條的實現(xiàn)之前還會講解一下?"回車和換行" 的區(qū)別。最后我們來介紹一下 Git,著重講解一下 Git 三板斧,一般只要掌握三板斧就基本夠用了。
?本篇博客全站熱榜排名:未上榜
Ⅰ. 緩沖區(qū)(Buffer)
0x00 引入:發(fā)現(xiàn) "緩沖區(qū)" 的存在
先說一下?unistd.h 庫中的 sleep 函數(shù),它可以按照秒去休眠:
?? 代碼演示:
#include <stdio.h>
#include <unistd.h>
int main(void) {
printf("Helo,World!\n");
sleep(2);
return 0;
}
? 思考:首先運行的是 ??處的代碼,還是 ?處的代碼?
這還用思考?肯定打出 Helo, World,先運行?處代碼,然后運行??處代碼休眠 :
競猜環(huán)節(jié)!如果我們把 Helo,World 后面的 \n 給去掉,此時是先執(zhí)行??還是先執(zhí)行???
?看樣子是先執(zhí)行??再執(zhí)行??了,but……
然而實際上,無論你加不加 \n,代碼都是從上往下先運行的,即先執(zhí)行 printf 再執(zhí)行 sleep!
代碼沒有任何的循環(huán)判斷跳轉什么的操作,那一定是 從上到下按順序執(zhí)行的,要堅信自己!
這就是所謂的 "順序結構",也是我們的默認結構。
既然是從上到下按順序執(zhí)行,可是我們運行代碼觀察到的現(xiàn)象就是 sleep 先休眠??然后打印啊。
?怎么肥事?。。。?/p>
" 呵呵,printf 已經執(zhí)行了,但是數(shù)據還沒有刷新出來。"
?? 真像:實際上,printf 已經先執(zhí)行了,只是這個?"Helo,World" 沒有立馬被顯示出來罷了!
當我們 sleep 時也沒有顯示,當我們 sleep 完甚至到程序退出后,這個?"Helo,World"?才顯示出來。
這個時候如果打印的消息如果沒有立即被顯示出來,
在 sleep 執(zhí)行期間它最后顯示出來證明了它的存在,
但是 sleep ?內它并沒有顯示出來,那么問題來了 —— 這個 "Helo,World"?在哪?
?難道有什么東西存著它嗎?沒錯!有!這,就是??" 緩沖區(qū) " !
0x01 緩沖區(qū)的理解
?什么是緩沖區(qū)?這個緩沖區(qū)在哪里?緩沖區(qū)其實說白了,就是一段內存空間。
既然是內存空間,那我們就能理解剛才舉的例子里的?"Helo,World" 數(shù)據是放在了內存空間里。
只要在內存里就沒有打印出來,所以我們 sleep??時它一直在內存里 "躺平" 呢。
最后 return 退出的時候,這個數(shù)據才顯示出來,所以才看到了我們現(xiàn)在看到的現(xiàn)象:
緩沖區(qū)的理解:就是一段內存空間。立馬將內存中的空間顯示出來??刷新策略?
我們今天不探討什么策略,就往顯示器打印這個點來說,我們只關注一種策略 —— 行刷新?!
所謂的行刷新,就是你要輸出的一個行字符串當中,看它是不是一個完整行,
如果是一個完整行,就會立馬刷新出來;如果不是,就不刷新,讓它去緩沖區(qū)一邊涼快去,
等緩沖區(qū)變滿了或者程序退出了,再或者碰到換行服務,再把它一塊送出去。
那么,如何證明你一個文本是完整的一行呢?
這也很簡單,只要你打印的內容包含 \n,包含反斜杠 n 在內的之前的所有內容成為一行。
不是直接把數(shù)據刷到我們外設上, 還是把數(shù)據先放到緩沖區(qū)里,只不過因為你有 \n,
它就立馬根據刷新策略,把內容給你刷新出來,僅此而已。
? 如果我不想用 \n,我就想讓我的數(shù)據立馬刷新出去(立馬顯示出來)呢?
這里就說來話長了,我們不得不說一下 stdin、stdout 和 stderr 的知識。
? 一般一個程序默認在啟動的時候會默認打開三個輸入輸出流:
#include <stdio.h>
extern FILE* stdin;
extern FILE* stdout;
extern FILE* stderr;
如何刷新呢?我們還可以通過 fflush() 去強制刷新:
#include <stdio.h>
int fflush(FILE* stream);
如果你仔細觀察你會發(fā)現(xiàn)它的參數(shù)和我們 stdin、stdout 和 stderr 類型是一樣的,都是 FILE*
" 實際上你們所有的 printf 底層打印的都是往 stdout 里丟的 "
在沒有 \n 時,我們通過 fflush 讓它打印完立馬給我刷新:
?? 運行結果如下:
Ⅱ. 實現(xiàn)一個簡易?"進度條"
0x00?回車和換行的概念
?在實現(xiàn)簡易?"進度條" 之前,我們還需要講解一下回車和換行的概念。
? 思考:你認為回車和換行是一個概念嗎?
- 回車:將光標撥回到當前行的最開始(最左側)
- 換行:新起一行(并不影響光標的位置)
我們所理解的 "換行"? 并不是這里的換行,想達到我們所理解的 "換行" 效果,
即新起一行并將光標撥回最開始位置,就需要:
回車 ?換行
?下面我們正式來談一談 "回車 + 換行" 的問題。
回車對應的就是 \r,而我們在 C語言中經常使用的 \n 其實就是 "回車 + 換行"。
0x01?先學會模擬 "倒計時"
為了寫 "進度條",我們先來模擬一下 "倒計時"?
?? 代碼演示:從 9 開始倒計時
#include <stdio.h>
#include <unistd.h>
int main(void) {
int cnt = 9;
while (cnt) {
printf("%d\r", cnt--);
fflush(stdout);
sleep(1);
}
return 0;
}
?? 運行結果演示:
0x02?開始實現(xiàn)簡易進度條
我們想要實現(xiàn)的效果:
我們先創(chuàng)建一個空文件夾,并創(chuàng)建一個?process.c 文件:
$ mkdir process_bar
$ touch process.c
然后我們形成一個 Makefile 文件:
?
process:process.c
gcc -o process process.c
.PHONY:clean
clean:
rm -f process
然后我們打開剛才創(chuàng)建的 process.c 文件,我們實現(xiàn)出 '#' 的填充部分:
定義一個 process() 函數(shù),用于實現(xiàn)進度條。我們假設 100 個單位,定義一個宏 TIMES 表示,然后創(chuàng)建 bar 數(shù)組存放,因為最后要存 \0 所以這里我們需要多預留一個位置給它,所以定義一個 TIMES+1 的宏,名曰 NUM。為了方便,我們索性使用 memset 將所有緩沖區(qū)空間設置為 \0。
然后開始我們的計數(shù)操作,創(chuàng)建一個 cnt 變量 while 它個 100 下,每次打印 bar 中的 1 個,然后用 # 填充 cnt 對應位置的 bar 元素。
然后讓程序睡個一秒再繼續(xù)走循環(huán)判斷。
?? 運行結果如下:
?…… 額,這進度條未免有些沙雕哈,沒關系,這是初始版嘛,很正常 ?????
emm,現(xiàn)在顯然有兩個問題亟待解決:
- sleep 一秒,這是打印地是否有些太慢……
- 這個進度條是否有些奇葩,哪有換行打的進度條霧草,太摩登了。
我們先來解決第一個問題,看看 usleep 函數(shù),問問那個男人:
$ man 3 usleep
按照微秒為單位去休眠,我們 usleep(20000) ,能讓它 2 秒內跑完。
然后我們剛才還講解緩沖區(qū)概念,的時候還介紹了?fflush()? 和 \r,在這里就派上用場了。
和剛才的倒計時一樣,這里換行的主要原因還是我們 printf 用了 \n,我們修改一下寫的代碼:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define TIMES 100
#define NUM TIMES+1
void process() {
char bar[NUM];
memset(bar, '\0', sizeof(bar)); // 將所有緩沖區(qū)空間設置為\0
int cnt = 0;
while (cnt <= TIMES) {
printf("[%s]\r", bar); // 改成\r
fflush(stdout); // 將數(shù)據立馬顯示出來
bar[cnt++] = '#'; // 填充#作為進度圖例
usleep(20000); // 休眠0.02s
}
printf("\n"); // 跑完再讓他換個行
}
int main(void) {
process();
return 0;
}
?? 運行結果如下:
不錯,有個進度條的樣子了。但好像沒有給進度條預留一塊空間啊,
現(xiàn)在的進度條是帶著 [ ] 直接往后懟的,我們可以給 [ ] 預留 100 個 字符空間:
printf("[%100s]\r", bar);
我們來看看效果如何,3,2,1 笑:
哈哈哈哈哈哈,太沙雕了,雖然給 [ ] 預留空間了,但是是從右往左反過來打的。
? 從右往左?阿拉伯兄弟直呼內行!?
為什么會這樣呢?因為 C 語言默認的對齊方式是右對齊的,如果想讓它左對齊,就要加 -
printf("[%-100s]\r", bar);
這下就沒有問題了:
下面我們來加上 "百分比"
百分比不就是我們定義的 cnt 變量么?我們打印出來就行:
printf("[%-100s] [%d %%]\r", bar, cnt);
最后,我們再實現(xiàn)一下 "不斷旋轉的光標",就大功告成了。
?想做到不斷旋轉的視覺效果,通過? ?| / - \ 這四個符號不斷變化即可。
由于 \ 需要用轉義才能表示,所以需要 \\?,我們把它們存到變量中。
打印時,訪問我們定義的變量即可,這里將? cnt % 4 就可以按順序循環(huán)訪問這四個字符了。
/* 不斷旋轉的光標: | / - \ */
const char* lable = "|/-\\";
int cnt = 0;
while (cnt <= TIMES) {
printf("[%-100s] [%d%%] ... %c\r", bar, cnt, lable[cnt % 4]); // 改成\r
?? 運行結果如下:
簡易的進度條就大功告成了 ~
Ⅲ.? Git?介紹
0x00 引入:git 是什么?
Git 是一個分布式版本控制系統(tǒng),它允許多個人在同一個項目中進行協(xié)作。
它允許用戶在開發(fā)過程中跟蹤文件的更改,并在需要時回滾到之前的版本。
這樣可以在團隊協(xié)作開發(fā)時避免沖突,并保證項目的完整性。
0x01 在 Github 創(chuàng)建項目
?點擊 Repositories 進入如下頁面,然后點擊 New:
創(chuàng)建 repository:
在創(chuàng)建好的項目頁面中復制項目的鏈接,以備接下來進行下載:
?創(chuàng)建好倉庫后,如果我想把代碼提交到 git,我們可以把 HTTPS 的內容復制下來。
0x02? git clone?克隆
復制好 url 后,如果想把遠端的倉庫克隆到本地,我們可以用 git clone 指令。
?創(chuàng)建一個放置代碼的目錄:
git clone [url] # 此處的 url 是剛剛建立好的項目的鏈接
第一次的時候會讓你輸入賬號和密碼:
此時我們就能看到倉庫的名字,赫然紙上:
這,就是我們從遠端拉去下來的我們所建立的項目。
你可以進 .git 倉庫里看看,看看就行,不要對里面的東西做任何的修改!
如果我們想把我們的代碼提交上去,比如我們創(chuàng)建一個 test.c 文件:
如果你想在提交之前看看 本地倉庫 和 遠端倉庫 之間的關系,你可以輸入 git status 查驗:
git status
?
0x03?三板斧之第一板斧 —— git add 添加
?如果想上傳到遠端,我們就要使用 git add 指令來操作了。
git add [file name]
我們試著把剛才創(chuàng)建的 test.c 文件添加到我們本地的倉庫:
(第一次使用 git 的時候,可能會讓你配置一下你的用戶名和郵箱)
添加到本地倉庫之后,我們再介紹一個 git commit 指令,提交日志。
0x04 三板斧之第二板斧 —— git commit -m
git commit -m # -m選項代表的是本次的提交日志
# 提交時應該表明提交日志、描述改動的詳細內容,務必培養(yǎng)這個好習慣。
提交日志要好好寫,不要瞎寫,因為這是要給人看的,你寫的一切殊不知……
?日志存在的目的是為了給人看的,也是給自己看的。
寫些什么呢?寫一寫你做了什么東西,比如:
0x05? 三板斧之第三板斧 —— git push 推入
剛才已經將 test.c 存入本地倉庫了,現(xiàn)在我們想要把它傳送到遠端倉庫,即遠端服務器上:
git push
需要填入用戶名與密碼,同步成功后刷新 Github 頁面就能看到代碼改動啦。
?? 總結:?建立倉庫 → git clone → git add → git commit -m "日志內容" → git push
?? [ 筆者 ]? ?王亦優(yōu)
?? [ 更新 ]? ?2023.1.12
? [ 勘誤 ]?? /* 暫無 */
?? [ 聲明 ]? ?由于作者水平有限,本文有錯誤和不準確之處在所難免,
本人也很想知道這些錯誤,懇望讀者批評指正!
?? 參考資料? C++reference[EB/OL]. []. http://www.cplusplus.com/reference/. Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. . 百度百科[EB/OL]. []. https://baike.baidu.com/.文章來源:http://www.zghlxwxcb.cn/news/detail-781070.html 比特科技. Linux[EB/OL]. 2021[2021.8.31 xi文章來源地址http://www.zghlxwxcb.cn/news/detail-781070.html |
到了這里,關于【看表情包學Linux】緩沖區(qū)的概念 | Git 三板斧 | 實現(xiàn)簡易進度條的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!