小天:什么是断点调试?还有什么是断点?还有断点调试中可以看见那些信息?
老田:断点调试就是指让程序在我们指定的位置停下来,根据我们的要求去一行行的执行代码。而我们指定要停下来的这个点就是一个断点。
断点调试的过程中,可以看到代码的状态改变情况(这里主要指局部变量的值改变),代码的运行顺序,调用堆栈的情况,被调试程序的输出信息等。不过在很长一段时间内,我们主要关心的都只是具备变量的改变和代码的执行顺序。
要对一段程序进行断点调试,第一步是要设置断点。断点的数量没有限制,但有一点,断点一定是要打在可执行的代码上,比如注释上面、类外面都无法设置断点。这个不需要多详细的讲,你自己挨个去点就知道哪里设置得了,那些设置不了啦。
我们按照下面步骤来对上面的死循环进行断点调试:
1. 在申明计数器这一行前点击鼠标左键,或产生一个红点点。
2. 点击启动调试按钮或者按F5键,启动调试。程序会运行到第一个断点位置停下来。如图3-2
接着我们对上图中标注的几个位置分别讲解:
1. 这种图示表示代码运行到当前行,并且,当前行是断点,该图示后面的代码行是黄色的,这也充分说明,程序正运行到当前这一行上了。
2. 监视、局部变量、自动窗口这里现在我们用不完,但主要关注自动窗口为最佳。在当前图片中,可以看到,现在正显示出变量i当前的值;
3. 将鼠标放到代码中的任意变量上,可以看到当前时候变量的值,这点和局部变量窗口中显示的差不多,只是说更为灵活,但各有用处嘛。
4. 目前,我们看这一大块窗口上提供的工具或者信息还没有多大用,所以可以点击这个图示,让这一些列窗口自动隐藏。
5. 这一个工具条默认是只有当调试状态的时候才显示出来,当然,你可以设置它平常也在或者调试的时候都不在,用鼠标右键即可设置。在这个工具条上主要用到的是功能继续、停止和重新启动,而后面的逐语句、逐过程一半不会用鼠标去点,因为如果代码很多的话,需要点很多次。逐过程我们现在理解起来还有点问题,其实它的作用是,哪怕当前运行的这一行代码里面还涉及到另外一个类或者方法,那也不管,只管讲当前行作为一行代码就行了。而逐语句则恰恰相反,如果运行到当前行代码涉及到其它类或者方法,那么逐语句就会跳到所引用的类或方法里面去,每一行一行代码的执行。通常逐过程我们按F10键,逐语句则按F11。
3. 按F10或者F11,让代码一行行的执行,你一直关注变量的变化吧。
小天:我从循环到,分支,前面的实例都试了,很不错,对分支和循环的理解也更加清楚了。但是对逐过程和逐语句还是不太清楚,因为在前面的练习中,我发现这两并没有什么区别。
老田:有区别的了。下面来做个示例,在这个示例中,我们将单独增加一个方法,而在main方法中去调用此方法。如下
1. 新建一个名为“断点调试”的控制台应用程序;
2. 使代码如下
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 断点调试 { class Program { static void Main(string[] args) { Console.WriteLine("请输入您的姓名:"); //接受用户输入,并将接受到的值转换为字符串交给变量name string name = Console.ReadLine().ToString(); //给这一行加断点。 //下一行申明一个变量,而他的值则是,这里开始调用方法GetName,并将name传入 //多调试几次,在下面这一行的时候,分别用F10和F11这两个键都试试 string Hellol = GetName(name); Console.WriteLine(Hellol); Console.ReadLine(); } /// <summary> /// 根据传入的姓名,组成一句话 /// </summary> /// <param name="p">姓名</param> /// <returns>欢迎语言</returns> static string GetName(string p) { string name = p; string hellol = "您好啊,欢迎您来这里!" + name; return hellol; //将值返回给调用方 } } } |
3. 就上面的代码,记得分别用F10键和F11键调试一次。这样你就可以很清楚逐过程和逐语句的好处了。