为了账号安全,请及时绑定邮箱和手机立即绑定

如何debug你的代码123

我如何调试我的程序?

这是编程的关键技巧,你必须学会​​如何做好。它主要是一门艺术;没有单独的办法做到这一点,学习它的最好方法就是做大量的工作。根据我们的经验,以下是一些可帮助您入门的建议。
 

调试的禅宗

要克服的最大障碍是你的信念---你的代码是正确的,电脑是不对的。编译器和库错误存在,但与编程错误相比,它们是非常罕见的。所以,99.99999%的时间计算机正在做你刚刚告诉它做的事情,而你刚才说错了。你的任务是找到你说的错误的东西 - 它在那里某处!

发现错误的最好方法是收集有关错误发生的条件以及错误的信息。有很多方法可以做到这一点,比如尝试不同的输入来查看错误行为是否存在模式,或者检查程序流和变量值。

当你开始理解这个bug的时候,你可以开始推断你的程序的哪些部分是相关的,并且开始在你的程序的更小部分中进行零分。最终你可以问“这行代码和它应该做什么相比?”你会发现在你的代码中确切的错误的东西。
其中大多数是通过编译器的“愚蠢的”小错误或拼写错误,但是期望它们中的许多是“深刻的”错误,特别是在您正在学习编程语言和软件概念的情况下。
收集信息的最好方法是使用调试器。这就是专业人员使用它们的原因调试器是你的朋友!学习如何使用它,以及如何使用它!它将以真正非凡的兴趣回报你的学习时间投资。

请参阅课程资料以及您的IDE文档和我们,以获取有关学习和使用调试器的帮助。

我们期待什么

避免学习和使用调试器是短视的,不专业的,坦率地说,是愚蠢的。我们希望您在所有项目中使用调试器。当您向我们寻求帮助查找错误时,我们希望您已经自己使用了调试器,并尽可能地去做了。

使用调试器

有两种方法取决于你的程序的不当行为。如果你的程序没有崩溃运行,那么它很高兴地错误的东西,但运行显然成功。在这第一种情况下的基本技巧是使用调试器来观看程序的工作,一次一个程序地执行程序。

一个图形化的调试器将会显示一个指向当前语句的箭头的源代码。在其他窗口中,您可以看到变量的当前值。你可以点击控制按钮,通过一个语句前进,然后查看变量的变化 - 通常是突出显示!使用其他按钮,可以逐步调用函数调用语句,而不必进入函数调用,进入函数,完成函数调用并返回到顶层。

使用这些巧妙的功能,检查程序流程和变量的值。看看该程序是否应该在哪里,输入值,函数参数和计算结果应该是什么。只要你看到一些不对的地方,就停下来试着找出是什么原因造成的。根据需要,重新启动程序并再次详细阅读该部分。为了节省时间,可以使用断点和跳过按钮来跳过您认为是好的程序部分。例如,一旦你的结论是你的defrangulate函数有什么问题,你可以在第一个语句中设置一个断点,然后告诉程序开始运行。然后调试器将自动停止在断点语句上,从而使你正确地进入你感兴趣的执行阶段。一旦你了解了调试器,以这种方式使用它比用打印语句乱抛垃圾代码要快得多,并试图跟踪输出的结果。

第二种情况是你的程序崩溃了 - 它被系统终止。通常情况下,如果您启动在调试器下运行的程序,然后继续运行,则调试器将自动控制发生崩溃事件的位置,您可以看到问题发生的位置,并检查该变量值点。有时会导致系统或库代码中发生致命事件,并且在调试器显示中看到奇怪的东西,甚至是汇编语言。不要惊慌!问题通常是你调用了一些库参数(比如零指针)的库例程(比如strcmp),这就是库代码崩溃的原因。您可以让调试器向您显示发生崩溃时调用堆栈帧的列表,并选择最近的一个代码,并让调试器切换到该函数的上下文。然后你可以看到你的代码在做什么以及它的变量导致了崩溃。如果你认为这个问题是在这个函数的调用代码中的话,你可以再次向上移动堆栈,甚至从顶部开始!

当你发现错误时该怎么办

一旦发现错误并理解错误,请立即修复并重新编译并重新运行程序。如果你有一个以上的错误,他们倾向于以非常混乱和混乱的方式进行交互。不要浪费时间去弄清楚一个搞砸的程序正在做的所有变态的事情。立即删除每个错误总是比较好,而不是试图了解多个错误发生的情况。

但是,如果你的程序有一个百亿个错误,而且真的是一塌糊涂的话,问题可能会更严重。通常你的问题的解决方法,你的程序设计,或者你对如何编写代码的理解都是根本上的缺陷。休息一下,看看你正在做什么 - 你的想法或你的知识有缺陷吗?

一旦你明白要做什么,有时候把部分或全部代码扔掉,重新开始,比理解你的问题之前做的一团糟或者如何编写代码更容易。一直发生在我们身上! “计划把第一个版本扔掉!”是软件开发的口号。

总是从一开始就在调试模式下运行你的程序,并保持在那里,直到你对你的程序非常有信心。你的新程序几乎肯定会有一些bug,那么为什么不从已经可用的调试器开始呢?调试器可以防止某些错误引起的某些系统崩溃,也可以节省您的时间。

调试器如何工作?

我们希望你使用的调试器是“符号调试器”,它们本身就是非常复杂的程序。通常情况下,编译器和链接器会丢弃关于函数和变量名称(“符号symbols”)的所有信息,只留下原始的机器指令。当您将项目置于调试模式时,编译器和链接器会将所有变量和函数的名称和内存位置保存在调试器使用的特殊数据文件中,并在编译的程序中插入特殊的“中断”代码以标记在机器代码中,每个语句都会启动,并在每个函数调用中进行。

当您在调试器下运行程序时,CPU会遇到在原始程序语句或函数调用的机器代码开始处插入的“中断”代码。中断代码调用调试器,调试器随后执行您在调试选项或函数中指定的任何内容,例如在执行语句之前暂停。

使用编译和链接过程中保存的信息,调试器可以打开相应的源代码文件,将其显示在窗口中,并显示哪个语句产生了将要执行的机器代码。使用其他保存的信息,还可以显示与运行时栈上当前变量相对应的内存位置的内容。

调试器的工作原理有一些重要的含义:首先,尽管基本功能非常可靠且易于使用,但它是一个非常复杂的程序,有很多额外的功能。所以实际上,你应该在调试器本身中看到一些错误和怪癖。其次,与正常运行的程序相比,调试器实际上修改了内存中事物的大小和位置。在某些情况下,当使用调试器时,错误的确切症状可能会改变,尤其是当您遇到错误的指针和数组时,它们的症状对于内存中事物的确切位置是超敏感的。所以,如果使用调试器更改错误症状,怀疑您的数组和/或指针代码!
 

为什么被称为“bug”?

这个故事始于20世纪40年代,美国海军的一个计算机项目使用了第一台通用计算机Mark I,它是一台甚至是ENIAC的机电计算机。程序员发现一个问题是由于机器中的继电器中死了一只蛾。删除该错误可以让电脑按程序运行。编程人员美国海军LTJG格雷斯·霍珀(Admiral)是着名的计算先驱,他保留了项目笔记本上的实际缺陷,
 http://umich.edu/~eecs381/generalFAQ/Debugging_files/droppedImage.jpg

 
Adm Hopper开发了第一批编译器之一,领导了计算机业务应用程序的开发,并共同发明了COBOL,可能仍然是单一的使用最多的计算机语言,因为它是第一个直接将语言特征合并到应用。事实上,COBOL工作得很好,以至于编写的许多程序在数十年(比任何人预期的时间更长)之后仍然在经常使用,这直接导致了Y2K问题 - 没有人希望你一年需要两位数以上的数字!

点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消