|
![]() | 作者: jhkdiy [jhkdiy]
![]() |
登录 |
猜数字游戏的bug讨论,如何发现并修正bug。 作者:jhkdiy 之前大家都看过了《C++编写猜数字游戏》的文章了,整个源代码比较简单,有C++基础就可以看 明白程序的流程,但我的目的并不是在说说简单的C++语法复习和C++的实际应用,而是在于说一 下一直被很多初学者忽略的编程问题:如何发现并修正bug。很多学编程的朋友一般只要在编译时没有 语法错误能编译运行就万事大吉了,这样的不良习惯在以后会很严重。 那么我们一般怎样发现错误呢?错误不外乎这几种情况:第一个肯定是语法错误,这个比较容易解决, 因为一般编译器都会发现这样的错误并有明显的提示,我们只要找到错误行并修正就可以了,错误一般 是无意的拼写错误,符号错误等。 另一种情况是语法没有错误,但是程序就是没有达到自己预想的结果这一般是逻辑错误,而逻辑错误又 分为两种情况,一种是无意的逻辑错误,例如本来是想一个循环执行10次的,但是错误将结束条件写错了,而 导致执行了更多或更少,这种情况就要自己阅读源代码来解决了,因为自己了解程序的流程,所以一般都比较 容易发现。另一种情况是算法本身有问题,或更通俗的说是解决问题的方法有问题,设计思路有问题,这种情 况算是比较难发现的了。因为既不是语法错误,又不是自己的无意写错,代码更自己设想的流程都一样,但结 果就是不对。这种情况打败了很多编程人员,很多朋友在这种情况下只能到论坛发帖子了,找求救了,但很多 网友也一样爱莫能助。我个人认为这种情况还是自己研究好,当程序到了这种地步的时候就应该思考了:是我 的设计思路有问题吗?这个问题有没有其它方法可以解决?解决问题的方法通常都不止一个,当出现这种情况 的时候就应该考虑使用其它设计思路了。这也意味着一个大问题:你的代码需要重写,这对一般的小程序不成 问题,但如果重写导致整个项目的变动时就麻烦了,所以要慎重。 还有一种情况是环境错误和系统错误。这种情况可以说简单,而有时候又不简单。这种错误的表现是程序能 正常编译,但程序一执行就说“非法内存访问”或“此内存不能read”,跟着便是程序崩溃。相信很多朋友都遇过 这种情况,程序员最痛苦的事莫过于此。新手一般不懂得解决这种问题,因为他还不懂得怎样调试程序,这时到论坛 发帖求助是正确的。懂得调试的朋友就比较容易发现错误,当出现内存访问错误对话框时,可以记下导致程序错误 的指令地址,然后用调试软件载入程序,在导致程序错误的指令前下断点来执行,这时通常都会发现问题的所在。 只要修改一下代码就可以了。最后一种情况就是系统本身的问题,这种问题当你不知道原因的时候最难解决,但当 你知道原因的时候却最容易解决,这种情况就是程序的运行环境问题,一般学习语言的时候不会碰到,但编写实际 的应用软件时就会发生了,例如有些API函数只能在NT系列的系统上运行,win9x是不支持的,有很多新手不知道某个 函数的执行平台,老是发帖子问,但很多时候的回复就是简单的“该函数不能在该系统上运行”。解决这样的问题只 有找个替换的方法了,或者使用新的API,或者使用另一种方法。 错误的表现总是多种多样的,很多时候让人琢磨不透,但当问题解决的那一刹那却无比欣喜。这就是编程,让我 欢喜让我优。当出现问题时要试着自己解决,发现错误并修正它,在这个过程中你会学习到更多有趣的知识,而你的 编程经验也将在这里积累,所以编程能力的提高不单单是编写更多的程序,同时还要懂得调试程序。 好了,说了这么多,下面就讨论一下这个游戏存在的问题,首先这里不讨论语法错误问题,因为如果出现语法问题 证明你的基础不扎实。那么这个程序到底都有那些问题呢?在解说之前还是再看看代码吧: 代码: 程序第一次运行完全没有问题,但很多朋友很快就发现了一个bug,这个bug出现在: 代码: 程序直接清屏后就继续游戏了,竟然忘了,忘了什么?当第二次猜数字猜对的时候尝试 次数明显不对,明明只用4次猜对了,它竟然说尝试了9次。再看看代码,哦,原来在继续下 一次游戏之前没有对tries变量作初始化,这个容易修正: 代码: 这下应该没问题了吧,第二次猜猜看,第三次猜猜看,咦??怎么每次猜的数字都是一样的? 再看看代码,又是刚才修改过的那段代码,程序中用来保存随机数的变量theNumber只在程序第一次 运行的时候赋值了,当第二次猜数字的时候它根本没有变,所以导致第二次以后的数字都是一样的。 好,知道问题所在后就好办了,继续修正: 代码: 好了,当程序第一次运行没问题,第二次、第三次也没问题了,自从修好后,腰不酸了,腿不疼了 嘿,还真灵・・・。真的没问题了吗?没问题啊,程序现在运行的好好的。呵呵,大家忽略了一个事实, 我们都假定用户的输入是可信赖的。问题就在这里,大家看看这段代码: 代码: 程序假定用户输入的就是我们期望的数字,但是,如果用户输入的不是数字又会如何呢?实际情况吓 我们一跳,程序无限循环,已经无法控制了。这在实际的应用软件中经常出现,这就表明很多软件设计者 都不经意地作了很多假设:只要用户照我的使用方法做程序准没错。但是很多用户就是喜欢搞破坏,喜欢 搞垮程序。我们作为设计者应该要重视这个问题,对用户的输入不作任何自以为是的假设,对输入进行严格 的检查,只有符合程序运行的输入才作处理。那么这个程序应该如何修改呢?很简单,我们要对用户的输入 进行检查,提示用户只能输入数字: 代码: 好了,再次编译运行程序,输入非数字字符,哦,程序检测到了,能正常运行。程序共 修改了三次,最后的代码如下: 代码: 总结下,第一个和第二个错误属于逻辑错误,由于编程疏忽大意而造成的,但第三个错误 在用户不输入非数字字符前是永远不会被发现出来的,这就是程序的健壮性问题。 希望看了这篇文章后对大家有所帮助,有所觉悟,在编程的道路上更进一步。 下面是修改后完整的代码和执行程序。 http://jhkdiy.go3.icpcn.com/code/download/gessnumber.rar http://jhkdiy.go3.icpcn.com/code/download/gessnumberfixed.rar |
地主 发表时间: 07-04-11 19:39 |
![]() | 回复: jhkdiy [jhkdiy] ![]() |
登录 |
晕,大家都去那里了,几天都没个回复的・・・ |
B1层 发表时间: 07-04-14 23:15 |
![]() | 回复: kert_t8 [kert_t8] ![]() |
登录 |
:) 我找出来两个 |
B2层 发表时间: 07-04-15 20:21 |
![]() | 回复: virgoshaka [virgoshaka] ![]() |
登录 |
太长了。。。。 |
B3层 发表时间: 07-04-23 02:42 |
![]() | 回复: virgoshaka [virgoshaka] ![]() |
登录 |
还是看完了。。。不错 不过我觉得学习的话还是不必太关注输入方面的代码健壮性的问题。。。 因为这个太复杂了。。。不是两三行代码可以解决的。。。 比如这个最后的程序,如果随机数生成50的话,我输入kk50,程序还是猜中了。。。但这显然不是我们的原意。 呵呵,个人意见。 |
B4层 发表时间: 07-04-23 03:20 |
![]() | 回复: jhkdiy [jhkdiy] ![]() |
登录 |
呵呵,说的没错,事实上不可能检测到并控制所有的非法输入。不然windows也没那么多漏洞了。这里只是抛砖引玉地介绍一下平时编程序的错误倾向。不过还是建议大家要以严谨的态度来写程序。不要丢三落四。 |
B5层 发表时间: 07-04-25 10:06 |
![]() | 回复: SysHu0teR [syshunter] ![]() |
登录 |
事实上,在我所写过的有限的垃圾代码中,大多需要交互的命令行程序,都是把输入作为字符串来处理的,也记不清是哪位大牛曾经告诉过我的。总之很感激他。 jhkdiy,很佩服你的钻研劲头与热心,加油! |
B6层 发表时间: 07-05-02 17:24 |
![]() | 回复: jhkdiy [jhkdiy] ![]() |
登录 |
谢谢SysHu0teR的赏识,唉,到现在都还没找到工作,信心大减了,都不知道还能不能干这一行了。 |
B7层 发表时间: 07-05-03 17:51 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号