vs调试技巧

在我们写代码的时候常常会出现一些错误(逻辑上的错误),当你不知道这些错误怎么修改的时候就可以尝试进行调试

1.调试的基本步骤

  • 发现程序错误的存在

  • 以隔离,消除等方式对错误进行定位

  • 确定错误产生的原因

  • 提出纠正错误的解决办法

  • 对程序错误予以改正,重新测试

2.Debug和Release的介绍

Debug为调试版本,包含调试信息,并且不作优化,便于程序员调试程序

Release为发布版本,进行了各种优化,便于用户使用

如何确定是Debug版本还是Release版本

我们调试是要将环境改成Debug,Release环境下是没办法调试的

3.快捷按键与功能详解

  1. F5 - 开始调试
  2. ctrl+f5 开始执行(不调试)
  3. F9 设置断点/取消断点
  4. F10 逐过程 - 不会进入函数
  5. F11 逐语句 - 遇到函数会进入函数
  6. (F5是和F9配合使用的)

3.1 - F10逐语句执行


int main()
{
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        printf("%d ", i);
    }

    return 0;
}

这段代码是怎么执行的呢,我们来按F10,逐过程看看代码怎么运行

vs调试技巧_第1张图片

按了一次F10后可以看到开始运行了,现在光标的位置在红圈所在地方,说明代码运行到了这里

vs调试技巧_第2张图片

再按一次F10,就运行到了下一句,此时我们打开局部变量看看

vs调试技巧_第3张图片

打开之后我们可以看到,运行到这一步之后,就会创建一个变量i,类型是int

vs调试技巧_第4张图片

我们再按一次F10

vs调试技巧_第5张图片

运行到下一步的时候,就把i的值赋为0了,接下来是一个循环,我们来看看循环是怎么运行的

vs调试技巧_第6张图片

满足循环条件i < 10,进入循环,并执行语句printf("%d",i),此时会打印出0

vs调试技巧_第7张图片

再次按F10的时候,就会回到for语句,继续判断是否满足for循环的条件,满足则进入循环,不满足离开循环.

vs调试技巧_第8张图片

当i已经打印了1-9之后,i会变成10,在判断不满足for循环条件之后,就会离开循环,执行下一句

vs调试技巧_第9张图片

执行到return 0 之后,就结束程序了

以上代码我们测试了F10的功能是逐过程执行代码,我们可以一条一条的查看代码,当你的程序出现错误的时候,你就可以逐语句,看看程序运行的过程和你想象的过程是否一样,如果不一样,那到底是哪一部分的代码出现了问题

3.2 - F11逐过程执行

当我们遇到函数之后,如下面这段代码


void test()
{
    printf("hehe\n");
}

int g_val = 100;

int main()
{
    int i = 0;
    test();

    return 0;
}

当你想看看test函数是怎么运行的时候,F10逐过程就无法满足我们的需求了

vs调试技巧_第10张图片

当我们运行到此时位置的时候,我们再按一次F10

vs调试技巧_第11张图片

可以看到此时直接跳到了下一句,并在屏幕上打印了一个hehe,并没有进入test函数的过程,此时我们就可以使用F11来观察在test函数内部运行的情况

vs调试技巧_第12张图片

我们在刚刚那个位置按下一次F11之后,可以看到,光标出现在了test函数内部,此时再按F11

vs调试技巧_第13张图片

可以看到此时打印出来了一个hehe,光标停留在了void函数的右大括号处,我们再按一次F11

vs调试技巧_第14张图片

此时光标来到了return 0处,可以说明test()到return 0 之间还有很多步骤,按F10都没有执行,F11每一条都执行了.F11和F10的区别就在于,F11是逐语句执行,从程序开始到结束的代码每一条都会执行,会进入函数内部,F10是逐过程,不会进入函数内部

3.3 F5 - 调试 F9 - 设置/取消断点

当你想测试某一行的代码,但是按F10或者F11要很多次的时候,你可以添加一个断点

vs调试技巧_第15张图片

我们在34行的位置按F9添加一个断点,此时在34行左边出现了一个红色的小圆圈,这个就是断点

vs调试技巧_第16张图片

此时我们按F5开始调试,发现屏幕上打印出了hehe还有1-9,我们发现这其实是34行之前的代码打印出来的东西,此时光标停在了35行,还没有打印出10行hehe,也就是当我们设置断点之后,按F5运行,就会移动到下一个断点处,并运行前面所有的代码


当我们进入循环,如果循环有100次,你想找到第50次,断点应该怎么设置

第一步:先设置一个断点

vs调试技巧_第17张图片

第二步:在断点处右击鼠标,点击条件

vs调试技巧_第18张图片

第三步:选择条件表达式,并在后面输入i==50(不要写成i=50),意思就是断点设置的条件是满足i==50

vs调试技巧_第19张图片

当我们设置好之后来看看效果,按F5开始调试

vs调试技巧_第20张图片

我们发现,当i=50的时候果然停下来了

还有一种方法

vs调试技巧_第21张图片

我们将断点设置在if语句里面,当i=50的时候才会进入if语句内部,所以我们将断点设置在if语句内部,这样也能很好的找到第50个

4.调试过程中查看相关信息

要开始调试才能看到窗口里的相关信息

vs调试技巧_第22张图片

可以看到当我们打开窗口是可以看到很多东西,比如我们刚刚说过的局部变量,我们来看看几个比较重要的

4.1自动窗口

vs调试技巧_第23张图片

当我们的代码运行到第一个for循环的位置时,可以看到自动窗口中存在很多变量,你可能会觉得这个和局部变量很像,但是自动窗口会把上下文中的信息自动加入窗口,不好的地方是会自动删除,不够灵活

vs调试技巧_第24张图片

可以看到,当我们运行到第二个for循环语句时,自动窗口内的东西只剩下i了,如果我们想观察ch和arr的值时就不太方便

4.2临时变量

vs调试技巧_第25张图片

可以看到当前范围内创建的变量

vs调试技巧_第26张图片

当我们进入test函数中,就无法看到main函数中创建的变量了

4.3监视

vs调试技巧_第27张图片

监视需要手动输入你要监视的值,但是监视的范围比较大,你可以监视变量的地址,观察变量存储在哪个位置,可以观察数组每一个元素的值

4.4内存

当我们想查看一个数的存储位置时,可以打开内存

比如我们想查看arr数组的位置(arr是数组名,本身就是地址,如果是普通变量要加&)

vs调试技巧_第28张图片

然后按下回车键

vs调试技巧_第29张图片

可以看到此时内存arr的地址

此时内存窗口被分成三个部分,左边一栏显示的是内存单元的地址,中间存放的是内存中的信息,内存中本来放的是二进制的数据,为了方便显示,显示的时候用16进制,右边一栏是把内存中的信息解读一下,参考价值不高

4.5反汇编

vs调试技巧_第30张图片

查看c语言翻译对应的汇编代码

4.6寄存器

vs调试技巧_第31张图片

可以看到寄存器,以及运行时候的变化

4.7调用堆栈

栈:和子弹上膛一样,如果没满,可以直接往里面放,如果满了之后,要把后加进去的拿出来才能放进去(先进后出)

队列:和排队一样,出去一个,进来一个,队头走,队尾进来,这种对数据的增加和删除方式叫做队列(先进先出)

vs调试技巧_第32张图片

当我们运行main函数时会调用test,test会调用test1,test1会调用test2,使用调用堆栈窗口时,可以观察到函数调用逻辑是怎样的,当程序比较复杂时,通过调用堆栈可以清晰的观察到调用逻辑

你可能感兴趣的:(c++,开发语言)