• 如何调试一个C++程序?以Visual Studio 2019为例的保姆级教程。


    1 前言

    在写程序时,就算提前想好了思路,也总是会在这个过程中遗漏一些东西,最终导致程序不能运行。这个时候调试程序这项技能就显得非常重要了。接下来我将以Visual Studio 2019(后续简称为vs2019)为例介绍一下我是如何调试一个C++程序的。

    2 建立一个项目,并且编辑程序

    打开vs2019,选择右侧的创建新项目。

     项目类型选择空项目。

     项目名称修改为Test2(也可以是你自己取的英文名字,例如project1),位置选择你想要保存的位置,方便寻找定位文件。然后点击创建。

     进入界面后,在左侧解决方案管理器中右键点击源文件,添加,新建项。

    选择C++文件,名称修改为main.cpp,然后点击添加。在main.cpp编辑窗口中输入以下程序。

    1. #include
    2. #include
    3. using namespace std;
    4. int main() {
    5. /*
    6. 例子:
    7. 输入三个数字,计算他们的和、平均值、最小值
    8. */
    9. //定义3个int类型的变量
    10. //写程序时变量的名字用英文或者英文缩写代替,增加程序的可读性
    11. //定义变量时尽量初始化
    12. //int number1 = 0, number2 = 0, number3 = 0;
    13. int num1 = 0, num2 = 0, num3 = 0;
    14. //读取从键盘输入的3个数字
    15. cin >> num1 >> num2 >> num3;
    16. //1.计算他们的和
    17. int sum = 0;
    18. sum = num1 + num2 + num3;
    19. cout << "sum: " << sum << endl;
    20. //2.计算他们的平均值
    21. //平均值要定义为实型变量(有小数)
    22. double avg = 0.0;
    23. avg = sum / 3.0;
    24. //保留一位小数显示
    25. cout << "average: " << setiosflags(ios::fixed) << setprecision(1) << avg << endl;
    26. //观察除以3的情况
    27. //情况1
    28. int temp = sum / 3;
    29. double avg3 = temp;
    30. //情况2
    31. double avg2 = sum / 3;
    32. //3.计算最小值
    33. int min_value = 0;
    34. //如果数字1小于数字2,那么最小值暂时是数字1,否则暂时是数字2
    35. if (num1 < num2) {
    36. min_value = num1;
    37. }
    38. else {
    39. min_value = num2;
    40. }
    41. //如果暂时的最小值大于数字3,
    42. //那么最终的最小值是数字3
    43. // 否则就是前面的暂时最小值,保持不变;
    44. if (min_value > num3) {
    45. min_value = num3;
    46. }
    47. cout << "min: " << min_value << endl;
    48. }

    顶部工具栏中选择: 调试---开始执行(不调试)或者键盘上按ctrl+f5   运行程序。

    输入数字 5 1 1,结果如下:

     2 尝试调试程序

    2.1 运用调试的手段观察求和计算

    添加断点

    在程序的第21行和22行即sum = num1 + num2 + num3;    cout << "sum: " << sum << endl;这两行语句的行号的左侧单击一下,出现红点标志,表示在这里添加了两个断点

    当进入调试模式,程序执行到断点时会暂停等待我们的操作。

    操作有以下三种:

    鼠标放在按钮上(不点击),出现提示可以看到分别是:

    逐语句F11, 一行代码一行代码的执行,碰到函数会进入函数;

    逐过程F10,碰到函数时会直接执行完函数这一行,不进入函数,其余也是一行代码一行代码的执行;

    跳出shift+F11,跳出当前函数。

    可以参考:https://zhidao.baidu.com/question/1822134520430420108.html

    开始调试

    添加完毕断点,选择工具栏中,调试---开始调试   或者按F5开始调试程序。

    首先输入三个数字 5 1 1,输入后回车,程序停留在21行(第一个断点)。可以看到第一个断点里面是一个黄色的箭头,表示程序当前停留在这里了。 

    我们此时可在左下角的自动窗口中观察各个变量的值,如下图

     可以观察到,此时输入的值已经存储到了三个变量num1, num2, num3中;而第21行语句还没有执行,sum的值还是我们定义变量时设置的初始值0。

    点击三个按钮中的逐语句(F11),执行第21行,停留在22行,如下图

     此时sum的值已经变成了求和后的结果7。

    初次调试到此结束, 我们点击红色正方形(在三个按钮旁边, shift+F5),退出调试。

    2.2 用调试的手段观察求平均值的运算

    添加断点

    首先我们将上一次调试的断点清除,点击断点的红色圆点即可。

    然后在27, 29, 32, 33, 35, 38这几行添加断点,如下图

     接下来F5开始调试,输入5 1 1三个数字,程序停留在27行等待我们的操作,此时avg的值是0,如下图

     我们使用逐语句执行功能(F11),程序执行第27行,停留在29行。我们这时可以观察到变量avg的结果已经变成了2.333.....(自动窗口或者局部变量窗口)

     继续逐语句执行F11,程序停留在32行,控制台保留一位小数输出了avg变量的值.

     继续逐语句执行F11,程序停留在33行。此时第32行语句已经执行。

    我们可以在局部变量窗口中观察到temp的值是2。int类型的sum和int类型的3运算的结果还是int类型,而int类型是没有小数的,7/3的结果的小数部分被直接丢弃了,导致了7/3结果是2的情况。

     继续逐语句执行F11,程序停留在35行。此时第33行语句已经执行。

    我们可以观察到此时avg2变量的值是2.0,因此我们可以知道,此时再将int类型的运算结果赋值给double类型的avg2变量,小数也回不来了。这是情况1,情况1是情况2的拆解步骤。

      继续逐语句执行F11,程序停留在38行。此时第35行语句已经执行。

    我们将sum/3的运算结果直接赋值给double类型的avg3变量,结果仍然是一样,7/3的小数部分被永久丢弃了。因为这里做的运算其实和情况1中的运算是一样的,只不过合成为一步完成。

    如果我们想要保留sum除以3的小数部分,要么就把sum定义为实型变量(float或者double),要么就把3换成3.0,3.0在C++中默认为double类型,或者都修改。

    这是运算过程中类型的隐含转换所决定的,假如有一个运算op(operate的缩写),需要a和b参加运算,

    a   op   b

    那么a和b运算之前会进行隐含的类型转换,把a和b中较低的类型转换为较高的那一个的类型。

    例如

    1. int a;
    2. double b;
    3. a + b;

    在加法计算前会将较低类型的a从int转换到double,然后就是两个double类型的变量在做加法,结果是double类型 ,是有小数的。

    3 总结

    其实调试挺简单的,有时候甚至不需要断点,我们用cout或者printf输出变量的值也是一样的,可以看到某一行代码执行后某个变量的值,就是没有打断点调试那么直观,但是方便。

    另外,屏幕前的你也可以尝试用调试的手段观察求取最小值的程序的运行。

    我看情况更新这一部分。

  • 相关阅读:
    工作记录---淘宝双11,亿级流量高并发是怎么抗住?(站在巨人的肩膀上学习,超开心~)--------脚踏实地,持续学习(看完这一篇获益匪浅)
    3d建模师会因为年龄大而淘汰吗?没有自学能力,入行都是问题!
    【笔记】Oracle不同数据库之间的表级别同步
    处理Activity#onResume()遇到java.lang.IllegalArgumentException诡异异常
    SDK动态设置自定义属性
    高阶测试开发必备技能: k8s入门
    面向对象编程原则(02)——单一职责原则
    Java 配置 HTTP/Socks 代理竟能如此简单
    Augmented Large Language Models with Parametric Knowledge Guiding
    API接口签名校验(C#版)
  • 原文地址:https://blog.csdn.net/lvdoujack/article/details/126893319