调试和错误处理
什么是调试和错误处理
错误分为:
- 语法错误 - 编译器会给出提示,比较好解决
int 0name;//这是一个不符语法规则的变量名
-
逻辑错误 - 难排查
//假如要计算两个整数的和 int result = 23 * 78;//加号写成了乘号,最后得到的不是自己想要的结果
调试分为
- 正常模式 - 正常模式指的是不会影响程序的正常运⾏。
方法:
- 通过Console.Write/WriteLine输出最终的变量的值,通过这个值来判断为什么没有达到预期
- 在Unity中使用Debug.Log(“”),Debug.LogError(“”),Debug.LogWarn(“”)像Unity的Console窗口输出信息,帮助我们调试
003-使用输出语句和Debug模式调试程序
- 模拟错误排查的过程 - 使用输出语句
//模拟错误排查的过程
//定义一个加法的函数,用于计算int类型之合
static int Add(int a, int b)
{
int result = a + b;//假设这里出现了逻辑问题,想写加法却写成了减法
Console.WriteLine("Method" + result);//方法输出,针对函数计算的排查
return result;
}
static void Main(string[] args)
{
int result = Add(40, 20);//因为书写出现了错误,所以本来想要得到 60 只会得到 20
Console.WriteLine(result);
}
通过输出差错的缺点:需要在项目中调试很多这种输出,调试结束之后还要全部注释掉,很麻烦;
- 另外一种调试的方式 - 中断(Debug)模式下的调试
Console.ReadLine();//这个语句就可以 暂停 程序的执行
//原理:ReadLine是调用用户输入的,因此执行到这一句的时候,就会停住等待
如何插⼊断点?
1,右击代码⾏,选择breakpoint(断点) -> insert breakpoint(插⼊断点)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AoDNGAod-1680078289496)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329145740325.png)]
2,光标定位到代码⾏,选择菜单上的Debug(调试)->Toggle Breakpoint(切换断点)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iGYj5guN-1680078289497)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329145916905.png)]
3,光标定位到代码⾏,按下F9键,在此按下F9是取消断点
4,在需要添加断点的⾏⾸位置,直接单击,再次单击取消断点
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CyjJ5tce-1680078289497)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329145812916.png)]
被禁用的断点没有效果的,后期可以再启用
如何让程序中断?
断点
断点是什么?
断点是源代码中⾃动进⼊中断模式的⼀个标记,当遇到断点的时候,程序会进⼊中断模
式。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sauKpej8-1680078289497)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329144529049.png)]
断点符点到哪里,就会在哪里暂停执行
注意空行不能打断点,只能打在有语句的地方
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mANZG7pT-1680078289498)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329144924270.png)]
在又断点的情况下会自动弹出局部变量和错误列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vovRrCSB-1680078289498)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329145130922.png)]
这个断点图标代表程序在这一行暂停了
从上到下执行,遇到第一个断点就会暂停[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-82LY3Tmo-1680078289499)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329145255456.png)]
局部变量会显示当前暂停处函数的所有变量
004-中断模式下的窗口介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nypeaKb5-1680078289499)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329150025052.png)]
调试 - 窗口 - 断点窗口
可以通过这个窗口看到,操作所有的断点
- 在中断模式下很方便查看变量的值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1SuAsukr-1680078289499)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329150150838.png)]
也可以把鼠标放到变量上去看他的值是多少
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pEqLQU9p-1680078289499)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329150309091.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-81pMU0Sn-1680078289500)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329150346206.png)]
在这里修不仅可以查看,还可以修改值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Jl7DciFJ-1680078289500)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329150707915.png)]
- 调用堆栈
可以查看到当前行的路径,是如何调用的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kNfIdSYF-1680078289500)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329150920278.png)]
即使窗口不仅能查看,还能运行表达式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DzvzFHVX-1680078289501)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329150959912.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vAhTaqvz-1680078289501)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329151054119.png)]
在这里修改变量的时候会导致一些语句变红
代表只是在中断模式下改变了变量的值,而不是程序真正运行的结果
005-逐语句和逐过程(中断模式)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DQpN4hgl-1680078289501)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329151334489.png)]
-
逐语句F11 - 就是一行一行代码去执行语句的过程,遇到函数调用二代时候会进入函数内
-
逐过程F10 - 也是一行一行,但是逐语句会进到函数内部执行,逐过程是不会进入函数内部的
-
跳出shift+F11 - 把当前函数执行完,然后返回;也就是直接从函数调用中跳出
006-关于程序中的异常
-
错误处理(异常处理)
我们上⾯讨论了再开发过程中如何查找和修正错误,使这些错误不会再发布的代码中出
现,但有时,我们知道可能会有错误发⽣,但不能100%的肯定他们不会发⽣,此时最好
能预料到错误的发⽣,编写⾜够健壮的代码以处理这些错误,⽽不必中断程序的执⾏。
-
异常:
异常是在运⾏期间代码中产⽣的错误。
⽰例:
int[] myArray = {1,2,3,4};
int myEle = myArray[4];//数组下标越界
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JJdryft8-1680078289501)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329152803318.png)]
运行起来的时候,才会出错
运⾏到这⾥的时候,会出现异常,这个异常的定义已经在CLR中定义好了。如果我们不去
处理这个异常,那么当异常发⽣的时候,程序会终⽌掉,然后异常后⾯的代码都⽆法执
⾏。
static void Main(string[] args)
{
// 生产环境 开发环境
int[] myArr = { 1, 2, 3, 4, };
int temp = myArr[4];
Console.Write("231");//控制台不会输出231
//语法规则没问题,编译器不会报错
}
007-使用try-catch-finally语句处理异常
异常处理(捕捉异常) try … catch … finally 语句
try//可能出现异常的代码
{
}
catch ()//要捕捉那些异常
{
}
finally//不管任何情况下都会执行的代码
{
}
try catch语句使用的例子
try//可以放多条语句
{
int temp = myArr[4];
}
catch (IndexOutOfRangeException e)//用类声明了一个异常类型的对象
{
//出现这个异常的时候,怎么处理
Console.WriteLine("出现了数组下标越界的异常");
}
catch (FieldAccessException e)//catch语句可以有多个,可以同时捕捉多个异常
{
Console.WriteLine("FieldAccessException的异常");
}
finally
{
Console.WriteLine("不管是否出现异常,finally都会执行");
}
//用try catch 处理异常的时候程序是不会崩溃的,等执行完就会继续往下执行
Console.Write("231");
008-使用trycatch检查用户输入的数据是否合法
-
编程题 - 让⽤户输⼊两个数字,⽤户可能会输入⾮数字类型,处理该异常,如果出现该异常就
让⽤户重新输⼊,输出这两个数字的和
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c0oVh62l-1680078289502)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329155452186.png)]
输入非合法数据会报异常[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRMxLEGa-1680078289502)(C:\Users\CoreDawg\AppData\Roaming\Typora\typora-user-images\image-20230329155846058.png)]
using System;
using System.Collections.Generic;
using System.Text;
namespace _008_使用trycatch检查用户输入的数据是否合法
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("请输入两个数字,每行一个");
//首先得到用户输入的两个字符串
//string number1 = Console.ReadLine();
//string number2 = Console.ReadLine();
//再把字符串转换成数字类型
int n1 = 0, n2 = 0;
//利用try语句捕捉异常
try
{
n1 = Convert.ToInt32(Console.ReadLine());
n2 = Convert.ToInt32(Console.ReadLine());
}
catch (FormatException e)
{
Console.WriteLine("你输入的数据不符合规则,请重新输入");
n1 = Convert.ToInt32(Console.ReadLine());
n2 = Convert.ToInt32(Console.ReadLine());
}
//此时的问题是,如果在catch语句里又写错了怎么办?所以需要循环检测try语句
Console.WriteLine(n1 + n2);//输入非数字类型会报异常
//需要把n1,n2的定义放在try外面,否则会报错,因为n1n2变成了try的局部变量
//对应的在括号里面就只需要重新赋值n1n2就行了
}
}
}
利用forwhile死循环优化
while (true)//外层的死循环保证只要出现一场就一直让玩家保持输入
//循环现在没有终止条件,即使输入正确,也会一直要求玩家输入
{
try
{
n1 = Convert.ToInt32(Console.ReadLine());
n2 = Convert.ToInt32(Console.ReadLine());
}
catch (FormatException e)
{
Console.WriteLine("你输入的数据不符合规则,请重新输入");
}
}
当try括号里出现了一处异常之后,后面的代码就不会执行了
while (true)//外层的死循环保证只要出现一场就一直让玩家保持输入
//循环现在没有终止条件,即使输入正确,也会一直要求玩家输入
{
try
{
n1 = Convert.ToInt32(Console.ReadLine());
n2 = Convert.ToInt32(Console.ReadLine());
break;//如果n1n2都合法的话,才会执行到break,说明此时n1n2合法,break跳出循环
}
catch (FormatException e)
{
Console.WriteLine("你输入的数据不符合规则,请重新输入");
}
}
009-使用思维导图处理知识点
n2 = Convert.ToInt32(Console.ReadLine());
break;//如果n1n2都合法的话,才会执行到break,说明此时n1n2合法,break跳出循环
}
catch (FormatException e)
{
Console.WriteLine("你输入的数据不符合规则,请重新输入");
}
}
### 009-使用思维导图处理知识点
![在这里插入图片描述](https://img-blog.csdnimg.cn/c058edcbf2024f9b911ae5caa15b9215.jpeg#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/d8c2bfeacb7b43a49e49d07d7f8623df.jpeg#pic_center)