banner
shuaikai

shuaikai

A SE Student

碼海拾遺

码海拾遗#

前言:完整的總結總是勞神耗時的,已經熟稔的或者易於得到的部分也沒有總結下來的必要。然遨遊碼海,總歸有一些需要記憶的小點,好記性不如爛筆頭,單開一篇又沒必要,索性全歸為一篇,作為手冊。

隨著越拾越多,大口袋又分成了若干小口袋,分別是【語言探幽】【底層探幽】【配置萬千】,分別記錄一些各語言知識點、四大件的內容以及有關環境搭建配置的內容。而本文【碼海拾遺】主要記錄一些命令、工具的使用。或許可以叫工具手冊,但為了紀念這一創舉,保留了 “碼海拾遺” 的名字

1 linux#

1.1 命令#

diff#

  1. diff file1 file2:比較文件的異同:怎麼樣改變第一個文件,可以把它變成第二個文件
    • < 表示左邊 file1 獨有的文件 / 行,>表示右邊 file2 獨有的文件 / 行,| 表示兩邊都有,但不一樣
    • 2,4a2,4:數字是閉區間[2-4]行,需要add 才能跟 file2 一樣,【add、 change、 delete】
  2. diff file1 file2 -y -W 100 | grep ">":並排顯示不同之處,每排寬度 100
  3. -y並排顯示: --suppress-common-lines僅顯示不同的;--left-column相同的僅在左邊顯示
  4. -w忽略所有空格,-i忽略大小寫,-I <str>忽略字符串,-b 忽略行尾空格,字符串中若干空格視為相等
  5. -C <num> 不同之處上下顯示 num 行上下文
  6. -q僅顯示是否相同
  7. -p可用於比較 C 程序
  8. -r遞歸比較子目錄,-N獨有的文件會顯示 "only in xxx"
  9. diff {dir1} {dir2} -Nrqy只顯示文件夾中哪些文件不一樣,不輸出具體的文件

find#

  1. find . -perm /111 -type f -delete:linux 下刪除可執行文件(加個 type 可以略掉文件夾)(find 命令參考
    • -perm mode:必須與 mode 指示的一樣
      -perm /mode:mode 中表示的,滿足一個就好了,比如111,則只要有一個1滿足就好了
      -perm -mode:mode 中表示的,必須全部具有,111就是 ugo 都得可執行,缺一不可。別的屬性不管
    • find -iname readme -o -name *.c -not -size +100k -exec ls -i {} + -fprintf0 file.txt
      find 查找是完全匹配;邏輯與或非;size 的單位注意默認不是 byte;exec 結尾是{} +大括號表示結果

grep#

  • -i:忽略大小寫進行匹配
  • -v:反向查找,只打印不匹配的行
  • -E: 使用正經的正則表達式
  • -n:顯示匹配行的行號
  • -r:遞歸查找子目錄中的文件
  • -l:只打印匹配的文件名(小寫 L)
  • -c只打印匹配的行數

sed#

sed 命令的基本格式是sed [-ni][-e<script>][-f<script文件>][文本文件]

  • -n:安靜模式,只顯示被 sed 處理過的行(否則會輸出所有來自 stdin 的輸入)
  • -e:允許後面直接跟命令,換句話說,不使用 -e 的話命令需要用單引號括起來。可以使用多個 -e
  • -f:允許使用指定 sed 腳本文件
  • -i:直接處理文件本身(會生成 temp 文件)

sed 命令中有一些動作:(sed 從 1 開始計算行)

  • i \:插入, 後面接字串,插入在當前行的一行 *(注意 i a c 這三個動作後面要加上反斜杠)*

  • a\:新增, 後面接字串,插入在當前行的一行

  • c\ :取代, 後面接字串,取代 n1, n2 之間的行

  • d :刪除,因為是刪除,所以 d 後面通常不接任何東西

  • p :打印,亦即將某個選擇的數據印出。通常 p 會與參數 sed -n 一起運行

  • s :取代,通常搭配正則表達式,例如 1,20s/old/new/g

    sed 以行為單位處理,加g是替換全部 pattern,不加是只替換每一行的第一個

# 在第二行上面插入一行 rowxxxyyyy
sed -i -e 2i\ rowxxxyyyy test.txt
sed '2,5c\ shuaikai'
# 在滿足 pattern 模式的行下面插入一行
sed -i '/.*123.*/a 456' test.txt
# 可以用圓括號來進行正則表達式捕獲,並用\+數字來進行引用。圓括號要進行轉義
echo "Hello, World" | sed -n 's#.*,\s\(\w*\)#\1#p'

awk#

awk 命令的基本格式是awk -F " " ' pattern { action } ' filename,即指定分隔符,然後單引號括起來的所有內容作為參數傳遞給 awk,其中前半部分是一個正則表達式 / 條件,後面具體執行的操作用大括號括起來

awk 處理文件是以為單位,對每一行執行操作;每一行通過分隔符劃分為NF個部分

  • NR:當前處理的行號;NF:當前行的塊數。NF==0即表示空行
  • $0:整行內容;$1...:第 1、2...NR 部分
  • 使用變量不需要聲明,第一次用到的時候自動賦空值
  • 循環、分支等與 C 語言相同
  • action 部分可執行內置函數:printlengthsqrtmatch等,也可以通過system()來執行任意函數
  • BEGIN塊,指定在執行動作之前做什麼;EDN塊,指定在執行完動作之後做什麼
# 輸出csv文件每行中長度超過5的字符串,不超過的用xxx代替
awk -F ',' 'NF%3==0 {for(i=1;i<=NF;i++) if(length($i)>5) print$i; else if print"xxx"}'
# 刪除文件中行號是4的倍數的行
awk 'NR%4==0 {print NR}' file | xargs -I{} sed -i "{}d" file
# BAEGIN 和 END 的示意,中間的action才是真正要執行的命令
## 比如如果需要什麼累加的東西,則可以在 END 塊中輸出出來
awk '[pattern] BAEGIN{print"我要開始了"} {action...} END{print"我結束了"}'

例子#

例 1 == 用 awk 和 sed 遷移阿里雲上的圖片:==

  1. 找到阿里雲 oss 倉庫,選擇批量導出 url,導出後是一個.csv 文件,格式為 obj,url

  2. 找一個文件夾下載所有 url

    cat export_urls.csv | awk -F, '{print $2}' | xargs wget
    
  3. 把下載的這些文件上傳到新的 oss 上,得到新的鏈接。這會導致原來的筆記裡面的圖片鏈接全部失效,因此要更改鏈接。鏈接的區別只在前面的 bucket 地址,後面的圖片名是完全一樣的。因此只需要找到所有的筆記文件,把其中圖片 url 中前面的 bucket 鏈接改成新的連接前綴即可

  4. 此處用到的 fd 命令要先下載,即 fd-find。可以對文件夾進行遞歸正則查詢。至此,就完成了對所有圖片的遷移、更改鏈接操作。

    fd ".*\.md$" | xargs sed -i 's#https:\/\/xxx.xxx#https:\/\/yyy.yyy#g'
    

1.2 工具#

直接:sudo apt install

  1. tldr:too long dont read,一個簡單版本的 man 手冊,記得先 - u 更新一下

  2. fzf:對輸出列表進行模糊查詢

  3. colordiff:彩色版 diff,可以 alias 為 diff

  4. fd-find:更快的 find 命令,命令為fdfind,alias 為 fd,功能非常多,-h查看

  5. htop:更易於閱讀的 top 命令

  6. ncdu:更易於閱讀的 du 命令,可以直接排序,查看文件夾大小

  7. ripgrep:更強大的 grep 命令,命令為rg

  8. bat:能高亮的 cat 命令,命令為batcat,alias 為 bat

  9. diff-so-fancy:下載後添加到 PATH,chown 和 chgrp 一下就好了,用法是git diff --color | diff-so-fancy,可以 alias 為 gitd。能夠讓 git diff 顯示的清晰一些,看情況用

  10. manpages-zh:中文 man 手冊,用法:man -M /usr/share/man/zh_CN,alias 為cman
    manpages-posix-dev:POSIX 的 man 手冊

    • 注意,vscode 中有時不能識別一些函數如sigactionpthread_xxx等,是因為沒有 "定義"__USE_POSIX這個宏(但實際上運行的時候是定義的),想要看補全的話,可以手動在,比如 signal.h 頭文件前面 define 上
    • 聽說 c_cpp_properties.json中定義"__USE_POSIX=1",也行,但我的不行。但這不失為定義宏的好地方
  11. cgdb:可以隨時預覽代碼的調試。⛓命令參考 / Esc (vim) i (cgdb) s (cgdb 翻頁)

    #可能會缺少 curses.h 文件,可以先
    sudo apt install libncurses5-dev libncursesw5-dev
    #安裝腳本:
    wget https://shuaikai-bucket0001.oss-cn-shanghai.aliyuncs.com/config/gdb/installCgdb.sh
    # mkdir ~/.cgdb
    wget -O ~/.cgdb/cgdbrc https://shuaikai-bucket0001.oss-cn-shanghai.aliyuncs.com/config/gdb/cgdbrc
    wget -O ~/.gdbinit https://shuaikai-bucket0001.oss-cn-shanghai.aliyuncs.com/config/gdb/.gdbinit
    
  12. expect:交互的終端腳本工具,可以編寫一些期待輸入的腳本,expect xxx send xxx

  13. neofetch:用於顯示系統信息以及一個 ASCII-logo,挺好看的

其他非必要:

  1. ossutil:阿里雲對象存儲的命令行工具

    #(1) 下載安裝
    wget https://gosspublic.alicdn.com/ossutil/install.sh && sudo bash install.sh && rm install.sh
    #(2) 生成配置文件 連按幾下回車即可
    ossutil config
    #(3) 下載自定義配置文件
    wget -O .ossutilconfig https://shuaikai-bucket0001.oss-cn-shanghai.aliyuncs.com/config/others/.ossutilconfig
    wget -O .bash_aliases https://shuaikai-bucket0001.oss-cn-shanghai.aliyuncs.com/config/bash/.bash_aliases
    
  2. man cpp:cpp 的 man 手冊,包括一些瀏覽器檢索的辦法 🔗 Linux 自主安裝 C++man 手冊

1.3 終端操作#

  1. ctrl-a/e: 行首 / 行尾; Alt-b/f: 左 / 右一個單詞
    crtl-w: 往左刪一個詞; Alt-d: 往右刪一個詞
    ctrl-u/k: 刪除光標左 / 右所有字符
    ctrl-y: 粘貼剛才刪除的內容
    ctrl shift '-': 撤銷操作
  2. ^xxx: 刪除上一條命令中的 xxx
    ^foo^bar: 把上一條命令中的 foo 替換為 bar
  3. >:把程序的標準輸出重定向
    2>:把程序的標準錯誤重定向
    &> /dev/null:把程序的標準輸出和標準錯誤都重定向到 null,這樣啥都看不到了

2 GCC#

版本切換#

# 先安裝不同版本的 gcc。只需指定大版本就好,小版本好像會找不到
sudo apt install gcc-8
sudo apt install gcc-11
# “註冊”到一個能切換的地方。後面的數字是【權值】,不指定的時候默認使用權值最大的版本
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 800
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 1100
# 進行版本切換
sudo update-alternatives --config gcc

3 GDB#

命令#

通用命令#

:book:GDB Reference 🔗調試器 GDB 常用功能

  • x / [Length][Format: t o d x f a c s] [Address expression b-8 h-16 w-32 g-64\ ] 📎GDB Command Reference

  • **p/**t-2 o-8 d-10 x-16 f-loat a-ddress c-har s-tring [var]

    1. ⚠️ 要注意區分,x 是掃描內存,因此後面跟的直接是內存地址, 而 p 是輸出變量的值,因此後面想跟地址的話,需要取其內容,即加上*
    2. 關於 *,很多命令地址前面都要加星號,因為不加星號的一個地址,是被當成函數來看待的
  • s n :C 語言級別的單步執行; **si ni** 匯編級別的單步執行

  • i [line] / [locals] / [vtbl] / [args] / [checkpoints] / [breakpoints]

    1. info line [line] / [function] / [*addr]:顯示源碼對應的內存中的起始結束地址

    2. info vtbl [objs]:直接查看對象的虛函數表(也可以類型轉換的形式打印出來,參考C++ 類的內存分配,基本思想就是:對象的第一塊內存放的就是虛表,虛表是一個函數指針數組,因此可以先將對象地址轉換為指向指針的指針,然後對其取內容,就得到了虛表指針。把這個值轉換為指向指針的指針,即得虛表)

  • set print array-indexes on:打印數組的時候顯示 index

  • set disassemble next-line ondisassemble

  • set [args] / [register] / [*address] = [val]:設置參數、寄存器值、內存處值

  • jump [*address]:跳轉到指定地址處執行,return [val]:直接返回。都可以改變程序走向。

  • shell [cmd]:運行 shell 命令

  • rbreak [regex]:在所有滿足正則表達式的函數處打斷點

多進程 / 線程調試#

  • gdb [pid]:調試正在運行的進程,或者進去後 attch [pip]

例子#

  • 打印棧內容(你打數組肯定也行):不妨設 $rsp 中存放的是 0x1234 p $rsp => (void*)0x1234
    1. x/10dw $rspx/10dw 0x1234,即用 x 命令直接把棧那一塊內存掃描出來
    2. p *(int (*)[10])0x1234 把棧頂地址類型轉換為一個指向數組的指針,然後 print 這個數組 val 的值(所以要加*),即棧的內容
    3. p (int [10])*0x1234 把棧頂的內容直接變成一個數組,然後輸出
    4. p *0x1234@6 注意@的用法,其左邊必須是你想查看內存處的,可以直接輸出後面的六個變量
      類似的 p *argv@argc,也是先取內容轉換為變量,再輸出
    5. 總結一下,用 x 就是直接掃描內存了,簡單粗暴;用 p 則是要把你想看的內存區域轉化成一個變量,一個 val,不管是 int 還是 int 數組,不管是怎麼類型轉換,反正基本思想是把內存當成一個變量進行輸出。最好還是用 x ,因為效果一樣,用 p 你還需要先得到 rsp 裡面的值
  • 查看虛表
  • 運用 core 文件gdb debug core進入之後,disassemble,可以看到 => 指向的就是運行出錯的地方

性能分析工具#

Valgrind:查看內存泄漏

grof

GPROF 是一種性能分析工具,用於測量程序的運行時間和函數調用頻率,以幫助開發人員找到程序中的性能瓶頸。它是 GNU 項目的一部分,通常與 GCC(GNU 編譯器集合)一起使用。

GPROF 通過插入計時器代碼和函數調用計數器代碼來收集程序的運行時間和函數調用信息。它使用兩個主要組件來生成性能分析報告:

  1. gprof 編譯器:這是一個特殊版本的 GCC,用於在編譯時在程序中插入性能分析代碼。使用 -pg 选项编译程序时,会将性能分析代码插入到生成的可执行文件中。
  2. gprof 分析工具:這是一個獨立的命令行工具,用於解析可執行文件中的性能分析代碼,並生成詳細的性能分析報告。它會記錄程序的函數調用關係、每個函數的運行時間以及函數調用次數等信息,並以可讀的格式輸出。

使用 GPROF 進行性能分析的一般流程如下:

  1. 在編譯程序時,使用 -pg 選項告訴編譯器插入性能分析代碼。例如:gcc -pg -o my_program my_source.c
  2. 運行程序,生成gmon.out文件。執行一系列典型的操作,以便 GPROF 能夠收集足夠的性能數據。
  3. 程序運行結束後,在終端中運行 gprof 命令來生成性能分析報告。例如:gprof my_program
  4. GPROF 會分析程序執行期間收集到的數據,並生成一個報告,其中包含函數調用關係圖、每個函數的運行時間百分比、函數調用次數等信息。

通過分析 GPROF 生成的報告,開發人員可以確定程序中的熱點函數(運行時間最長的函數)和瓶頸函數(被頻繁調用的函數),以便進行性能優化。

4 Git#

配置#

  1. git config --global init.defaultBranch main
  2. 找機會修改一下 github 用戶名
  3. --global: ~/.gitconfig
    --system:/etc/gitconfig

基礎命令#

5 Makefile#

教程#

REF1:makefile 簡明教程, REF2:如何輸出到指定文件夾REF3:關於自動生成依賴.d 文件

模式替換#

$(patsubst <pattern>,<replacement>,<text> )
查找中的單詞(單詞以 “空格”、“Tab” 或 “回車”“換行” 分隔)是否符合模式,如果匹配的話,則以替換。

​ 這裡,可以包括通配符 “%”,表示任意長度的字串。如果中也包含 “%”,那麼,中的這個 “%” 將是中的那個 “%” 所代表的字串。(可以用 “\” 來轉義,以 “%” 來表示真實含義的 “%” 字符)

$(patsubst %.c,%.o, a.c b.c)
# 把字串 “a.c b.c” 符合模式[%.c]的單詞替換成[%.o],返回結果是 “a.o b.o”

變量替換引用#

​ 對於一個已經定義的變量,可以使用 “替換引用” 將其值中的後綴字符(串)使用指定的字符(字符串)替換。格式為$(VAR:A=B)或者${VAR:A=B}

​ 意思是,替換變量 “VAR” 中所有 “A” 字符結尾的字為 “B” 結尾的字。“結尾” 的含義是空格之前(變量值多個字之間使用空格分開)。而對於變量其它部分的 “A” 字符不進行替換。

foo := a.o b.o c.o
bar := $(foo:.o=.c)
# 注意變量不要帶 $
SRCS_NODIR := $(notdir $(wildcard $(SRC_DIR)/*$(SRC_SUFFIX)))
OBJS_NODIR := $(SRCS_NODIR:$(SRC_SUFFIX)=$(OBJ_SUFFIX))

模板 1#

# 一個適合中小規模的makefile模版,基本上自己按照實際情況指定一下 源文件,目標文件,頭文件目錄,以及源文件後綴就行了。

# ---------------------------------------------------------------------------
# commands
# ---------------------------------------------------------------------------
CC := gcc
LINK := gcc
RM := rm -rf
MV := mv
TAR := tar
MKDIR := mkdir

# ---------------------------------------------------------------------------
# settings
# ---------------------------------------------------------------------------
SRC_SUFFIX := .c
OBJ_SUFFIX := .o
LIB_SUFFIX := .a
BIN_SUFFIX := .exe
DLL_SUFFIX := .so

INC_PREFIX := -I
LIB_PREFIX := -L

OPT_C := -c
OPT_OUT := -o
OPT_LINKOUT := -o

CFLAGS := $(OPT_C)
LIBFLAGS := -Debug

# ---------------------------------------------------------------------------
# directories
# ---------------------------------------------------------------------------
SRC_DIR := ./src
OBJ_DIR := ./obj
INC_DIR := ./inc
LIB_DIR := ./lib /usr/local/lib /lib /usr/lib

# ---------------------------------------------------------------------------
# common settings
# ---------------------------------------------------------------------------
SRCS := $(wildcard $(SRC_DIR)/*$(SRC_SUFFIX))
OBJS := $(patsubst $(SRC_DIR)/%$(SRC_SUFFIX),$(OBJ_DIR)/%$(OBJ_SUFFIX),$(SRCS))
INCS := $(addprefix $(INC_PREFIX), $(INC_DIR))
LIBS := $(addprefix $(LIB_PREFIX), $(LIB_DIR)) $(LIBFLAGS)
TEMPFILES := core core.* *$(OBJ_SUFFIX) temp.* *.out typescript*

# ---------------------------------------------------------------------------
# make rule
# ---------------------------------------------------------------------------
TARGET := loader

.PHONY: all clean

all: $(TARGET)

clean:
$(RM) $(TARGET)$(BIN_SUFFIX) $(OBJS)

$(TARGET):$(OBJS)
$(LINK) $(OPT_LINKOUT)$(TARGET)$(BIN_SUFFIX) $(LIBS) $(OBJS)

$(OBJS):$(OBJ_DIR)/%$(OBJ_SUFFIX):$(SRC_DIR)/%$(SRC_SUFFIX)
$(CC) $(CFLAGS) $(INCS) $(OPT_OUT)$@ $<

模板 2#

CXX := g++

SRC_DIR := ./src
OBJ_DIR := ./build
BIN_DIR := ./bin
INC_DIR := ./include

VPATH = $(INC_DIR) $(OBJ_DIR) $(SRC_DIR)
vpath %.h $(INC_DIR)

# 一種搜索源文件的方式
# SRC_DIRS = $(shell find $(SRC_DIR) -maxdepth 3 -type d)
# SRCS = $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)/*.cpp))
# TODO: 這樣子出來的目標文件,在jing'tai時就找不到依賴了
# OBJS := $(OBJ_DIR)/$(notdir $(patsubst %.cpp, %.o, $(SRCS)))

SRCS := $(wildcard $(SRC_DIR)/*.cpp)
OBJS := $(patsubst $(SRC_DIR)/%.cpp, $(OBJ_DIR)/%.o, $(SRCS))
INCS := $(addprefix -I, $(INC_DIR))
BUILDING_DIRS := $(OBJ_DIR) $(BIN_DIR)

TARGET := adb_lab2.exe
RUN := run.sh

$(TARGET) : $(BUILDING_DIRS) $(OBJS)
	$(CXX) -o $(BIN_DIR)/$(TARGET) $(OBJS)
	@touch $(RUN)
	@echo "$(BIN_DIR)/$(TARGET)" > $(RUN)

# 這裡的前綴不能少。makefile不會自動去VPATH裡面找這幾個目標,而是直接當成新的目標來對待
$(OBJ_DIR)/BufferPoolManager.o : BufferPoolManager.h LRUReplacer.h
$(OBJ_DIR)/DataStorageManager.o : DataStorageManager.h
$(OBJ_DIR)/LRUReplacer.o : LRUReplacer.h
$(OBJ_DIR)/main.o : BufferPoolManager.h

# 一個創建運行時依賴文件夾的方法
$(BUILDING_DIRS) :
	@mkdir $@

# 這叫 靜態模式
$(OBJS) : $(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
	$(CXX) -o $@ -c $< $(INCS)

.PHONY: all clean output
all : $(TARGET)
clean:
	-rm -rf $(BUILDING_DIRS) test.dbf $(RUN)
output:
	@echo $(SRCS)
	@echo --------------
	@echo $(OBJS)

模板 3#

🔗自動處理頭文件的依賴

CC := gcc
CC_INCLUDE_FLAGS := -I ./include/
CC_FLAGS := $(CC_INCLUDE_FLAGS) -g

# 程序執行的參數
ARGS := ~/codes

DIR_SRC := ./src
DIR_OBJ := ./build
DIR_EXE := ./bin

SRCS := $(shell find $(DIR_SRC) -name "*.c")
OBJS := $(patsubst $(DIR_SRC)/%.c, $(DIR_OBJ)/%.o, $(SRCS))
DPTS := $(patsubst %.c, %.d, $(SRCS))
DIRS := $(DIR_OBJ) $(DIR_EXE)

target := $(DIR_EXE)/my_ls_pro

$(target): $(DIRS) $(OBJS)
	$(CC) $(OBJS) -o $@

$(DIRS):
	@mkdir $@

$(DIR_OBJ)/%.o: $(DIR_SRC)/%.c
	$(CC) $(CC_FLAGS) -c $< -o $@

# set -e : 讓終端處於執行命令返回結果不為 0 就終止執行的狀態
# gcc -M : 輸出所有的依賴關係,-MM 不輸出系統的依賴
%.d: %.c
	@set -e; \
	rm -f $@; \
	$(CC) -MM $(CC_FLAGS) $< $(CC_INCLUDE_FLAGS) > $@.$$$$.dtmp; \
	sed 's,\(.*\)\.o\:,$*\.o $*\.d\:,g' < $@.$$$$.dtmp > $@;\
	rm -f $@.$$$$.dtmp

-include $(DPTS)

clean:
	rm -f $(OBJS)
	rm -f $(DPTS)

run:
	make
	$(target) $(ARGS)

6 vim#

基本操作#

  1. 定義宏:q + [a-zA-Z] + your_operation + q,使用時@ + [a-zA-Z]

  2. Ctrl + a光標第一個數字加一,Ctrl + x光標第一個數字減一

  3. 行內移動:f w b e

  4. 自動補全:Ctrl + p

  5. 查詢 man 手冊:K

  6. :digraphs 列出所有特殊字符

  7. vim 中有很多寄存器,可以用 :reg [xxx] 來查看

    1. a-zA-Z 是用戶寄存器,用來存放錄製的按鍵,vim 不會去更改它
    2. 0-9 是系統寄存器,裡面存放了一些系統定義的東西,比如 0 移動到行首
    3. + 是系統共享剪切板,"是 vim 臨時剪切板,yy dd p 等命令都是用的這個。可以設置二者互通
  8. 按住 shift 和鼠標左鍵,即可在 vim 中選中,並複製粘貼

  9. #:自動查找井號後面的單詞

  10. image-20230208121344239
  11. ctrl w ←↑↓→切換窗口,ctrl w HJKL移動窗口

  12. :vertical resize +-n:調整當前窗口寬度,去掉vertical調整高度

  13. 默認的map是遞歸的,比如 a 映射 b,b 映射 c,那麼就等於 a 映射了 c。可以根據使用模式,做非遞歸的映射,即nnoremap/inoremap/vnoremap/cnoremap(normal/insert/visual/comandline)

  14. doc/help.md・chenxuan/vim-fast - 码云 - 开源中国 (gitee.com)

myvimrc#

快速配置:vimfast || 基於vimplus || vim 快捷鍵help.md || 內置快捷鍵key.md

# 我自己的快速配置 √
wget -O ~/.vimrc https://shuaikai-bucket0001.oss-cn-shanghai.aliyuncs.com/config/vim/.vimrc.mine
wget https://shuaikai-bucket0001.oss-cn-shanghai.aliyuncs.com/config/vim/vim-win.tar.gz && cd ~ && tar -xvf vim-win.tar.gz

# 無插件快速配置
wget https://gitee.com/mirrorvim/vim-fast/raw/master/vimrc-no-plug -O ~/.vimrc

通用設置#

let mapleader = ","      " 定義<leader>鍵為逗號[,]
set (no)wrap			" 長行(不)換行

打開窗口#

"分屏與豎直分屏
// :split [file]
// :vsplit [file]
"vim中調試
// Termdebug [bug_file]	" 打開源代碼、gdb、IO三個窗口
nnoremap <leader><leader>d Termdebug<space>	" 用[,,d]直接打開此模式
"vim中打開新的終端
// :vert term	" vert,即打開豎直方向終端,去掉即水平方向分窗口
nnoremap <leader><leader>t :vert term	" 打開豎直終端
nnoremap <leader><leader>t :bo term ++rows=6	"六行水平終端

mybash_aliases#

wget -O ~/.bash_aliases https://shuaikai-bucket0001.oss-cn-shanghai.aliyuncs.com/config/bash/.bash_aliases

7 VScode#

C/C++ 環境#

插件#

  • inline bookmark

可以對行進行標記,並在左側列出

"inline-bookmarks.expert.custom.words.mapping": {"blue": [">mark[\\s]","@mark[\\s]"],"purple": [">panic[\\s]","@panic[\\s]"],"green":[">note[\\s]","@note[\\s]"],"red":[">warn[\\s]",">why[\\s]","@warn[\\s]","@why[\\s]"],"warn": [">todo[\\s]",">TODO[\\s]","@todo[\\s]","@TODO[\\s]"]},

8 編碼風格#

命名#

普通變量#

  • 推薦使用下劃線隔開單詞 (Google 開源風格指南),也可以使用駝峰命名法,但是不要使用無意義的字母!

  • tDataNode:t 開頭表示這是一個類型,type

  • kPI:k 開頭表示常量,在程序運行中不會被修改

成員變量#

以下內容準確性待考究。但首尾下劃線一般都表示 “私有” 之意

  1. __foo__: 定義的是特殊方法,一般是系統定義名字,類似__init__() 之類

  2. _foo: 以單劃線開頭的表示的是 protected 類型的變量或函數,即保護類型,只允許本身和子類訪問。也有在後面加下劃線的,同理。都是表達 "私有" 之意。

  3. __foo: 以雙下劃線開頭的表示的是 private 類型的變量或函數,即私有類型,只允許本身訪問。

  4. C 語言中,單下劃線開頭表示是標準庫的變量,雙下劃線表示是編譯器的變量

註釋#

參考

文件註釋#

/**
 * @file 文件名
 * @brief 簡介		 
 * @details 細節
 * @author 作者
 * @version 版本號
 * @date 年-月-日
 * @copyright 版權
 * @todo 待辦
 * @throw 異常描述
 * @bugs 漏洞
 * @pre 前提條件
 * @see [參考]
 */

函數註釋#

 /**
  * @brief 函數描述
  * @param 參數描述
  * @return 返回描述
  * @retval 返回值描述
  */

結構體註釋#

 /**
 * @brief 類的詳細描述
 */

常變量註釋#

//定義一個整型變量a
int a

int a; /*!< 定義一個整型變量a */
int a; /**< 定義一個整型變量a */
int a; //!< 定義一個整型變量a
int a; ///< 定義一個整型變量a
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。