VS调试
调试(Debugging/Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序错误的一个过程。
调式的基本步骤
发现程序错误存在;
以隔离、清除等方法对程序错误(bug)进行定位确定错误产生的原因;
提出纠正错误的解决办法;
对程序错误予以改正,重新测试。
#include <iostream>
using namespace std;
int mySum(int a, int b, int c);
int main()
{
int a = 10;
int b = 20;
int c[5000];
for (int i = 0; i < 5000; i++) //设置断点,发现错误
{
c[i] = mySum(a, b, i);
}
return 0;
}
int mySum(int a, int b, int c)
{
int tmp = a + b;
tmp += c;
return tmp;
}
VS调试功能
快捷键
F5,开始调试。开始调试后再次使用F5跳到下一个断点。
F9,设置或取消断点。将光标定位到某一行。
F10,逐过程,通常用来处理一个过程,一个过程可以是一次函数调用或者是一条语句。
F11,逐语句,就是每次都执行一条语句,如果遇到函数则进入函数内部。
观察变量
左下方自动窗口可以观察程序运行过程中变量的变化。
左下方监视窗口可以观察表达式在程序运行过程中的变化。
条件断点
在多次循环里,我们需要再特定条件下,中断程序执行,这时候可以使用条件断点。
条件断点允许设置一个表达式,当表达式条件为真时,中断执行。
条件断点可以通过右键菜单添加,也可以通过修改普通断点的设置把普通断点变成条件断点。
异常
异常就是程序运行中发生了难以预料的、不被期望的事件而导致程序偏离正常流程的现象。
抛出异常throw
当程序出现问题时,抛出一个异常。
throw可以抛出C++中的任意对象。
#include <iostream>
using namespace std;
int myDiv()
{
int a, b;
cin >> a >> b;
if (b == 0)
{
throw "除0错误"; // 抛出异常
}
cout << "myDiv 正常计算" << endl;
return a / b;
}
int main()
{
try
{
int c = myDiv();
cout << "c: " << c << endl;
}
catch (const char* e)
{
cout << e << endl;
}
cout << "myDiv调用完成" << endl;
return 0;
}
捕获并处理异常try、catch
try,捕获异常,try后面的代码块包含可能抛出异常的代码。
catch,处理异常,处理对应的try捕获到的异常。
catch(...)捕获任何异常。
#include <iostream>
using namespace std;
class ExpBase
{};
class ExpA : public ExpBase
{};
class ExpB : public ExpBase
{};
class ExpX
{};
void test()
{
int n;
cin >> n;
if( n == 0)
{
ExpBase expbase;
throw expbase;
}
if (n == 1)
{
ExpA expa;
throw expa;
}
if (n == 2)
{
ExpB expb;
throw expb;
}
if (n == 3)
{
ExpX expx;
throw expx;
}
}
int main()
{
try
{
test();
}
// 多个catch语句会按照顺序依次尝试,当catch的参数类型和抛出的异常类型相同时,执行该catch语句对应的处理。
catch (ExpA& e)
{
// 当异常类有继承关系时,子类对应的catch语句应该在父类之前。
cout << "catch (ExpA& e)" << endl;
}
catch (ExpBase& e)
{
/*
catch后的参数类型为基类时,子类对象都会被补获。
例如,输入2时,test抛出ExpB,会被这个catch语句处理。
*/
cout << "catch (ExpBase& e)" << endl;
}
catch (...)
{
// catch (...)补获任何异常
cout << "catch (...)" << endl;
}
return 0;
}