【Linux】特效爆滿的Vim的配置方法 and make/Makefile原理

一、軟件包管理器

1、Linux下安裝軟件的常見方式:

? ? ? ? 1)源代碼安裝——不推薦。

? ? ? ? 2)rpm包安裝——不推薦。

? ? ? ? 3)包管理器安裝——推薦

2、安裝軟件命令

 # Centos$ sudo yum install -y lrzsz# Ubuntu$ sudo apt install -y lrzsz

3、卸載軟件命令

 # Centossudo yum remove [-y] lrzsz# Ubuntusudo apt remove [-y] lrzsz

? ? ? ? 任何評估一款操作系統的好壞?操作系統被設計出來之后,最重要的事情是什么?

? ? ? ? 答:操作系統形成使用圈子就會被更多的人使用,為了讓更多的人使用就必須讓圈子更完善;有人愿意在特定的os上編寫特定的軟件適應不同的群體,并且在各種圈子完善社區、文檔、論壇、資料。

二、編輯器 Vim

? ? ? ? ?IDE在Linux下的開發工具是獨立的!寫代碼——編輯器vim,編譯代碼——gcc/g++,調試——gdb/cgbd,構建工具——makefile/make/cmake。

? ? ? ? 進入vim的指令:vim + 文件。進入vim之后要寫內容按鍵盤 i 鍵。

? ? ? ? vimd的多模式:命令模式、插入模式、底行模式。

? ? ? ? 底行模式:set nu,是給內容加上行號,如:

?注意:如果想去掉行號在底行模式輸入:nonu。

命令模式下:

????????shift+g:光標進入文本末端。

? ? ? ? gg:光標進入文本的開始。

? ? ? ? n+shift+g:光標進入來到文本n行。

? ? ? ? shift+4:光標進入到當前行的末尾。

? ? ? ? shift+6:光標來到當前行的開始。

? ? ? ? h:光標往左移動。

? ? ? ? j:光標往下移動。

? ? ? ? k:光標往上移動。

? ? ? ? l:光標往右移動。

? ? ? ? w:按照單詞向右移動。注意:可以加上數字。

? ? ? ? b:按照單詞向左移動。注意:可以加上數字。

? ? ? ? yy:復制當前行的內容。n+yy復制前n行內容。

? ? ? ? p:粘貼。n+p可以粘貼n次。

? ? ? ? dd:刪除當前行。n+dd刪除前n行內容。

? ? ? ? u:撤銷操作。

? ? ? ? ctrl+r:對u的撤銷。

注意:任意模式下都可以進行撤銷操作,退出vim就不能撤銷了。

? ? ? ? shift+~:對光標的字母進行大小寫切換。

? ? ? ? r:替換光標所在位置的一個字符,n+r替換n個字符。

? ? ? ? shift+r:進入替換模式,忽視原來文本內容,可重新編寫。注意:進入替換模式之后要退出來就要按Esc鍵。

? ? ? ? x:刪除光標所在字符,向右刪除。

? ? ? ? shift+x:向左刪除光標所在字符。

? ? ? ? 批量化注釋:①ctrl+v,②hjkl選擇區域,③shift+i,④//,⑤Esc。

? ? ? ? 批量化去注釋:①ctrl+v,②hjkl選擇區域,③d,④Esc。

底行模式下:

? ? ? ? w!:保存。

? ? ? ? q!:退出。

? ? ? ? wq!:強制保存并退出。

注意:如果vim打開文件,突然終端退出,vim會形成臨時文件,默認在當前路徑的下一個.swp臨時ls -al。

? ? ? ? :/key+n:匹配搜索。

? ? ? ? :!cmp:不退出vim,直接對代碼進行編譯運行。

? ? ? ? :%s/dst/src/g:把文本內容所有的dst替換成src。

? ? ? ? :vs:分屏操作。ctrl+www,選中哪一個分屏。

注意:當vim退出光標在第n行,再次打開光標還在原來位置。那么我們Linux下可輸入vim +文件名+n,直接進入到第n行。在命令模式下退出vim操作:shift+zz。

配置炫酷的vim:

????????要配置炫酷的vim,原生的配置可能功能不全,可以選擇安裝插件來完善配置,保證用戶是你要配置的用戶,接下來:

? ? ? ? ①安裝TagList插件,下載taglist_xx.zip,解壓完成,將解壓出來的doc的內容放到~/.vim/doc,將解壓出來的plugin下的內容拷貝到~/.vim/plugin。

? ? ? ? ②在~/.vimrc中添加:let Tlist_Show_One_File=1?letTlist_Exit_OnlyWindow=1?let Tlist_Use_Right_Window=1

? ? ? ? ③安裝文件瀏覽器和窗口管理器插件:WinManager

? ? ? ? ④下載winmanager.zip,2.X版本以上的

? ? ? ? ⑤解壓winmanager.zip,將解壓出來的doc的內容放到~/.vim/doc,將解壓出來的plugin下的內容拷貝到~/.xim/plugin

? ? ? ? ⑥在~/.vimrc中添加 let g:winManagerwindowLayout=‘FileExplorer|TagListnmap wm :WMToggle<cr>

? ? ? ? ⑦然后重啟vim,打開~/XXX.c或~/XXX.cpp,在normal狀態下輸入"wm",你將看到上圖的效果。更具體移步:手把手教你把Vim改裝成一個IDE編程環境(圖文)_vim 打造成 ide-CSDN博客,其他手冊,請執行vimtutor 命令。

三、讓普通用戶暫時提權的方法

? ? ? ? 1、進入到root界面

? ? ? ? 2、指令:ls /etc/sudoers,查看sudoer是否存在。

? ? ? ? 3、指令:vim /etc/sudoers,進入sudoers

? ? ? ? 4、yy接著p一下

四、g++/gcc

1)區別

? ? ? ? gcc:C編譯器。只能用來進行編譯C語言。

? ? ? ? g++:C++/C語言編譯器。

2)四步生成可執行文件

? ? ? ? 預處理(頭文件展開,去注釋,宏替換,條件編譯):指令:gcc 文件名 -o 編譯后行的文件名(可自己寫)。由于gcc是一步到位(直接形成可執行文件),所以可以這么做:gcc -E 文件名 -o 預處理之后的文件名.i;

? ? ? ? 編譯:把C語言變成匯編語言,指令:gcc -S 文件名.i -o 文件名.s

? ? ? ? 匯編:把匯編語言翻譯成二進制文件,指令:gcc -c 文件名.s -o 文件名.o

? ? ? ? 鏈接:把二進制文件形成可執行文件,指令:gcc 文件名.o -o 文件名.exe

補充知識:為什么要把C語言翻譯成匯編?

答:翻譯語言的本質是轉成CPU能夠識別的指令集;匯編語言是用字母來對二進制指令進行包裝;

先有匯編語言還是先有用匯編語言寫的匯編編譯器?

答:先拿二進制寫出一個匯編編譯器,再寫出匯編語言,然后在拿匯編語言完善匯編編譯器,最后再用匯編語言編寫軟件(如C語言編譯器),最終再拿C語言編譯器來寫匯編編譯器(編譯器自舉),所以先有語言。

.o二進制文件能不能直接運行?

答:不能,原因:如果運行.o文件他會報出錯誤:可重定位目標二進制文件,因為我們用到的庫方法,只有說明,沒有定義。

注意:在Linux中靜態庫是以.a為后綴,動態庫是以.so為后綴;window的靜態庫是以.lib為后綴,動態庫是以.dll為后綴。? ? ? ??

動態鏈接優點:節省內存空間;缺點:慢,編譯完成依舊依賴動態庫;靜態庫的優點:不需要庫跳轉,一旦編譯完成不依賴庫;缺點:可執行程序體積較大(把庫實現的方法拷貝到程序里面),消耗內存資源。

注意:gcc默認編譯是采用動態鏈接的方式完成,如果想要強制進行靜態鏈接可以輸入指令:gcc 文件名 -o 文件名 -static。

3)靜態庫和動態庫

????????靜態庫是指編譯鏈接時,把庫文件的代碼全部加入到可執行文件中,因此生成的文件比較大,但在運行時也就不再需要庫文件了。其后綴名一般為“.a”

????????動態庫與之相反,在編譯鏈接時并沒有把庫文件的代碼加入到可執行文件中,而是在程序執行時由運行時鏈接文件加載庫,這樣可以節省系統的開銷。動態庫一般后綴名為“.so”,如前面所述的libc.so.6就是動態庫。

????????gcc在編譯時默認使用動態庫。完成了鏈接之后,gcc就可以生成可執行文件,如下所示。gcc hello.o-o hellogcc默認生成的二進制程序,是動態鏈接的,這點可以通過file 命令驗證。

五、自動化項目的構建(生成可執行文件)——make/Makefile

1)背景

????????會不會寫makefile,從一個側面說明了一個人是否具備完成大型工程的能力。

????????一個工程中的源文件不計數,其按類型、功能、模塊分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至于進行更復雜的功能操作。

????????makefile帶來的好處就是—“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。

????????make是一個命令工具,是一個解釋makefile中指令的命令工具,一般來說,大多數的IDE都有這個命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可見,makefile都成為了一種在工程方面的編譯方法。

????????make是一條命令,makefile是一個文件,兩個搭配使用,完成項目自動化構建。

2)make/Makefile的執行原理

????????make會在當前目錄下找名字叫“Makefile”或“makefile”的文件。

????????如果找到,它會找文件中的第一個目標文件(target),在上面的例子中,他會找到myproc 這個文件,并把這個文件作為最終的目標文件。

????????如果myproc文件不存在,或是myproc所依賴的后面的myproc.o文件的文件修改時間要比 myproc 這個文件新(可以用touch 測試),那么,他就會執行后面所定義的命令來生成myproc這個文件。

????????如果myproc 所依賴的myproc.o文件不存在,那么make 會在當前文件中找目標為myproc.o文件的依賴性,如果找到則再根據那一個規則生成myproc.o文件。(這有點像一個堆棧的過程)

????????當然,你的C文件和H文件是存在的啦,于是 make 會生成 myproc.o 文件,然后再用myproc.o文件聲明make的終極任務,也就是執行文件 hello了。

????????這就是整個make的依賴性,make會一層又一層地去找文件的依賴關系,直到最終編譯出第一個目標文件。

????????在找尋的過程中,如果出現錯誤,比如最后被依賴的文件找不到,那么make就會直接退出,并報錯,而對于所定義的命令的錯誤,或是編譯不成功,make根本不理。

注意:gcc無法二次編譯老代碼的原因:源代碼的時間比可執行文件的要舊,如果修改源代碼那么的他的時間就會比可執行文件新,這時候就可以進行二次編譯。修改一個文件的時間可以使用touch 一個已經存在的源文件,這時候就可以進行二次編譯。

結論:判斷文件新舊是根據文件的Mod時間來判定;.PHONY為什么總是被執行的?原因:就是讓gcc或者對應的命令忽略Mod時間對比新舊。

注意:Modify是文件內容被修改的時間,change 是文件屬性被修改的時間;只要修改文件的內容Mod和change的時間也會被修改,原因:修改文件內容會影響文件大小,包括Mod時間也是屬性。Access是文件最近被訪問的時間,查看文件會跟新時間,相當于修改文件屬性,這時Linux就會刷新到磁盤,因為查看文件次數較多所以會增加磁盤的訪問次數,外設效率低下,導致os整體效率降低,故而訪問文件內容達到特定次數之后,才會更新一次時間。

?知識點補充:

使用 wildcard 函數,獲取當前所有.c文件名OBJ=$(SRC:.C=.0)//將SRC的所有同名.c替換成為.o形成目標文件列表$@:代表目標文件名。$^:代表依賴文件列表%.c展開當前目錄下所有的.c。%.o:同時展開同%<:對展開的依賴.c文件,一個一個的交給gcc。@:不回顯命令S(RM)·替換,用變量內容替換它

注意:?

?SRC=$(wildcard *.cc) #wildcard是make的一個函數,用來匹配文件名
#*.cc就是wildcard函數的參數
#用法$(wildcard pattern) ?參數 pattern 是一個文件名通配符模式
#文件名通配符模式是一種使用特殊字符來匹配一組文件名的語法
#特殊字符*表示匹配任意數量的字符(包括零個)
OBJ=$(SRC:.cc=.o)
這是 Makefile 中的 變量替換(模式替換) 語法,格式如下:
$(變量名:模式=替換)
它的意思是:把“變量名”中所有 符合“模式” 的部分,替換為“替換”。

?六、進度條原理和設計

main.c

#include "process.h"
#include <unistd.h>
#include <time.h>
#include <stdlib.h>double gtotal = 1024.0;
double speed = 1.0;// 函數指針類型
typedef void (*callback_t)(double, double);// 1.0 4.3
double SpeedFloat(double start, double range) // [1.0 3.0] -> [1.0, 4.0]
{int int_range = (int)range;return start + rand()%int_range + (range - int_range);
}// cb: 回調函數
void DownLoad(int total, callback_t cb)
{srand(time(NULL));double curr = 0.0;while(1){if(curr > total){curr = total; // 模擬下載完成cb(total, curr); // 更新進度, 按照下載進度,進行更新進度條break;}cb(total, curr); // 更新進度, 按照下載進度,進行更新進度條curr += SpeedFloat(speed, 20.3);  // 模擬下載行為usleep(30000);}
}int main()
{printf("download: 20.0MB\n");DownLoad(20.0, FlushProcess);printf("download: 2000.0MB\n");DownLoad(2000.0, FlushProcess);printf("download: 100.0MB\n");DownLoad(100.0, FlushProcess);printf("download: 20000.0MB\n");DownLoad(20000.0, FlushProcess);return 0;
}

process.c

#include "process.h"
#include <string.h>
#include <unistd.h>#define SIZE 101
#define STYLE '='void FlushProcess(double total, double curr) // 更新進度, 按照下載進度,進行更新進度條
{if(curr > total)curr = total;double rate = curr / total * 100; // 1024.0 , 512.0 -> 0.5 -> 50.0int cnt = (int)rate; // 50.8 , 49.9 -> 50, 49char processbuff[SIZE];memset(processbuff, '\0', sizeof(processbuff));int i = 0;for(; i < cnt; i++)processbuff[i] = STYLE;static const char *lable = "|/-\\";static int index = 0;// 刷新printf("[%-100s][%.1lf%%][%c]\r", processbuff, rate, lable[index++]);index %= strlen(lable);fflush(stdout);if(curr >= total){printf("\n");}
}// version1: 能夠使用嗎??
// 說明原理
void Process()
{const char *lable = "|/-\\";int len = strlen(lable);char processbuff[SIZE];memset(processbuff, '\0', sizeof(processbuff));int cnt = 0;while(cnt <= 100){printf("[%-100s] [%d%%][%c]\r", processbuff, cnt, lable[cnt%len]);fflush(stdout);processbuff[cnt++] = STYLE;usleep(30000);}printf("\n");
}

process.h

#pragma once#include <stdio.h>// version1
void Process();
void FlushProcess(double total, double curr); // 更新進度, 按照下載進度,進行更新進度條

完!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/917913.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917913.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917913.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Boot Actuator 監控功能的簡介及禁用

Spring Boot Actuator: Production-ready Features 1. 添加依賴 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency> </dependencie…

Matlab(1)

一、基本操作1. matlab四則運算規則&#xff1a;先乘除后加減&#xff0c;從左到右2、對數和指數的表示sin(pi^0.5)log(tan(1))exp&#xff08;sin&#xff08;10&#xff09;&#xff09;3、類型&#xff1a;matlab變量默認為double4、who&whos&#xff1a;命令行輸入who&…

Kotlin Android 開發腳手架封裝

Kotlin Android 開發腳手架封裝&#xff08;模塊化版本&#xff09; 我將按照模塊化設計原則&#xff0c;將腳手架拆分為多個文件&#xff0c;每個文件負責特定功能領域&#xff1a; 1. 核心初始化模塊 文件路徑: core/AppScaffold.kt object AppScaffold {lateinit var contex…

Flutter 報錯解析:No TabController for TabBar 的完整解決方案

目錄 Flutter 報錯解析&#xff1a;No TabController for TabBar 的完整解決方案 一、錯誤場景&#xff1a;當 TabBar 失去 "指揮官" 二、為什么 TabBar 必須依賴 Controller&#xff1f; 1. TabBar 與 TabController 的協作關系 2. 狀態管理的核心作用 3. 實戰…

【24】C++實戰篇——【 C++ 外部變量】 C++多個文件共用一個枚舉變量,外部變量 extern,枚舉外部變量 enum

文章目錄1 方法2 外部變量 應用2.1 普通外部全局變量2.2 枚舉外部全局變量 應用2.2.2 枚舉外部變量優化c多個文件中如何共用一個全局變量 c頭文件的使用和多個文件中如何共用一個全局變量 C共享枚舉類型給QML 1 方法 ①頭文件中 聲明外部全局變量&#xff1b; ②在頭文件對…

Linux SELinux 核心概念與管理

Linux SELinux 核心概念與管理一、SELinux 基本概念 SELinux 即安全增強型 Linux&#xff08;Security-Enhanced Linux&#xff09;&#xff0c;由美國國家安全局&#xff08;NSA&#xff09;開發&#xff0c;是一套基于強制訪問控制&#xff08;MAC&#xff09;的安全機制&…

Git 中**未暫存**和**未跟蹤**的區別:

文件狀態分類 Git 中的文件有以下幾種狀態&#xff1a; 工作區文件狀態&#xff1a; ├── 未跟蹤 (Untracked) ├── 已跟蹤 (Tracked)├── 未修改 (Unmodified) ├── 已修改未暫存 (Modified/Unstaged)└── 已暫存 (Staged)1. 未跟蹤 (Untracked) 定義&#xff1a;Gi…

前端1.0

目錄 一、 什么是前端 二、 HTML 1.0 概述 2.0 注釋 三、開發環境的搭建 1.0 插件 2.0 筆記 四、 常見標簽&#xff08;重點&#xff09; 四、案例展示&#xff08;圖片代碼&#xff09; 五、CSS引入 一、 什么是前端 web前端 用來直接給用戶呈現一個一個的網頁 …

Flutter鏡像替換

一、核心鏡像替換&#xff08;針對 Maven 倉庫&#xff09; Flutter 依賴的 Google Maven 倉庫&#xff08;https://maven.google.com 或 https://dl.google.com/dl/android/maven2&#xff09;可替換為國內鏡像&#xff0c;常見的有&#xff1a;阿里云鏡像&#xff08;推薦&am…

MATLAB實現的改進遺傳算法用于有約束優化問題

基于MATLAB實現的改進遺傳算法&#xff08;GA&#xff09;用于有約束優化問題的代碼&#xff0c;包括處理非線性約束。此代碼通過引入懲罰函數和修復機制&#xff0c;有效處理約束條件&#xff0c;提高算法的魯棒性和收斂速度。 1. 定義優化問題 % 定義目標函數 function f ob…

Qt子類化QWidget后,使用setStyleSheet設置樣式無效的解決方案

關鍵代碼&#xff1a; #include <QPainter> #include <QStyleOption>void paintEvent(QPaintEvent *e) {QStyleOption opt;opt.init(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);QWidget::paintEvent(e); }定義…

【python中級】關于Flask服務在同一系統里如何只被運行一次

【python中級】關于Flask服務在同一系統里如何只被運行一次 1.背景 2.方案1 2.方案2 1.背景 python Flask實現的一個http服務,打包成應用程序exe后在windows10系統運行; 由于我會不斷的更新這個http服務,我希望運行這個http服務的時候之前的http服務被停掉; 即實現 Pytho…

git配置公鑰/密鑰

遇到 “gitgithub.com: Permission denied (publickey)” 錯誤通常意味著你嘗試通過 SSH 連接到 GitHub 時&#xff0c;SSH 密鑰沒有被正確設置或者 GitHub 無法識別你的公鑰。這里有幾個步驟可以幫助你解決這個問題&#xff1a; 檢查 SSH 密鑰 首先&#xff0c;確保你已經在本…

【機器學習】“回歸“算法模型的三個評估指標:MAE(衡量預測準確性)、MSE(放大大誤差)、R2(說明模型解釋能力)

文章目錄一、MAE、MSE、r概念說明二、MAE&#xff08;平均絕對誤差&#xff09;&#xff1a;用"房價預測"理解誤差測量三、MSE&#xff08;均方誤差&#xff09;&#xff1a;誤差的"放大鏡"1、概念說明2、 sklearn代碼實踐3、流程總結四、R&#xff1a;理解…

智慧城市SaaS平臺|市容環衛管理系統

【生活垃圾中轉設施監管】1) 設施信息管理a) 設施基本信息支持記錄中轉設施的名稱、位置、類型、容量、負責人等基本信息。b) 設施分布地圖支持通過GIS地圖展示中轉設施的分布情況&#xff0c;支持地圖查詢和導航。2) 垃圾收運監控a) 垃圾收運記錄支持記錄垃圾收運的時間、車輛…

JAVA-13常用類(2025.08.02學習記錄)

String類String類equals方法String類compareTo方法String類valueOf方法boolean參數內存分析_字符串拼接只會在內存中開辟一個對象內存分析_字符串new創建對象內存分析_變量和字符串拼接字節碼執行過程String類內存分析package com.cn;public class test01 {public static void …

QT----簡單的htttp服務器與客戶端

HTTP協議學習 協議的相關學習可以參考這篇 csdn學習連接 總體流程如下 HTTP服務器 監聽ip和端口,有連接時接收請求,發送回復 server.h #pragma once #include <QtWidgets/QMainWindow> #include "ui_httpServer.h" #include <QTcpServer> #include &l…

飛 算 JavaAI 解 析:有 了 它,麻 麻 再 也 不 用 擔 心 我 不 會 寫 代 碼 了!

聲 明&#xff1a;本 篇 博 客 為 測 評 體 驗 非 廣 告。 文 章 目 錄一、產 品 簡 介二、注 冊 與 上 手方 法 一 - - - 從 IDEA 插 件 市 場 安 裝方 法 二產 品 使 用三、產 品 體 驗智 能 引 導 功 能理 解 需 求設 計 接 口表 結 構 設 計處 理 邏 輯生 成 源 碼Java ch…

iOS混淆工具有哪些?在集成第三方 SDK 時的混淆策略與工具建議

許多 iOS 項目中&#xff0c;不可避免地會集成各種第三方 SDK&#xff0c;比如支付、統計、廣告、社交登錄等。這些 SDK 常常存在逆向被 Hook 或提取業務邏輯的風險&#xff0c;尤其是在流程敏感或要求合規的行業中。 當你無法對第三方源碼進行控制或重新編譯時&#xff0c;混淆…

【學習筆記之redis】刪除緩存

有一串這個代碼&#xff0c;staffEmailList這個key值里面的數據是錯誤的我需要刪除它&#xff0c;把數據新的數據加載到redis緩存中。 public EmailAddressRespDTO getAllEmailAddress() { List<EmailAddressRespDTO> staffEmailList redisCache.getCacheList("s…