代码调试技巧【OI缩水版】

1 小黄鸭调试法

来自维基:小黄鸭调试法是软件工程中使用的调试代码方法之一。

就是在程序的调试、纠错或测试过程中,耐心地向小黄鸭解释每一行程序的作用,以此来激发灵感。

2 输出中间值

在关键位置输出值

适用于以下一些:
数据输入,输出
死循环,盏溢出
过程值,语义分析(较痛苦
much more :

适用于细节手误没看到。
操作函数化,分块测试,能独立测试的算法部分先验证其正确性。
对照神犇代码,用一样的部分替换掉自己代码,并测试答案。

3 断点、单步

GDB调试技巧

我也不会啊,我也很无奈啊。

4 对拍

大量随机数据测试,正确性判断

步骤

  1. 写好程序和暴力
  2. 写好数据生成器
  3. 写好对拍文件

关于对拍脚本

”Windows 环境下对拍文件.bat
“用重定向的方式代替代码内的文件输入输出
@echo off "关掉屏幕显示
:loop "循环
  rand.exe %random% > input.txt “随机生成数据
  test.exe < input.txt > test.out ”运行错解
  std.exe < input.txt > std.out “运行标程
  fc test.out std.out “比较输出
  if errorlevel 1 pause ”如果不同就停下来
goto loop “重复循环
#Linux 环境下对拍文件.sh
#!/bin/bash
while true; do
  ./rand > input.txt
  ./test < input.txt > test.out
  ./std < input.txt > std.out
  if diff std.out test.out; then
      printf "AC\n"
  else
      printf "Wa\n"
      exit 0
  fi
done

关于数据生成器

#include<cstdlib>
#include<ctime>
int random(int n){//返回一个[0,n-1]的随机整数。
    return (long long)rand()*rand()%n;
}
int main(){
    srand((unsigned)time(0));
    return 0;
}

1.随机生成整数序列

int n = random(100000)+1;
int m = 1000000000;
for(int i = 1; i <= n; i++)
    a[i] = random(2*m+1)-m;

2.随机生成区间列

for(int i = 1; i <= m; i++){
    int l = random(n)+1;
    int r = random(n)+1;
    if(l > r)swap(l,r);
    cout<<l<<" "<<r<<"\n";
}

3.如何生成一棵树?

for(int i = 2; i <= n; i++){
    //从2~n之间的每个点i向1~i-1之间的点随机连一条边
    int fa = random(i-1)+1;
    int val = random(1000000000)+1;
    cout<<fa<<" "<<i<<" "<<val<<"\n";
}

4.如何生成一张图?

pair<int, int>e[1000005];//保存数据
map<pair<int,int>,bool>h;//防止重边
//先生成一棵树,保证联通
for(int i = 1; i < n; i++){
    int fa = random(i)+1;
    e[i] = make_pair(fa,i+1);
    h[e[i]] = h[make_pair(i+1,fa)] = 1;
}
//再生成剩余的m-n+1条边
for(int i = n; i <= m; i++){
    int x, y;
    do{
        x = random(n)+1, y = random(n)+1;
    }while(x==y || h[make_pair(x,y)]);
    e[i] = make_pair(x, y);
    h[e[i]] = h[make_pair(y,x)] = 1;
}
//随机打乱,输出
cout<<n<<" "<<m<<"\n";
random_shuffle(e+1,e+m+1);
for(int i = 1; i <= m; i++)
    cout<<e[i].first<<" "<<e[i].second<<"\n";

5 静态查错

程序按照思路编完之后,查编译错误。

编译全部修正后,千万不要测样例。

1、经验证明,第一次就把样例过了的几率很低,即使过了,在测自己的特殊数据的时候也会出错。所以,编译完后一定要静态查错。

2、经验表明,静态查错是很有效果的。基本上每次静态查错都可以找到变量代错的错误。特别是快排的I,J是否带错,DEC,INC是否搞错,SWAP是不是加了VAR等等。

3、试想:如果没有静态查错,就去测样例,如果程序有错,样例不过,影响心情;即使样例过了,因为程序有错,特殊数据也不一定能过;即使特殊数据也过了,程序有错,评测的时候绝对会错。发现错了,影响心情了,还是要来静态查,心情不好,肯定效率低。那还不如一开始就静态查,即使发现错误,获得成就感,心情很好。千万不要慌着去测。

4、要保证程序无错,思路清晰,结构清晰了,然后再去测样例,再去测特殊数据。
样例过了不要得意,特殊数据过了不要得意,很有可能还有很多特殊情况你没有想到。

(1)是否写上了using namespace std? (这是C++的,Pascal就不用了)
(2)数组开得是否够大?
(3)变量类型是否正确?
(4)memset时,所填的sizeof(XX)的XX是不是匹配?大小是不是正确? (Pascal 是 fillchar)
(5)外层循环与内层循环的i,j是不是混用了?
(6)循环之前,i,j是否定义了?
(7)输入数据都输入了吗?
(8)这个程序是在执行你想让它执行的步骤吗?

6 其他一些

  1. 重写代码(雾

  2. 拒绝调试(逃

代码调试

03-04

最近我写了一些代码在eclipse跑了一下,老是报错!是关于servlet和Ajax的!麻烦大虾帮我看一下!代码比较多!rnpackage han;rnrnimport java.util.LinkedList;rnrnrnrnpublic class ChatService rn private static ChatService sc;rn private LinkedList chatMsg;rn private ChatService()rn rn rn public static ChatService instance()rn if(sc==null)rn sc=new ChatService();rn rn return sc;rn rn public void addMsg(String user,String msg)rn if(chatMsg==null)rn chatMsg=new LinkedList();rn rn rn public String getMsg()rn if(chatMsg==null)rn chatMsg=new LinkedList();rn return "" ;rn rn String result="";rn for(String tmp:chatMsg)rn result+=tmp+"/n";rn rn return result;rn rnrn rnrnpackage han;rnrnimport java.io.IOException;rnrnimport javax.servlet.RequestDispatcher;rnimport javax.servlet.ServletContext;rnimport javax.servlet.ServletException;rnimport javax.servlet.http.HttpServlet;rnimport javax.servlet.http.HttpServletRequest;rnimport javax.servlet.http.HttpServletResponse;rnrnpublic class ChatServlet extends HttpServlet rnrn rn public void service(HttpServletRequest request, HttpServletResponse response)rn throws ServletException, IOException rn request.setCharacterEncoding("UTF-8");rn String msg=request.getParameter("chatMsg");rn if(msg!=null&&!msg.equals(""))rn String user=(String)request.getSession(true).getAttribute("user");rn ChatService.instance().addMsg(user, msg);rn rn rn request.setAttribute("chatList", ChatService.instance().getMsg());rn forword("Test.jsp",request,response);rn rn rnrn rn public void forword(String url,HttpServletRequest request, HttpServletResponse response)rn throws ServletException, IOException rn ServletContext context=getServletConfig().getServletContext();rn RequestDispatcher rd=context.getRequestDispatcher(url);rn rd.forward(request, response);rn rn rnrnrnrnrnMyAjax.htmlrnrnrn rn 聊天页面rn rn rn rn rn rn rn rn rn 聊天页面rn rn rn rn  rn rn rn rn rn rnrnrnrnweb.xmlrnrnrn rn ChatServicern han.ChatServicern rn rn Chatrn han.ChatServletrn rnrnrn rn rn ChatServicern ChatServicern rn rn Chatrn /chat.dorn rn rnrn<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>rnrnTest.jsprnrnrn rn rn rn rn rn $requestScope.chatList rn rnrnrn运行老是报错!麻烦大虾们把错误揪出来!谢谢!rn

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试