【技巧】Debug
OI中,很少人能写题一遍过。大部分人在过完编译后,会因为种种原因RE/WA/TLE,这时就需要Debug,这里分享一些Debug的技巧。
干瞪眼
这个没啥说的,看代码就行,有时候犯一些低级错误很容易看出来
编译命令
-Wall
,也就是$Warning All$的缩写-Wextra
,也就是$Warning Extra$的缩写
-Wall
在编译时加上-Wall
命令,比如这样
g++ a.cpp -o a -Wall
这会让你看到一部分粗心犯的错误,比如表达式忘加括号等
-Wextra
g++ a.cpp -o a -Wextra
这会显示一些奇怪的东西,比如类型为int
的函数没有用到返回值,会蹦出警告
C/C++
语法
错误流
C
fprintf(stderr, "a : %d ", a);
和printf
一样,只不过是输出到错误流。也就是说,如果对标准流stdout
进行freopen
写文件后,向stderr
输出的东西还会进入终端而不是文件。所以,向Online_Judge
上交代码时,错误流并不需要注释掉。
C++
cerr << "a : " << a << ' ';
使用方法类似cout
,区别是向错误流输出,交题时也不需要注释掉。
assert.h
/cassert
这里提供了一个函数assert(bool)
,在这个函数里传一个表达式,如果不满足条件,它会直接退出程序,并在终端显示错误信息。比如,我为了防止写的SegmentTree
出现问题,就加了这么一句
void Modify(int now, int l, int r, int nl, int nr, int k) {
assert(r >= l);
if (l == nl && r == nr) {
tag[now] = (tag[now] + k) % mod;
return;
}
int mid = nl + nr >> 1;
tree[now] = (tree[now] + k * (r - l + 1) % mod) % mod;
if (r <= mid) {
Modify(now << 1, l, r, nl, mid, k);
} else if (l >= mid + 1) {
Modify(now << 1 | 1, l, r, mid + 1, nr, k);
} else {
Modify(now << 1, l, mid, nl, mid, k);
Modify(now << 1 | 1, mid + 1, r, mid + 1, nr, k);
}
}
这样,它会在$l$>$r$的时候退出程序,并显示错误信息,我就能知道是否是这个函数出现了问题。
gdb
这个东西就很好用了,刚学会使用dev-cpp
时就会用图形化的gdb
了,后来因为OI考场上没有dev-cpp
,所以学了命令行的gdb
。并且使用Emacs
自带的gdb-many-windows
插件特别方便,比图形化还丝滑。
编译命令:
g++ a.cpp -o a -g3
然后使用gdb
打开,就可以debug了,常用的操作有这么几个:
- 设置断点:
b
然后一个数字,为断点行数 - 查看变量:
display
然后加表达式,注意在namespace
中的需要加namespace名 ::
- 跑代码:
n
,疯狂按就好了
重构
要没啥办法就重构吧。
版权属于:Noire02
本文链接:https://noire02.moe/archives/debug.html
北京第三区交通委提醒您:复制千万条,版权第一条。转载删出处,博主两行泪。
最后一次更新于2022-10-09
0 条评论