编程要保持简单(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++函数。