第7章 调试和错误处理 7.1.1 VS中的调试
VS有一个输出窗口,调用方法是
需要注意的是,这个窗口有两个模式,使用其中的下拉列表就可以选择这些模式。可以在Build和Debug模式之间切换。Build和Debug模式分别显示编译和运行期间的信息。
本节提到的“写入Output窗口”时,实际上是指“写入Output窗口的Debug模式视图”。
另外,还可以创建一个日志文件,在运行应用程序时,会把信息添加到该日志文件中。把信息写入日志文件所使用的技巧与把文本写到Output窗口上所使用的技巧相同,但需要理解如何从C#应用程序中访问文件系统。现在,把这个功能放在本书后面的章节中,因为即使不太了解文件访问技巧,也可以把信息写入日志文件。
输出调试信息
在运行期间把文本写入Output窗口是非常简单的。只要用需要的调用替代Console.Writle()调用,就可以把文本写到希望的地方。此时,可以使用如下两个命令
Debug.WriteLine() //将信息输出到Output窗口的Debug模式视图
Trace.WriteLine() //将信息输出到Output窗口的Debug模式视图
此处的Debug和Trace和输出窗口中的Debug和Build无关,和项目的配置有关
这两个命令函数的使用方法几乎完全相同,但有一个关键的区别。第一个命令仅在调试模式下运行,而第二个命令还可用于发布程序。
实际上,Debug.WriteLine()命令甚至不能编译为可发布的程序,在发布版本中,该命令会消失,这肯定有其优点(显而易见的是,编译好的代码文件比较小)。
实际上,一个源文件可以创建出两个版本的应用程序。调试版本显示所有的额外诊断信息,而发布版本没有这个功能,也不向用户显示信息,否则,用户会觉得这非常讨厌。
这两个函数的用法与Console.WriteLine()是不同的。其唯一的字符串参数用于输出消息,而不需要使用{X}语法插入变量值。这意味着必须使用+运算符在字符串中插入变量值。它们还可以有第二个字符串参数,用于显示输出文本的类别,这样,如果应用程序的不同地方输出了类似的消息,我们就可以马上确定Output窗口中显示的是哪些输出信息。
这些函数的一般输出如下所示:
<category>:<message>
例如,下面的语句把MyFunc作为可选的类别参数
Debug.WriteLine("Added 1 to i","MyFunc");
其结果为:
MyFunc:Added 1 to i //MyFunc为category,Added 1 to i为message
下面的示例以这种方式输出调试信息。
class Ch07Ex01
{
public static void Method()
{
int[] testArray = { , , , , , , , , , , , };//初始化一个测试用的整数数组
int[] maxValIndices;//声明一个整数数组,用于存储Maxima函数的下标结果
//调用函数
int maxVal = Maxima(testArray,out maxValIndices);
//输出返回结果
Console.WriteLine("Maximum value {0} found at element indices.", maxVal);
foreach (int index in maxValIndices)
{
Console.WriteLine(index);
}
Console.ReadKey();
} /// <summary>
/// 计算整数数组中的最大值
/// </summary>
/// <param name="integers">整数数组</param>
/// <param name="indices">存储最大值的下标</param>
/// <returns></returns>
static int Maxima(int[] integers, out int[] indices)//最大数,极大值
{
Debug.WriteLine("Maximum value search started."); //开始搜索时,假定源数组中的第一个元素就是最大值,且数组中只有一个最大值
indices = new int[];
int maxVal = integers[];//将数组中的第一个元素赋予maxVal
indices[] = ;//第一个元素的下标
int count = ;//存储搜索到的最大值的个数 Debug.WriteLine(string.Format("Maximum value intialized to {0},at element index 0.", maxVal));//string.Format()比使用+连接运算符略高效些
for (int i = ; i < integers.Length; i++)//循环遍历整数数组,但忽略第一个元素,因为已经处理过
{
Debug.WriteLine(string.Format("Now looking at element at index {0}.", i));
if (integers[i] > maxVal)//每个值都和maxVal比较
{
maxVal = integers[i];//修改最大值
count = ;
indices = new int[];//修改下标数组
indices[] = i;
Debug.WriteLine(string.Format("New maximum found. New value is {0},at element index {1}.", maxVal, i));
}
else
{
if (integers[i] == maxVal)//找到和最大值相同的数据,记录index
{
count++;
int[] oldIndices = indices;//先备份旧的下标数组
indices = new int[count];//重建不同长度的数组来实现返回一个刚好能容纳搜索到的下标的数组 //CopyTo()函数:把oldIndices中的值复制到新的indices数组中,此函数只提取一个目标数组和一个用于复制第一个元素的下标
oldIndices.CopyTo(indices, );//把旧数组中的值复制到新的数组 indices[count - ] = i;
Debug.WriteLine(string.Format("Duplicate maximum {0} found, with {1} occurrences", maxVal, count));
}
}
}
Trace.WriteLine(string.Format("Maximum value {0} found,with {1} occurrences.", maxVal, count));//输出窗口中的Release模式下
Debug.WriteLine("Maximum value search completed.");
return maxVal;
}
}
Debug模式下的输出窗口
Release模式下的输出窗口
除了WriteLine()函数外,还需要注意其他一些问题
1.首先是Console.WriteLine()的等价函数:Debug.Write()和Trace.Write()
这两个函数使用与WriteLine()函数相同的语法(一个或两个参数,即一个消息和可选的类别),但它们还是有区别的,因为它们没有添加行尾字符
2.还有下述命令
Debug.WriteLineIf()
Trace.WriteLineIf()
Debug.WriteIf()
Trace.WriteIf()
这些函数的参数都与没有if的对应函数相同,但增加了一个必选参数,且该参数放在列表参数的最前面。这个参数的值为布尔值(或者计算结果为布尔值的表达式),只有这个值为true的之后,函数才会输出文本。使用这些函数可以有条件地把文本输出到Output窗口中。
例如,在某些情况下,只需输出调试信息,所以代码中有许多Debug.WriteLineIf()语句,它们都取决于具体的条件,如果没有这个条件,就不显示它们,以防Output窗口显示多余的信息。
1.跟踪点
设置好断点之后,在所在的行右键,选择断点,先插入断点
然后再右键,断点,命中条件
在打开的“命中断点时”的对话框中,在打印消息中输入要处处的字符串,如果要输出变量值,可以把变量名放在花括号中
2.诊断输出与跟踪点
第7章 调试和错误处理 7.1.1 VS中的调试的更多相关文章
- windows核心编程-第一章 对程序错误的处理
第一章-对程序错误的处理 在开始介绍Microsoft Windows 的特性之前,必须首先了解 Wi n d o w s的各个函数是如何进行错误处理的. 当调用一个Wi n d o w s函数时,它 ...
- 【转】gdb 调试段错误
[转]gdb 调试段错误 转自:blog.csdn.net/yangzhu1982/article/details/6318600 开发嵌入式Linux的时候经常会遇到segmentation fau ...
- linux ulimit的使用,如何产生core文件,调试段错误
---恢复内容开始--- 下面先简单介绍下ulimit命令: 1. limit -a 可以查看系统各种资源的限制,如: core文件大小,数据段的大小等. $ ulimit -a core file ...
- linux驱动调试--段错误之oops信息分析
linux驱动调试--段错误之oops信息分析 http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=29401328&id= ...
- 使用单进程、strace、gdb调试PHP错误
使用单进程.strace.gdb调试PHP错误 PHP一般是在FPM的呵护下运行的,但是某些情况下进程异常崩溃会导致502.下面是解决思想: 1. 单进程运行: php -d display_erro ...
- 在Linux中调试段错误(core dumped)
在Linux中调试段错误(core dumped) 在作比赛的时候经常遇到段错误, 但是一般都采用的是printf打印信息这种笨方法,而且定位bug比较慢,今天尝试利用gdb工具调试段错误. 段错误( ...
- gradlew 命令行 build 调试 构建错误 Manifest merger failed MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- HelloWorld程序编写调试及错误解决
HelloWorld程序编写调试及错误解决 eclipse软件编写 相较于windows内置记事本,eclipse编写程序更为简单快捷.由其生成的程序模板编写如下: package helloworl ...
- Linux下调试段错误 (gdb,core,ulimit)
Linux环境下经常遇到某个进程挂掉而找不到原因,我们可以通过生成core file文件加上gdb来定位. (1)首先 在makefile中要增加编译调试选项 -g,才可以利用下面的gdb来调试 gc ...
随机推荐
- LeetCode——Summary Ranges
Description: Given a sorted integer array without duplicates, return the summary of its ranges. For ...
- 微信小游戏 Egret开发数据域官方Demo下载地址
随着引擎的升级,伴随而来就是各种问题,使用官方调试过的Demo,少走弯路. Mark下 官方Demo
- PHP概率算法---砸金蛋示例
这是一个很经典的概率算法: function get_rand($proArr) { $result = ''; //概率数组的总概率精度 $proSum = array_sum($proArr); ...
- AE导出mov
最近安装了AE发现没法导出MOV格式的: 感觉应该是没有安装支持MOV的播放器之类的原因造成的:果断去下载一个quicktime 安装好之后重启发现真的有 mov 格式了
- class表与student表之间的关系
1.班级表 2.学生表 3.student(学生表),Score(成绩表),course(课程表) 4.三张表联合查询 5.连接连个结果集(两个集合必须有相同的列数,列具有相同的数据类型,最 ...
- ZOJ 3203 Light Bulb
Compared to wildleopard's wealthiness, his brother mildleopard is rather poor. His house is narrow a ...
- Code Forces 149DColoring Brackets(区间DP)
Coloring Brackets time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- HDU 4597 Play Game(DFS,区间DP)
Play Game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Sub ...
- .net各版本framework官方下载地址
版本 链接 说明 Microsoft .NET Framework 4(独立安装程序) https://www.microsoft.com/zh-cn/download/details.aspx?id ...
- Rancher OS
Rancher OS 是生产规模中运行 Docker 最小,最简单的方式.RancherOS 的所有东西都作为 Docker 管理的容器.这些系统服务包括 udev 和 rsyslog.Rancher ...