本文於 2021/9/21 重寫
0. 關於終端
打開 NOI Linux,按 Ctrl+Alt+T
,就會彈出來一個窗口,這就是 Linux 下的終端,NOI Linux 中使用的終端是 bash
大概長這個樣子↑
可以在右上角的 Preferences 中的 Profiles 一欄中設置終端的顏色和主題
比如可以把這玩意搞成透明的,顏色也整好看一些↑
這里的終端可以理解為和系統文字交互的窗口,好處是非常靈活,功能強大
1. 基本命令和 Tab 使用技巧
使用 ctrl+C
可以殺掉當前終端運行的程序,會顯示為 ^C
0. 終端下的文件系統
注意所有的斜杠都是 /
打開終端,默認的位置是 ~/
,也就是 /home/$USERNAME/
,可以理解為用戶的主文件夾,文件系統的 GUI 的主文件夾就是這個玩意
.
表示當前文件夾,可以試一試 ls
和 ls .
的結果是一樣的,運行程序的之后也要寫 ./exe
,就是為了讓文件系統找到當前文件夾
..
表示父文件夾,就是上一級文件夾
/
表示根目錄,但用不到,所以不過多介紹
和我們常常理解的文件路徑一樣,終端中的路徑也是由 文件夾/文件夾/.../文件(夾)
組成的
特別地,如果你在第一個文件夾前面沒有加上 /
或 ~/
,那么就會在當前目錄中的子文件夾中開始尋找,否則就會從 根目錄/主文件夾 開始找
1. 進入目錄 cd
用法:cd 文件夾
,注意一定要是一個文件夾,按照我們上面的路徑形式
2. 列表 ls
ls 是 list 的縮寫
用法 ls [目錄,默認為 .] [參數]
,即在參數的要求下列出給出目錄下所有文件
主要有用的參數是 -l
,會顯示所有文件/文件夾的權限、大小等信息
最左邊是權限系統,具體我也不太懂,大概就是有 d
的是文件夾,剩下的有 x
的是可執行,rw
分別表示讀寫權限
中間是作者,然后是大小 (Byte),然后是修改時間
綠色的是可執行,藍色的是文件夾,白色的是普通文件
3. 建立文件夾 mkdir
mkdir 是 make directory,即創建目錄的縮寫
用法是 mkdir 文件夾名
,會在當前文件夾下面建一個子文件夾
4. 拷貝文件 cp / 刪除文件 rm
cp 是 copy 的縮寫,rm 是 remove 的縮寫
cp [參數] 文件 目標位置/文件
,將文件考到目標位置下(保留原來名字)或拷到文件的文件夾下,該名叫文件。需要注意的是默認參數是 -f
,即拷貝文件,如果要拷貝文件夾就要用 -r
,而不管是不是文件夾都拷貝用 -rf
rm [參數] 文件/文件夾
同理,刪除指定文件夾或文件,要加 -f
、-r
或 -rf
5. 移動/重命名 mv
mv 是 move 的縮寫
mv 舊文件 新文件
,注意這里舊文件和新文件可以包含路徑
6. 內置比較命令 diff/cmp
diff 是 differance 的縮寫,獲取兩個文件的不同,基本會使用 diff 文件 文件 -Z
來比較兩個文件,其中 -Z 表示忽略空格和換行(由於換行 windows 和 linux 可能不同)
cmp 是按字節比較兩個文件
7. 打印到終端 cat
我也不知道為啥叫 cat
cat
會重復輸入的內容
可以給 cat
后面跟文件,也可以重定向輸入輸出(后面會講)
2. 在終端下編譯、運行程序
使用 g++ 編譯
NOI 系列賽、CSP 使用的都是 gcc,或者叫 g++,NOI Linux 2.0 上代的是 9.3.0,默認 c++ 版本是 c++14
試試在終端里輸入 g++ --version
,他會告訴你這是 9.3.0 版本的
g++ 的用法是 g++ [參數] ... [參數] 源文件 ... 源文件 [參數] ... [參數]
常用的參數包括:
-o exename
:將輸出的可執行文件輸出到 exename-lm
:使用 cmath 必須要加-Wall -Wextra
大概全部/額外警告-O0/O1/O2/O3/Ofast
:開啟對應優化-std=c++xx
:使用 c++xx 標准,其中 xx 可以使 98/11/14/17-fsanitize=address,undefined
:開啟 ason,可以幫助你解析越界或UB行為,注意會讓你的程序變慢
運行程序
只需要一行:文件名稱
,注意這里需要包含所在文件夾,比如當前目錄下有 a.exe
,直接輸入 a.exe
會報錯,必須是“當前文件夾”下的 a.exe
才可以,所以要用 ./a.exe
3. 程序運行的計時、重定向輸入輸出、對拍
給終端上運行的程序計時
在運行文件命令前面加上一行 time
就可以得知程序占用的時間(系統時間/用戶時間)
在運行文件命令后使用 < 文件
和 > 文件
可以重定向 stdin/stdout
,即 stdin
或 stdout
從指定文件而不是終端讀取/寫入,可以自己進行嘗試
生成隨機數
一般我們在生成隨機數的時候都會用 srand(time(0))
或 srand(clock())
配合 rand()
生成隨機數,但 time()
和 clock
的計時精度不高,導致拍了很多組生成的隨機數據都是一樣的,c++11
之后有了 std::mt19937
的隨機數生成器和 std::chrono
的高精度計時器,所以我們可以這樣寫:
std::mt19937 mtrnd(std::chrono::system_clock::now().time_since_epoch().count());
后面的計時器是微秒級的,而 mt19937
的循環節非常長,非常隨機,而且得到隨機數的話是 ll 類型,可以直接用 mtrnd()
調用隨機數
對拍
下面給出我寫的一個對拍
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
cout << fixed << setprecision(15);
cerr << fixed << setprecision(15);
int t = 1e6;
for(int i = 1; i <= t; i++) {
cerr << "test #" << i << "... ";
system("./gen.exe > in");
system("./std.exe < in > ans");
system("./sol.exe < in > out");
if(system("diff -Z out ans")) {
cerr << "WA!" << "\n";
return 1;
}
cerr << "AC!" << "\n";
}
return 0;
}
使用 system()
函數可以視作在終端下執行對應的命令,而 diff
和 cmp
命令是有返回值的,不一樣即為 1,所以就可以這么寫
4. 使用終端召喚編輯器(emacs/gedit)
可以試試 emacs b.cpp &
,會新建一個空的文件,而在彈出來的窗口里編輯好點擊保存之后,當前文件夾會多出一個 b.cpp
的文件,內容剛好是剛剛編輯的內容
(咕着先