调试和对拍

调试和对拍

真正赛场上,你是单独在作战

OI赛制又决定了你不可能立刻知道程序的正确性

所以,写完代码、跑过样例以后,把它直接就放在一边绝对是错误的做法,你需要进一步检查正确性

 

调试

程序输出错误结果或崩溃时,你就拿到了一组可以用于调试的宝贵输入数据(叫hack数据,就是能把你

的程序卡掉)

接下来你要逐步跟踪程序的运行过程,找到问题所在,这就叫调试

调试的时候,你可以控制程序一步步向下执行,并且可以查看所有变量在当前的值

如果变量的取值不符合它的预期,你就找到了问题。接下来结合算法流程,看看哪里写错了。

 

在Dev-CPP里,你可以这样调试

单击编辑器行号:设置一个断点。

F5 :开始调试。调试器将从main() 处不断模拟运行,直到碰到断点或程序结束

F6 :停止调试

F7 :让程序向下执行一行,但不进入本行中任何函数

F8 :让程序向下执行一行,进入本行的函数。如果这行有多个函数,进入一个函数后出来的那一下按的

是F7 的话,出来以后就会直接执行完这一行的所有其他函数,不会进去;如果出来那一下按的是F8 ,

还会进入本行其他函数

alt+A :添加一个变量,这样在左边栏里面你就能看到这个变量的取值

alt+S :让程序自动向下运行,直到碰到断点或者程序结束

Tips: 你可以通过设置断点+ alt+S + 取消断点的组合快速在程序里面跳转

 

对拍

可供调试的hack数据怎么来?

我们要写一个批处理文件,帮我们不断:

1. 随机生成数据

2. 运行我们用于提交的程序

3. 运行我们另写的一个绝对正确、但是可能很慢的暴力程序。你可以选择用很简单的算法去实现一个

数据规模更小的同一问题,这样实现难度和错误概率都会大大降低

4. 调用命令比较两个程序的输出是否一样,如果一样,重复1.,否则暂停,等你来调试

接下来你就拿着hack数据去调试

批处理文件dp.bat

:loop
data.exe >input.in
my <input.in >my.out
std <input.in >std.out
fc my.out std.out
if %errorlevel% == 1 pause
goto loop

解释:

循环标记

运行数据生成器data.exe ,输出数据到input.in

运行my.exe ,你的主代码。重定向输入文件为input.in ,重定向输出文件为output.out 。(注意你

要删掉freopen 语句,或者freopen 直接定向这两个文件)( freopen 优先级高于这里的重定向)

运行std.exe ,暴力程序。输入重定向input.in ,输出重定向std.out

比较两个输出文件是否一样,进行暂停或者循环

data.cpp

#include <bits/stdc++.h>
using namespace std; int Rand(){ // Windows下rand()的范围是0~32767,可能无法满足需求。因此手写一个随机到 2147483647的 int res = 0; for (int i = 0; i < 31; i++) res += (1 << i) * (rand() % 2); return res; } int main(){ srand(time(NULL)); // 重要!设置随机种子,否则跑出来的数据都是一样的。这样写 每一秒会换一组数据 // 接下来,按照题目要求输出数据 int n = 10, q = 5; printf("%d %d\n", n, q); for(int i = 1; i <= n; i++) printf("%d ", Rand() % 100); printf("\n"); for(int i = 1; i <= q; i++){ int l = rand() % n + 1; int r = l + Rand() % (n - l + 1); printf("%d %d\n", l, r); } return 0; }

 

posted @ 2021-07-23 22:53  limited_Infinite  阅读(207)  评论(0编辑  收藏  举报
// //返回顶部 //返回顶部按钮