FAQ > 金融建模 > 建模问题 > 如何调试程序

Q:如何查找nil的错误    

  • A:查找出来的值是nil,表示不存在。如果从数组中取值或取值后计算(加减乘除等),取出来的值是nil或报“不能进行加法操作,类型不对”/“不能进行减法操作,类型不对”/“不能进行乘法操作,类型不对”/“不能进行除法操作,类型不对”等。对于此类型的错误,用户可从弹出的错误提示中,从最后一句开始找错误点(错误提示会定位错误的行及错误类型),可以找到最终的错误提示。用户可以在错误行的前一行用echo /try ...except ...end/断点 等方式进行调试。
    PS:
    1、如果报“不能进行**操作,类型不对”错误,请检查相关的 数据是否符合相关操作的要求,比如简单的四则运算,不能用一个数字与一个数组进行运算,也不能用数字和字符串/nil等进行运算。用户可以在错误语句之前将数据echo出来,或者用断点调试的方法进行检查。
    2、错误调试范例:
    错误代码如下:stocks是一维股票数组,其中第5个是空值,空代码无法提取收盘价。
      stocks:=array("SZ000001","SZ000002","SZ000003","SZ000004","","SZ000005");
      r:=array();
      for nI:=0 to length(stocks)-1 do
      begin
       stockid:=stocks[nI];
       setsysparam(pn_stock(),stockid);
       r[nI]['代码']:=stockid;
       r[nI]['名称']:=stockname(stockid);
       r[nI]['收盘']:=close();
      end;
      return r;
    执行后报错如下:第11行“没有指定股票”

    我们在错误提示框中从下到上查看(如果有多层函数调用的,最下面的提示代表最外层的错误,如此一个个进行查找),可以看到是在主函数的第11行报了执行close出错。第11行的语句是“r[nI]['收盘']:=close();”。我们可以想象跟close相关的内容是当前的股票、时间等,我们可以用以上提出的3中方式进行调试:
    1)echo :在11行的前面加上
    echo 'nI:',nI;
    echo 'stockid:'stockid;
    我们就会发现,在打印出来的信息中,最后打印出来的nI和stockid,就是执行close出错的当前代码,从而可以定位nI对应的stockid是否符合代码要求。
    2)try方法:在11行前后加上
    try
    r[nI]['收盘']:=close();
    except
    return array(nI,stockid);
    end;
    这种方法,是在执行close()出错时就会执行except...end之间的内容,没有错误就会继续执行。由此,我们同样可以把nI和Stockid返回。
    3)断点:在11行加断点,点击调试执行,当执行到这句的时候,就会停下来,用户可在下面的调试框中查看相关的数据。这种方法的缺陷是,如果在循环中调试,每运行到这句,会会停下来。一旦循环的数据量大又无法定位是循环到第几个出错时,调试的工作量就会很大了。优点是运行到调试点时,用户可返回所有的变量和数据进行查看。
    为了更高效的查找错误,用户可以用echo 和断点的方式结合,先用echo找出错误出现在第几次循环中,用断点方式,循环直接从错误的点开始。一次就可到断点,再查看相关的变量等。