コードの海の拾い物#
前言:完全なまとめは常に労力と時間を要します。すでに熟知している部分や容易に得られる部分については、まとめる必要はありません。しかし、コードの海を航海する中で、覚えておくべき小さなポイントがいくつかあります。良い記憶力よりも悪い筆記が良いので、単独で一篇を書く必要はなく、すべてを一篇にまとめて、マニュアルとして残すことにしました。
収集が増えるにつれて、大きなポケットは幾つかの小さなポケットに分かれました。それぞれは【言語の探求】【基盤の探求】【設定の万華鏡】であり、それぞれの言語の知識点、四大要素の内容、環境構築の設定に関する内容を記録しています。本稿【コードの海の拾い物】は、主にいくつかのコマンドやツールの使用を記録しています。ツールマニュアルと呼ぶこともできますが、この創意を記念するために「コードの海の拾い物」という名前を残しました。
1 linux#
1.1 コマンド#
diff#
diff file1 file2
:ファイルの違いを比較します:最初のファイルをどのように変更すれば、2 番目のファイルにできるか<
は左側の file1 にのみ存在するファイル / 行を示し、>
は右側の file2 にのみ存在するファイル / 行を示し、|
は両方に存在するが異なることを示します。2,4a2,4
:数字は閉区間で、[2-4]
行はa
dd しなければ file2 と同じになりません【a
dd、c
hange、d
elete】。
diff file1 file2 -y -W 100 | grep ">"
:異なる部分を並べて表示し、各行の幅は 100 です。-y
は並べて表示します:--suppress-common-lines
は異なる部分のみを表示し、--left-column
は同じ部分を左側にのみ表示します。-w
はすべての空白を無視し、-i
は大文字と小文字を無視し、-I <str>
は文字列を無視し、-b
は行末の空白を無視し、文字列中の複数の空白を等しいものと見なします。-C <num>
は異なる部分の上下に num 行のコンテキストを表示します。-q
は同じかどうかのみを表示します。-p
は C プログラムの比較に使用できます。-r
はサブディレクトリを再帰的に比較し、-N
は独自のファイルを "only in xxx" として表示します。diff {dir1} {dir2} -Nrqy
はフォルダ内のどのファイルが異なるかのみを表示し、具体的なファイルは出力しません。
find#
find . -perm /111 -type f -delete
:Linux で実行可能ファイルを削除します(type を加えることでフォルダを省略できます)(find コマンドの参考)。-perm mode
:mode が示すものと一致する必要があります。
-perm /mode
:mode に示されるもので、1 つでも満たせば良いです。例えば111
の場合、1 つの1
が満たされれば良いです。
-perm -mode
:mode に示されるもので、すべてを持っている必要があります。111
は ugo すべてが実行可能で、欠けてはいけません。他の属性は無視します。find -iname readme -o -name *.c -not -size +100k -exec ls -i {} + -fprintf0 file.txt
:
find の検索は完全一致です;論理 AND、OR、NOT;size の単位はデフォルトでバイトではないことに注意;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 の 3 つのアクションの後にはバックスラッシュを加える必要があります)*。 -
a\
:追加、後に文字列が続き、現在の行の下の行に挿入されます。 -
c\
:置換、後に文字列が続き、n1, n2 の間の行を置換します。 -
d
:削除、削除するため、d の後には通常何も続きません。 -
p
:印刷、つまり特定の選択データを印刷します。通常、p は引数 sed -n と一緒に実行されます。 -
s
:置換、通常は正規表現と組み合わせて使用します。例えば、1,20s/old/new/gsed は行単位で処理し、
g
を加えるとすべてのパターンを置換し、加えないと各行の最初のもののみを置換します。
# 2行目の上に行 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 部分では、内蔵関数を実行できます:
print
、length
、sqrt
、match
など。また、system()
を使用して任意の関数を実行することもできます。 BEGIN
ブロックは、アクションを実行する前に何をするかを指定します;END
ブロックは、アクションを実行した後に何をするかを指定します。
# 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
# BEGINとENDの例示。中間のactionが実際に実行されるコマンドです。
## 例えば、何かを累積する必要がある場合、ENDブロックで出力できます。
awk '[pattern] BEGIN{print"始めます"} {action...} END{print"終わりました"}'
例#
例 1 ==awk と sed を使用して阿里雲上の画像を移行する:==
-
阿里雲 oss リポジトリを見つけ、URL を一括エクスポートを選択し、エクスポート後は.csv ファイルで、形式は obj、url です。
-
フォルダを見つけてすべての URL をダウンロードします。
cat export_urls.csv | awk -F, '{print $2}' | xargs wget
-
ダウンロードしたこれらのファイルを新しい oss にアップロードし、新しいリンクを取得します。これにより、元のノート内の画像リンクがすべて無効になりますので、リンクを変更する必要があります。リンクの違いは前のバケットアドレスのみにあり、後の画像名は完全に同じです。したがって、すべてのノートファイルを見つけて、画像 URL の前のバケットリンクを新しい接頭辞に変更すれば良いです。
-
ここで使用する fd コマンドは事前にダウンロードする必要があります。つまり、fd-find です。フォルダに対して再帰的な正規表現検索を行います。これで、すべての画像の移行とリンクの変更操作が完了しました。
fd ".*\.md$" | xargs sed -i 's#https:\/\/xxx.xxx#https:\/\/yyy.yyy#g'
1.2 ツール#
直接:sudo apt install
-
tldr
:too long dont read、簡単なバージョンの man マニュアルで、最初に - u で更新することを忘れずに。 -
fzf
:出力リストに対してファジー検索を行います。 -
colordiff
:カラーバージョンの diff で、diff としてエイリアスできます。 -
fd-find
:より高速な find コマンドで、コマンドはfdfind
、エイリアスは fd、機能が非常に多いです。-h
で確認できます。 -
htop
:より読みやすい top コマンドです。 -
ncdu
:より読みやすい du コマンドで、直接ソートしてフォルダサイズを確認できます。 -
ripgrep
:より強力な grep コマンドで、コマンドはrg
です。 -
bat
:ハイライト機能付きの cat コマンドで、コマンドはbatcat
、エイリアスは bat です。 -
diff-so-fancy
:ダウンロード後に PATH に追加し、chown と chgrp を行うだけで、使用法はgit diff --color | diff-so-fancy
で、エイリアスは gitd です。git diff をより明確に表示できるようにします。状況に応じて使用します。 -
manpages-zh
:中国語の man マニュアルで、使用法はman -M /usr/share/man/zh_CN
、エイリアスはcman
です。
manpages-posix-dev
:POSIX の man マニュアルです。- 注意:vscode では、時々
sigaction
、pthread_xxx
などの関数を認識できないことがあります。これは、"定義" されていないためです。__USE_POSIX
というマクロ(実際には実行時に定義されています)を手動で定義することで、補完を確認できます。 c_cpp_properties.json
で"__USE_POSIX=1",
を定義することも聞いたことがありますが、私のはうまくいきませんでした。しかし、これはマクロを定義する良い場所です。
- 注意:vscode では、時々
-
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
-
expect
:対話型の端末スクリプトツールで、期待される入力のスクリプトを作成できます。expect xxx send xxx
。 -
neofetch
:システム情報と ASCII ロゴを表示するためのツールで、見た目が良いです。
その他の非必須:
-
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
-
man cpp
:cpp の man マニュアルで、いくつかのブラウザ検索の方法 🔗 Linux 自主安装 C++man 手册。
1.3 ターミナル操作#
ctrl-a/e
: 行の先頭 / 行の末尾;Alt-b/f
: 左 / 右に 1 単語
crtl-w
: 左に 1 単語削除;Alt-d
: 右に 1 単語削除
ctrl-u/k
: カーソルの左 / 右のすべての文字を削除
ctrl-y
: 直前に削除した内容を貼り付け
ctrl shift '-'
: 操作を元に戻す^xxx
: 前のコマンドの中の xxx を削除
^foo^bar
: 前のコマンドの中の foo を bar に置き換えます。>
:プログラムの標準出力をリダイレクトします。
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]- ⚠️ 注意を要します。x はメモリをスキャンし、したがって後に続くのは直接メモリアドレスです。一方、p は変数の値を出力しますので、後にアドレスを続けたい場合は、その内容を取得する必要があり、
*
を加えます。 *
について、多くのコマンドではアドレスの前にアスタリスクを加える必要があります。アスタリスクなしのアドレスは関数として扱われます。
- ⚠️ 注意を要します。x はメモリをスキャンし、したがって後に続くのは直接メモリアドレスです。一方、p は変数の値を出力しますので、後にアドレスを続けたい場合は、その内容を取得する必要があり、
-
s n
:C 言語レベルのステップ実行; **si ni
** アセンブリレベルのステップ実行。 -
i [line] / [locals] / [vtbl] / [args] / [checkpoints] / [breakpoints]
-
info line [line] / [function] / [*addr]
:ソースコードに対応するメモリの開始および終了アドレスを表示します。 -
info vtbl [objs]
:オブジェクトの仮想関数テーブルを直接確認します(型変換の形式で印刷することもできます。参照C++ クラスのメモリ割り当て)。基本的な考え方は、オブジェクトの最初のメモリブロックには仮想テーブルがあり、仮想テーブルは関数ポインタの配列です。したがって、オブジェクトアドレスをポインタのポインタに変換し、その内容を取得することで仮想テーブルポインタを得ることができます。この値をポインタのポインタに変換すると、仮想テーブルが得られます。
-
-
set print array-indexes on
:配列を印刷する際にインデックスを表示します。 -
set disassemble next-line on
,disassemble
。 -
set [args] / [register] / [*address] = [val]
:パラメータ、レジスタ値、メモリの値を設定します。 -
jump [*address]
:指定されたアドレスにジャンプして実行し、return [val]
:直接戻ります。どちらもプログラムの進行を変更できます。 -
shell [cmd]
:シェルコマンドを実行します。 -
rbreak [regex]
:すべての正規表現に一致する関数でブレークポイントを設定します。
マルチプロセス / スレッドデバッグ#
gdb [pid]
:実行中のプロセスをデバッグするか、またはその後にattch [pip]
を実行します。
例#
- スタック内容を印刷する(配列を印刷することもできます):例えば、$rsp に 0x1234 が格納されているとします。
p $rsp => (void*)0x1234
x/10dw $rsp
またはx/10dw 0x1234
、つまりx
コマンドを使用してスタックのその部分のメモリを直接スキャンします。p *(int (*)[10])0x1234
スタックのアドレスを配列を指すポインタに型変換し、その配列のvalの値を印刷します(したがって*
を加えます)。つまり、スタックの内容です。p (int [10])*0x1234
スタックの内容を直接配列に変換し、出力します。p *0x1234@6
注意@
の使い方、左側はメモリの値を確認したいもので、後ろの 6 つの変数を直接出力できます。
同様に、p *argv@argc
も、まず内容を取得して変数に変換し、出力します。- まとめると、
x
を使用するとメモリを直接スキャンし、シンプルで粗暴です;p
を使用すると、見たいメモリ領域を変数として出力する必要があります。int でも int 配列でも、どのように型変換しても、基本的な考え方はメモリを変数として出力することです。最良の方法はx
を使用することです。なぜなら、効果は同じで、p
を使用すると rsp の値を取得する必要があるからです。
- 仮想テーブルを確認する 略。
- コアファイルの使用:
gdb debug core
に入った後、disassemble
を実行すると、=>
がエラーが発生した場所を指しています。
パフォーマンス分析ツール#
Valgrind
:メモリリークを確認します。
grof
:
GPROF は、プログラムの実行時間と関数呼び出し頻度を測定するためのパフォーマンス分析ツールで、開発者がプログラム内のパフォーマンスボトルネックを見つけるのに役立ちます。これは GNU プロジェクトの一部で、通常 GCC(GNU コンパイラコレクション)と一緒に使用されます。
GPROF は、プログラムにパフォーマンス分析コードを挿入するために、タイマーコードと関数呼び出しカウンターコードを挿入します。パフォーマンス分析レポートを生成するために、2 つの主要なコンポーネントを使用します。
- gprof コンパイラ:これは、プログラムをコンパイルする際にパフォーマンス分析コードを挿入するための GCC の特別なバージョンです。プログラムをコンパイルする際に
-pg
オプションを使用すると、生成された実行可能ファイルにパフォーマンス分析コードが挿入されます。 - gprof 分析ツール:これは、実行可能ファイル内のパフォーマンス分析コードを解析し、詳細なパフォーマンス分析レポートを生成するための独立したコマンドラインツールです。プログラムの関数呼び出し関係、各関数の実行時間、関数呼び出し回数などの情報を記録し、可読形式で出力します。
GPROF を使用したパフォーマンス分析の一般的な流れは次のとおりです。
- プログラムをコンパイルする際に、
-pg
オプションを使用してコンパイラにパフォーマンス分析コードを挿入するように指示します。例えば:gcc -pg -o my_program my_source.c
- プログラムを実行し、
gmon.out
ファイルを生成します。GPROF が十分なパフォーマンスデータを収集できるように、一連の典型的な操作を実行します。 - プログラムの実行が終了した後、ターミナルで
gprof
コマンドを実行してパフォーマンス分析レポートを生成します。例えば:gprof my_program
- GPROF は、プログラム実行中に収集されたデータを分析し、関数呼び出し関係図、各関数の実行時間の割合、関数呼び出し回数などの情報を含むレポートを生成します。
GPROF が生成したレポートを分析することで、開発者はプログラム内のホット関数(実行時間が最も長い関数)やボトルネック関数(頻繁に呼び出される関数)を特定し、パフォーマンスの最適化を行うことができます。
4 Git#
設定#
git config --global init.defaultBranch main
- 機会を見つけて github のユーザー名を変更します。
--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: こうすると、ターゲットファイルが静的に見つからなくなります。
# 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#
基本操作#
-
マクロを定義する:
q + [a-zA-Z] + your_operation + q
、使用時は@ + [a-zA-Z]
-
Ctrl + a
はカーソルの最初の数字を 1 加算し、Ctrl + x
はカーソルの最初の数字を 1 減算します。 -
行内移動:
f w b e
-
自動補完:
Ctrl + p
-
man マニュアルを検索する:
K
-
:digraphs
ですべての特殊文字をリスト表示します。 -
vim には多くのレジスタがあり、
:reg [xxx]
で確認できます。- a-zA-Z はユーザーレジスタで、録音されたキーを保存するために使用され、vim はこれを変更しません。
- 0-9 はシステムレジスタで、いくつかのシステム定義のものが保存されています。例えば、0 は行の先頭に移動します。
+
はシステム共有クリップボードで、"
は vim の一時クリップボードで、yy dd p
などのコマンドはこれを使用します。両者の相互運用を設定できます。
-
shift
を押しながら左クリックで、vim 内で選択し、コピー&ペーストできます。 -
#
:井号の後の単語を自動的に検索します。 -
-
ctrl w ←↑↓→
でウィンドウを切り替え、ctrl w HJKL
でウィンドウを移動します。 -
:vertical resize +-n
:現在のウィンドウの幅を調整し、vertical
を外すと高さを調整します。 -
デフォルトの
map
は再帰的です。例えば a が b にマッピングされ、b が c にマッピングされると、a は c にマッピングされます。使用モードに応じて、非再帰的なマッピングを行うことができます。つまり、nnoremap/inoremap/vnoremap/cnoremap
(normal/insert/visual/comandline)。
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の3つのウィンドウを開きます。
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 "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 で始まる場合、これは型を示します。 -
kPI
:k で始まる場合、これは定数であり、プログラムの実行中に変更されることはありません。
メンバー変数#
以下の内容の正確性は検討中です。しかし、前後のアンダースコアは一般的に「プライベート」を示します。
-
__foo__: 特殊メソッドを定義しており、一般的にシステム定義の名前、例えば__init__() のようなものです。
-
_foo: 単一のアンダースコアで始まる場合、これは protected タイプの変数または関数を示し、すなわち保護されたタイプであり、自己とサブクラスのみがアクセスできます。後ろにアンダースコアを加えることも同様です。これらはすべて「プライベート」を示します。
-
__foo: 二重アンダースコアで始まる場合、これは private タイプの変数または関数を示し、すなわちプライベートタイプであり、自己のみがアクセスできます。
-
C 言語では、単一アンダースコアで始まる場合、標準ライブラリの変数を示し、二重アンダースコアはコンパイラの変数を示します。
コメント#
ファイルコメント#
/**
* @file ファイル名
* @brief 概要
* @details 詳細
* @author 著者
* @version バージョン番号
* @date 年-月-日
* @copyright 著作権
* @todo 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を定義 */