在提高組的考試中要求使用noi linux,因此了解一下如何在linux環境下編程是很有必要的。
linux環境下的基礎操作
命令行操作
1,使用Ctrl + Alt + T召喚出終端。
2,基礎指令:
1,cd
使用方法:cd + 文件目錄
效果:使終端所在的目錄切換到指定文件目錄,但是每次cd只能不斷深入某個文件夾,如果要退出這個文件夾則直接使用cd,后面不加任何東西
如果文件名太長懶得打的話,可以打一半然后按Tab鍵,如果這時你給出的部分文件名已經可以使電腦確定出唯一的一個文件的話,那么將會自動補全這個文件名,否則會給你列出可能的文件名。
2,l
列出當前目錄下的文件和文件夾,一般和cd配合使用。
3,./ 程序名
用來運行一個程序
4,> 和 <
有時候你並沒有在程序中打文件輸入和輸出,然后你需要使用文件輸入輸出,但是又懶得打文件輸入輸入+重新編譯。
這個時候使用這個指令就很方便。
./work < in.in > out.out表示運行work文件,從in.in中讀入,輸出到out.out中。
編輯器
1,gedit的使用
gedit是我常用的編輯器,基礎功能都有,界面比較簡潔,因為noi linux下默認打開.cpp文件的軟件是emacs,所以如果要使用gedit的話,建議先新建一個.cpp文件,然后右鍵選擇打開.cpp的軟件,選文本編輯器(gedit),然后就會默認使用gedit打開.cpp文件了。
一般來說,打開gedit后第一反應應該是進行一些基礎的設置。
這里推薦的設置是:
選擇編輯,打開首選項:
1,勾選顯示行號.
2,勾選右邊對齊線顯示的位置.(這個一般用於提示自己每行的代碼不要過長,會使得代碼美觀一點)
3,勾選突出顯示當前行.(方便定位當前光標所在的位置)
4,勾選突出顯示匹配的括號.
5,勾選啟用自動縮進.
6,勾選在保存前創建備份文件(每次都選了,但是從來沒用到過,以防萬一吧)。
7,配色方案我喜歡用暗色的,感覺光線柔和一點,這個根據個人喜好選擇即可.
設置完后關閉首選項。點擊F9,然后切換到文件瀏覽器模式(我用的ubuntu16.04,叫法可能不同,但差別不會很大)。這個模式有什么好處呢?
1,你可以直接右鍵在當前目錄下進行新建文件等一系列關於文件的操作(但是好像不能復制粘貼文件),而不需要再打開文件夾進行一系列操作。
2,你可以直接右鍵在當前目錄下調出命令行,從而避免繁瑣的cd操作,尤其是在有中文目錄的情況下這個會很實用。
3,可以快速切換到當前目錄,還可以快速打開當前目錄下的文件夾。
1,如果要快速上下翻動可以關閉數字鎖定,然后利用小鍵盤快速翻動,1,7分別對應翻到底部和翻到頂部。2, 8則是小幅度的翻動,3和9是較大幅度的翻動。
2,gedit自帶替換的功能(Ctrl + H),這個功能一般用於你之前使用了某個變量名,而你現在又想使用這個變量名,這時你可以用這個功能快速替換之前的同名變量,避免名字沖突。
3,gedit的搜索功能(Ctrl + F),搜索了之后會高亮匹配項。為了防止誤選建議勾選區分大小寫和匹配整個單詞。
4,快速跳轉到某一行(Ctrl + I).
以上快捷鍵根據版本不同,可能略有區別,如果不能使用就在上面的搜索選項中查看對應快捷鍵即可。
5,你也可以在終端中使用gedit + 文件名來快速創建一個文件,並在gedit中打開。
程序編譯
最基礎的編譯命令:g++ 1.cpp
編譯出來的文件叫做a.out
使用./a.out可以運行這個程序。
當然還有一些額外的常用指令,使用的時候直接加在后面即可。
1,-o
可以讓你命名編譯出來的文件,比如g++ 1.cpp -o work可以使得編譯出來的文件叫做work
2,-Wall -Wextra
這兩個指令的作用差不多,可以給你一些額外的警告和提示,用於避免一些NC錯誤。
比如當你在if的判斷條件中把x == y寫成了x = y時它就會警告你。但這兩個指令帶來的警告不會使編譯失敗。
3,-O2
顧名思義,開啟O2選項,O2是一種更高級別的優化,平時默認是O1,如果在沒有開O2的情況下,大多數STL會跑得很慢(sort之類的除外)。
4,-g
開啟gdb
以下是一個示例:(編譯1.cpp為work,並運行此程序 同時開啟O2優化)
g++ 1.cpp -g -Wall -Wextra -o work -O2
./work
5,文件調用。
這個應該都會吧,一般都是使用freopen來實現文件調用。
int main()
{
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
pre();
build();
work();
fclose(stdin);
fclose(stdout);
return 0;
}
程序調試
gdb的使用
gdb是一個功能很強大的調試軟件,一般來講是用於動態調試,跟devc++的單步跟蹤差不多,但功能更多,更穩定。因為使用gdb時往往需要一步步的查看程序運行的情況,所以可能調試起來會比較慢,但可以通過一些小技巧來加快調試速度,這個可以自己體會&總結。
首先是一些基礎操作;
還有一些不常見操作;
對拍
有時候你打出了一道題的正解,但你可能並不放心你的正解是否是正確的,這時一個很常見的驗證方法是對拍。
首先你需要以下程序:
1,正解(或者是一些針對部分數據的高級暴力也是可以的)
2,暴力
3,造數據的程序
4,對拍程序
正解和暴力怎么寫就看你自己了,這里簡單講一下如何造數據和寫對拍
造數據程序:
#include<bits/stdc++.h>
using namespace std;
#define R register int
int main()
{
freopen("in.in", "w", stdout);
srand(time(0));
int n = rand() % 1000 + 1, m = rand() % 1000 + 1;
n = 1000, m = 1000;
printf("%d %d\n", n, m);
for(R i = 1; i <= n; i ++) printf("%d ", rand() % 50000 + 1);
printf("\n");
for(R i = 1; i <= m; i ++)
printf("%d\n", rand() % n + 1);
fclose(stdout);
return 0;
}
這是一份造數據的程序,首先一般會寫一個文件輸出,表示造出的數據放入要某個文件里。
srand();是給rand()指令重新指定一個種子,否則你將會每次都造出一樣的數據,因為rand實際上是通過一個式子不斷的計算得到隨機值(不是真隨機),所以如果種子一樣,那么隨機出來的東西也將是一樣的。
然后中間的就根據題目的輸入格式自己寫了。
一般在開始會在題目給點范圍內隨機一個數據大小,但是有時候為了特殊目的(想測極限數據,要用小的錯誤數據調試等),可能會在下面強制指定一個數據大小。如上面程序中的n = 1000, m = 1000;
對拍程序:
#include<bits/stdc++.h>
using namespace std;
#define R register int
int main()
{
for(R i = 1; i <= 1000; i ++)
{
system("./make");
system("./work > out.out");
system("./work1 > out1.out");
if(system("diff -bB out.out out1.out"))
{
printf("error in %d\n", i);
return 0;
}
else
{
printf("passed... %d\n", i);
system("sleep 1");
}
}
return 0;
}
對拍一般都是一樣的,所以不會的話背下代碼即可,當然理解一下就更好記了。
system();中的指令會起到跟你在終端中輸入這串指令一樣的效果。
diff -bB out.out out1.out是在忽略行末空格和換行的情況下對比兩個文件,如果不同的話會給你返回一個非0的值,因此如果不同的話就輸出錯誤並終止程序,這樣的話你就可以保留使你錯誤的那個數據點。
否則的話輸出passed... 當前數據點。提示你過了這個點。
因為一般都是寫的srand(time(0));所以如果時間是一樣的話,種子也會是一樣的,隨機出來的東西也會是一樣的,所以這個時候多次對同一組數據進行測試就沒有意義了。所以一般會使用sleep命令來延遲一秒的時間以滿足每次測試的時候種子都不同。
快速編譯程序:
這個可能比較冷門,有時候會比較方便。
#include<bits/stdc++.h>
using namespace std;
string name, tmp, s;
int main()
{
cin >> tmp >> name;
s = "g++ " + tmp + ".cpp -g -Wall -Wextra -o " + name;
system(s.c_str());
return 0;
}
運行這個程序,然后輸入你要編譯的文件名+你要編譯為的程序名,就可以快速將這個文件編譯為指定程序名。從而避免每次都要打一長串編譯命令