編程要保持簡單(KISS, keep it simple and stupid)。
?
算法競賽中的輸入輸出框架:
輸入數據保存在文件中,輸出數據也保存在文件中。
幾乎所有算法競賽的輸入數據和標準答案都是保存在文件中的。
使用文件最簡單的方法是使用輸入輸出重定向:
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
重定向包括scanf、printf在內的所有鍵盤輸入、寫屏幕輸出的函數。
?
要明確規則:是標準輸入輸出還是文件輸出輸出,如果是文件輸入輸出,是否禁止用重定向方式訪問文件。
?
?
條件編譯以去掉重定向
?
#define LOCAL#ifdef LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
?
?
?
?
?
C++重定向輸入流
?
#include <fstream>
ifstream cin("test.txt");
?
?
?
?
?
如果禁用重定向方式:
?
FILE *fin, *fout;
fin = fopen("data.in", "rb");
fout = fopen("data.out", "wb");
int x;
while(fscanf(fin, "%d", &x) == 1) {...}
//scanf返回成功讀入的變量個數;忽略空格、TAB和回車;Windows下Ctrl+Z結束輸入,Linux下Ctrl+D結束
fprintf(fout, "%d", x);
fclose(fin);
fclose(fout);
重定向和fopen兩種方法各有優劣。
?
重定向方式寫起來簡單、自然,但是不能同時讀寫文件和標準輸入輸出;
fopen的寫法繁瑣,但是靈活性較大(如可以反復打開并讀寫文件)。
如果想把fopen版的程序改寫成讀寫標準輸入輸出,只需賦值"fin=stdin; fout=stdout",并且去掉fclose()語句即可。
?
?
gcc編譯器的使用
MinGW環境下的gcc和Linux下的gcc一致性較好,并且免費。
到www.mingw.com下載安裝包,在安裝時選擇g++編譯器。
?
編譯命令:
gcc test.c -o test ?//將源文件test.c編譯為test.exe文件。
gcc test.c -o test -Wall ?//顯示警告信息
gcc -lm test.c -o test -Wall ?//-lm 讓編譯器連接數學庫math.h
gcc -DLOCAL test.c -o test -Wall ?//用于條件編譯,為源程序定義LOCAL變量
?
可以用-o1,-o2,-o3對代碼速度進行優化。
速度上,直接編譯 < -o1 < -o2 < -o3。
由于某些優化可能會誤解程序員的意思,一般比賽不推薦使用。
?
gdb簡介
調試器,gcc的最佳拍檔
編譯時加-g選項,以顯示行號。
gdb test.exe
list ? ?顯示下10行
list- ? ?顯示上10行
break ? ?在指定行號或指定函數處設置斷點,如b main ? ? ? ?delete breakpoint 斷點編號
run ? ?運行程序,直至斷點或結束
continue ? ?從斷點處繼續運行
next ? ?跳過執行 step over
step ? ?跳入執行 step in
?
在提示符下,直接按Enter鍵等價于再次執行上一條指令
?
until ? ?讓程序執行到指定位置,如until 9;//執行到9行 ? ? ?until doit;//執行到doit函數
print ? ?打印出一些變量的值
info locals ? ?顯示所有局部變量,info breakpoint//顯示斷點信息
display ? ?把一個表達式設置為display,當程序每次停下來都會顯示其值,如display i+1000
enable display
disable display
delete display 編號
clear ? ?向break一樣清除斷點
?
gdb高級功能
bt ? ?最常用的棧幀命令,其他命令可通過help stack學習
commands ? ?可以指定在某個斷點處停下來后所執行的gdb命令
ignore 斷點編號 跳過次數 ? ? 命令可以讓斷點在前count次到達時都不停下來,
condition 斷點編號 生效條件? ? 可以給斷點加一個條件 condition 2 i==5,讓該斷點僅當i=5時有效。
?
特殊斷點watchpoint ? ?
watch a ? ?在變量a 修改時停下,并顯示修改前后的變量值
awatch a ? ?變量a被讀寫時都會停下來
rwatch a ? ?變量a被讀時停下來
?
gdb可以自由調用函數,不管是源程序中新定義的函數還是庫函數。
call 函數名 ? ??
注意,如果學過宏和內聯函數就會知道,很多看起來是函數的卻不一定真的是函數,或者說,不一定是調試器識別的函數。
print ? ?condition ? ?display ?命令都可以像call這樣使用C/C++函數。
?
?
?