debug检查单
当你的程序没有AC时,请按此检查单一项一项检查。
首先看这个
电脑坏了,键盘鼠标坏了,IDE坏了,账号上不去了,电脑没电了,运行不了代码了,题目/数据有问题……
重启IDE,再不行就重启电脑,还不行就举手向监考老师提问。
做题时一字不落地阅读整个题目(包括提示、Hint)了吗?
编译时打开「显示所有警告信息(
-Wall
)」开关了吗?能看懂编译器给出的警告吗?妥善处理了这些警告吗?
在
scanf
、printf
函数里用%lld
输入输出long long
类型变量时,会产生这样的警告:1
2[警告] unknown conversion type character 'l' in format [-Wformat=]
[警告] too many arguments for format [-Wformat-extra-args]这是可以忽略的。其它的警告,一般都不能忽略,需要消除。
然后,请根据你的具体错误选择对应的检查单
怎么看?
比赛页面左侧,点击「我的提交」:
把鼠标放到「结果」那一栏上:
CE(Compile Error)
你的程序存在语法错误(C / C++ 最常见的是缺少分号、缺少括号、使用了中文标点符号或者函数调用错误等等)或者OJ系统不支持的写法(较少见)。
此时应当仔细检查代码在本机能否通过编译,改正后再次提交。
保存文件时,后缀名是
.c
而不是.cpp
吗?编译器的标准选到
ISOC99
了吗?能看懂编译器给出的报错信息吗?用翻译软件翻译一下呢?
输出特殊字符时,合理地进行转义了吗?
是否使用了不在标准库中的函数?
例如:
strrev
报错:[错误] ld returned 1 exit status
:
使用的各库函数名、关键字拼写正确吗?
常见易错:
main
、printf
、scanf
、sin
、void
之前运行程序打开的控制台(黑框框)关掉了吗?
实在不行,新建一个
.c
文件,并把你原来的代码粘贴进去,再编译试试。
报错:[错误] stray '\xxx' in program
:
程序里有全角(中文)符号吗?
半角符号(正确):
1
. ; : ' " ! ( ) [ ]
全角符号(错误):
1
。 ; : ’ “ ! () 【】
WA(Wrong Answer)
你程序输出的结果有错误,与期望输出不匹配(也有可能是因为缺少了必要的换行和空格)。
请检查你的程序是否出现了致命的逻辑错误,当然有的时候是因为手滑。
用到的运算有可能产生数据溢出吗?数据溢出的情况得到妥善处理了吗?
例如:\(a\) 和 \(b\) 都是
int
类型的变量,那么 \(a+b\) 、\(a-b\) 和 \(a\times b\) 都有可能超过int
型上下限,从而产生数据溢出。即便你使用一个long long
类型的变量承接表达式的值,可是表达式计算过程中已经发生了溢出,仍然会导致结果错误。请对照下面的代码,思考错误的原因和正确的处理方式。
1
2
3
4
5
6
7
8
9
10
11
12int a,b;
a=2147483647;
b=2;
long long c,d;
c=a+b;
d=a*b;
printf("%lld %lld\n",c,d);
//错误,输出-2147483647 -2
c=(long long)a+b;
d=(long long)a*b;
printf("%lld %lld\n",c,d);
//正确,输出2147483649 4294967294再例:有些情况下,即便题目保证了输入数据和结果都在
int
范围内,但是中间计算过程仍然会发生溢出。1
2
3
4
5
6
7int a,b,c;
a=2000000000;
b=2000000000;
c=5000;
int d=(a+b)/c;
//在本代码中,abc,以及d本应得到的值都在int范围内
//但a+b已经超过了int范围,因此会得到错误的结果。如果程序用到了浮点数,那么合理地处理了浮点误差和
NaN
吗?例如:不能用
==
判断两个浮点数是否相等,计算整数的整数次方时不要用pow
函数,浮点数除法的除数、\(\log (x)\) 里的 \(x\) 是否可能是 \(0\)。希望其值为浮点数的算式,值真的是浮点数吗?
请对照下面的代码,思考错误的原因和正确的处理方式。
1
2
3
4double a=1/3;
printf("%f",a);//a=0
a=1.0/3.0;
printf("%f",a);//a=0.3333...程序的输入部分输入的内容真的是正确的吗?
在输入结束以后,把输入的变量输出一下看看。
输出特殊字符时,合理地进行转义了吗?
重复声明了相同名称的变量吗?
错误示例1:
1
2
3
4int i;
for(int i=1;i<=n;++i){
//i在不同作用域中被重复声明
}错误示例2:
1
2
3
4
5
6
7
8int x;
long long myPow(int a, int x) {//函数形参和全局变量重复
long long ans = 1LL;
for (int i = 1; i <= x; ++i) {
ans *= a;
}
return ans;
}使用
printf
语句输出时,类型标识符和输出的变量类型的对应关系是正确的吗?从
int
改成long long
的时候,输出的%d
改成%lld
了没?输出给定的字符串时,是从题目上复制粘贴的吗?
特殊情况、边界情况考虑了吗?
例如:区间合并,输入只有一个区间;进制转换,被转换的数为零……
在声明任何变量、数组、指针、字符串时,给它赋予了合理的初始值吗?
除非你这个变量(数组、指针、字符串……)是声明了以后立刻输入的,否则必须赋予初始值,不管是全局还是局部。
多组输入输出问题中,在每组开始时,给用到的变量、数组清零或重新初始化了吗?
其实不只是每组开始时,最好能检查一下整个程序里该初始化的地方都初始化了没。
多组输入输出问题中,在输出每组答案以后换行了吗?
REG(Runtime Error)
这种错误分很多种,具体请百度。最常见的是 SIGSEGV,一般是因为访问了不存在的数组元素或者函数调用过多导致爆栈。
在本地,这样的错误往往表现为输入了数据以后,程序卡死,过一会儿后结束,然后程序的返回值不是零,例如:
... with return value
后面的那个 3221225620
就是程序的返回值。当它不是 0
时,说明你的程序发生了运行时错误。
数组的长度开得够大吗?
如果你习惯下标从 \(1\) 开始,那么数组的长度要加一。
字符串注意
\0
也要占一位。\(10^x\) 就是 \(1\) 后面有 \(x\) 个 \(0\) 。
字符串做拼接操作时,是否预留了足够的空间?
用变量做数组的长度了吗?
这种写法是错误的,请思考为什么:
1
2
3
4
5
6int n;
int a[n];
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}使用
scanf
语句时,加&
符号了吗?字符串不用加,别的都得加。
使用除法
/
或取模%
运算时,除数或模数有可能是零吗?有可能因为数据溢出而导致意外的 \(0\) 。例如:
递归调用函数的层数是否太多了?能改写成循环吗?
例如:计算阶乘、二分法等,都要写成循环
在使用下标访问数组元素时,下标会小于 \(0\) 或超过数组长度吗?
长度超过十万(\(10^5=100000\))的数组,开成全局的了吗?
主函数结束的时候写
return 0
了吗?
TLE(Time Limit Exceeded)
你的程序可能因为时间效率不高或者出现了死循环,所以未能在规定的时限内运行结束
在本地,这样的错误往往表现为输入数据以后程序没有反应,也不退出。
程序是否有死循环?
检查方法:
在每个模块前加入调试输出语句,例如:在输入完成后加一行
1
printf("输入完成!\n");
运行程序,找到程序在哪个循环处死循环了
在出现死循环的循环中,输出循环控制变量,进行详细检查。
多组输入输出问题时,是否设置了正确的终止条件?
scanf(...)!=EOF
、gets(...)!=NULL
递归调用函数的效率是否太低了?能改写成循环吗?
例如:计算斐波那契数列
评测机一秒只能运算 \(10^8\) 次,你循环的次数是否太多了?
OJ上题目的时间限制大部分是\(1000\text{ms}\),而\(1000\text{ms}\)评测机能够计算的次数大概不超过1亿次。所以当你的代码中
for
循环,或while
循环循环了超过一亿次时,请果断更换解题方法。
MLE(Memory Limit Exceeded)
你的程序占用的内存超过了规定值,可能是因为使用了过大的数组,也可能是没有做到内存释放(较少见)。
请计算程序所占用的内存,检查是否超过了限制。
一般来说,一道题的内存限制是 \(65536 \text{KB}\),即 \(65536\) 千字节。
一个
int
占用 \(4\) 个字节,与此同时,一个空的程序还要占用一定的基础内存。也就是说,你最多只能开长度为 \((65536-1200)\times 1024/4 =16470016\) 的int
数组。保险起见,最多开 \(10000000=10^7\) 长度的
int
数组。
PE(Presentation Error)
你的程序几乎能AC了,但是和标准输出数据有点细微的差距(大小写,空格数量,换行数量之类的)。
此时应当仔细观察题目给出的输出样例,确认格式无误(选中数据粘贴到编辑器最为稳妥)。
- 认真阅读题目的「输出格式」部分了吗?
- 多组输入输出问题中,在输出每组答案以后换行了吗?
OE(Other Error)
其他错误,详询老师或者助教。
- 把它先当REG(Runtime Error)看。
作者:梁秋月、逐月的游星
本站的运行成本约为每个月5元人民币,如果您觉得本站有用,欢迎打赏: