VC++6.0调试:Watch窗口的使用
#include <stdio.h>
#include <windows.h> class AutoExpand
{
public:
AutoExpand(int val, char* pval)
{
a = val;
p = pval;
}
private:
int a;
char *p;
};
class CantExpand
{
public:
CantExpand(int val, char* pval)
{
a = val;
p = pval;
}
private:
int a;
char *p;
}; int main(void)
{
int p[] = {0x31,0x32,0x33,0x34};
int *a = p; FILE* fp = fopen("File Not Exist", "r");
DWORD dwError = GetLastError(); AutoExpand ae(, "abc");
CantExpand ce(, "abc"); return ;
}
上面代码中出现的变量先说明一下:
p: 是整形数组,含四个元素,总共16Byte;
a: 整形指针,指向数组p;
fp: 文件指针,用来标识打开的"File Not Exist",我机器里是没这个文件的;
dwError: 获得fopen失败的错误码。一般来说可以用FormatMessge来格式化这个错误原因或者直接用VC自带的工具errorlookup来查找这个错误码的解释;
ae和ce: 是自定义的AutoExpand类型的变量和CantExpand类型的变量。注意,这两种类型只有类型名字不同。
下面看一下我在调试这个程序的时候,watch窗口的显示:
上图中,左边是Context窗口的Locals页,显示所有局部变量。右边是Watch窗口,是我自己添加的要观察的对象。
好,先看看整形数组p。我们看到Context窗口的显示p其实只显示了数组的地址,点了+号展开后,显示出了4个整形数据。而右边窗口,我添加了一个p,c。p后面加个",c"是什么意思呢?看看效果,p,c下面的[0],[1],[2],[3]显示的是这4个整形值对应的ascii字符哈。所以从这里有了第一个小技巧:
1.watch窗口中,在整形变量后面加上",c"可以显示该变量对应的ASCII字符。实际上,可以直接敲数字这么显示也行。比如上面右边窗口中的118,c的对应值是'v'。也就是说118对应的ASCII字符是'v'。那么,反过来,要知道一个字符的ASCII码值怎么看呢?看上面,'v',d就是显示字符'v'对应的十进制ASCII码值是118。 'v',x显示的是对应的十六进制的ASCII码值。除了",c" ",d" ",x"外,还有一些其他的参数可以加,见后面的附表。
然后我们看看变量a。a是个指针。看左边窗口,即使点了它的+号展开,也只看到了它指向的地址的第一个元素(49)。如果想要看得更多的数据,也可以像我一样,在上面的Memory窗口里看。但是Memory窗口只有一个,要看多个指针指向的数据就麻烦了,切来切去。那就在watch窗口中显示吧,a,4就可以了,看到我的watch窗口的显示没?所以,有了第二个小技巧:
2.watch窗口中,把指针当成数组看,只要在指针名后面加上一个长度,就可以想看数组一样看到对应的数据了。比如我上面的a,4。那么如果一个指针指向的数据很大,比如一个整形指针a是指向一个1000个整数的大块内存,我只想看看最后4个数据,要怎样呢?那就(a+996),4 呗。从第996个数据开始,看4个~
接下来这个小技巧是我最喜欢的一个了。调试中遇到系统函数调用失败的情况,通常都要加上GetLastError()函数获得返回值,然后查对应的解释才知道错误原因。比如,我上面的代码要打开一个不存在的文件,结果fopen失败。取回了错误码dwError=2,一查才知道是文件不存在。那么可不可以不用查,调试器直接告诉我原因呢?当然可以,不然我写这干嘛!刚才的错误码2是记录在dwError中了,所以只要在watch窗口看看dwError,hr看value栏:系统找不到指定的文件!爽吧!总结一下,第三个小技巧:
3. 在watch窗口中察看错误原因,只需要在错误之后面颊上",hr"就可以了。比如我上面的 dwError,hr 和 2, hr 都能够显示错误消息。想看某个错误码的解释,只要后面加上",hr"就轻松搞定,非常方便!这里还要提一下的是,即使不调用GetLastError()也是可以看错误原因的。在fopen()调用完后,直接在watch窗口敲err,hr也可以显示最近一次的错误原因。但是我机器重新装了os,还没装vc,现在用的还是安装前的尸体。所以这个err,hr的显示有问题。不过还是有应对之法,那就是强大的TIB信息。watch窗口看看*(unsigned long*)(TIB+0x34), hr也是一样的。至于为什么吗,那就是GetLastError的机制了。
还剩2个变量,ae和ce。这两变量类型名不同,但是其他全都一样。为什么这两个变量在watch窗口中显示的不一样呢?ae直接显示出了类成员的值,ce就显示了个......嗯,这就是最后一个小技巧:
4. 在vc安装目录的msdev\bin目录下有个autoexp.dat文件。可以在里面自定义数据的显示。具体的看看它前面的大段说明,说得很详细。我就是在文件后面加上一行AutoExpand =int_val=<a,d> sz_val=<p,s>。
附表:
下表说明调试器可识别的格式说明符。
说明符 | 格式 | 值 | 显示 |
---|---|---|---|
d,i | signed 十进制整数 | 0xF000F065 | -268373915 |
u | unsigned 十进制整数 | 0x0065 | 101 |
o | unsigned 八进制整数 | 0xF065 | 0170145 |
x,X | 十六进制整数 | 61541(十进制) | 0x0000F065 |
l,h | 用于 d、i、u、o、x、X 的 long 或 short 前缀 | 00406042,hx | 0x0c22 |
f | signed 浮点型 | 3./2. | 1.500000 |
e | signed 科学计数法 | 3./2. | 1.500000e+000 |
g | signed 浮点型或 signed 科学计数法,无论哪个都更短 | 3./2. | 1.5 |
c | 单个字符 | 0x0065 | 101 'e' |
s | 字符串 | 0x0012fde8 | "Hello world" |
su | Unicode 字符串 | "Hello world" | |
hr | HRESULT 或 Win32 错误代码。(调试器自动将 HRESULT 解码,因此这些情况下不需要该说明符。 | 0x00000000L | S_OK |
wc | 窗口类标志。 | 0x00000040 | WC_DEFAULTCHAR |
wm | Windows 消息数字 | 0x0010 | WM_CLOSE |
下表包含用于内存位置的格式化符号。
符号 | 格式 | 显示 |
---|---|---|
ma | 64 个 ASCII 字符 | 0x0012ffac .4...0...".0W&.......1W&.0.:W..1...."..1.JO&.1.2.."..1...0y....1 |
m | 以十六进制表示的 16 个字节,后跟 16 个 ASCII 字符 | 0x0012ffac B3 34 CB 00 84 30 94 80 FF 22 8A 30 57 26 00 00 .4...0...".0W&.. |
mb | 以十六进制表示的 16 个字节,后跟 16 个 ASCII 字符 | 0x0012ffac B3 34 CB 00 84 30 94 80 FF 22 8A 30 57 26 00 00 .4...0...".0W&.. |
mw | 8 个字 | 0x0012ffac 34B3 00CB 3084 8094 22FF 308A 2657 0000 |
md | 4 个双倍字长 | 0x0012ffac 00CB34B3 80943084 308A22FF 00002657 |
mq | 2 个四倍字长 | 0x0012ffac 7ffdf00000000000 5f441a790012fdd4 |
mu | 2 字节字符 (Unicode) | 0x0012fc60 8478 77f4 ffff ffff 0000 0000 0000 0000 |
可以使用带有计算为位置的任何值或表达式的内存位置说明符。
VC++6.0调试:Watch窗口的使用的更多相关文章
- vc++6.0各种报错合集(附:VC++6.0调出打印窗口的方法)
背景: 由于VC++6.0对于现在的我来说,只是一个工具,暂时没有太多的时间分配到这块去深究它,由于不明其原理,因此也只是在此把错误积累下来,以备下次相同错误出现时能快速排除,节省时间. 正文 一.出 ...
- VC++6.0调试简单快捷键
编译——F7 重新编译——Ctrl+F7 设置断点 ——F9 取消断点——F9 删除所有断点——Ctrl+Shift+F9 开始调试——F5 进行下一次调试——F5 停止调试——Shift+F5 逐过 ...
- 【转】 VC++6.0 在Win7 64位下调试,Shift+F5无法退出
Win7 64位VC++6.0调试代码无法关闭窗口解决方法 VC++6.0 在64位Windows7下调试的时候,再结束调试,程序无法退出,只能关闭VC++6.0 IDE环境. 问题描述:当我击F5开 ...
- VC++ 6.0中实现三叉切分窗口与多视图 [转]
一.引用 当用户需要同时对文当的不同部分进行编辑时,常常会用到切分窗口;这些窗口可以都是相同的视,或者一个窗口为列表视,而另一个为树型视图.应用程序框架有多种方式来表示多视图,切分窗口是其中的方式之一 ...
- VC++6.0远程调试(亲试成功)
0 前言 VS2008及以上远程调试上篇已经讲过,这里再讲下VC++6.0开发环境下的远程调试能力,仅需下面4步即可,更方便的就接着后面的5-6步. 因为目标程序需要在有采集卡等相关硬件支持下的工控机 ...
- VC++6.0 打印调试信息
1.在MFC中加入TRACE语句 2.在TOOLS->MFC TRACER中选择 “ENABLE TRACING”点击OK 3.进行调试运行,GO(F5)(特别注意:不是执行‘!’以前之所以不能 ...
- VC++6.0一些常见问题解决方法(打开多个窗口、行号、添加文件无响应、更改.exe图标及名称等等)
背景: 最近使用VC++6.0做一个界面,供测试CAN通信使用.由于客户希望我们提供简单方便的函数接口让其最快速使用CAN,DLL(动态链接库)是不二之选.做DLL需要两个VC窗口进行测试才方便.可是 ...
- 自己编写的基于VC++6.0的串口调试软件,并贡献源程序!
自己编写的基于VC++6.0的串口调试软件源程序! 程序下载链接: 点击打开链接
- VC++6.0 IDE的工程用Code::Blocks来打开、编译、调试终极配置方案
本篇文章转自 CSDN blog,转载请注明出处! 原文地址: http://blog.csdn.net/liquanhai/article/details/6618300 引子:竟然可以用Code: ...
随机推荐
- VARCHAR的最大长度的问题
大家知道,在SQL Server 2000中,VARCHAR的最大长度是8000,如果字符串的长度超过8000,保存在VARCHAR中时就会被截断.如果你需要传入的参数恰好很长,比如是一个xml,很多 ...
- PSP个人项目耗时对比记录表:四则运算
Personal Software Process Stages Time(%) 计划 5 •估计这个任务需要多长时间 5 开发 60 •需求分析 5 •生成设计文档 5 ...
- PICT用户手册 [转]
PICT 3.3 User's Guide Jacek Czerwonka, Test Lead, Microsoft Corporation Overview Using PICT to Combi ...
- ReLU 和sigmoid 函数对比
详细对比请查看:http://www.zhihu.com/question/29021768/answer/43517930 . 激活函数的作用: 是为了增加神经网络模型的非线性.否则你想想,没有激活 ...
- WinForm POST上传与后台接收
前端 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using ...
- react-native项目之样式总结
react native(以下简称rn)里面涉及到的样式规则都是在js文件中写的,一改pc端的在样式文件中定义规则,所以pc端开发习惯的童鞋转向开发rn项目时,可能会对样式感到有些奇怪:其实react ...
- OSLab多进程
日期:2019/3/23 内容:Linux下与多进程相关的函数. 进程基本知识 定义 应用程序关于某数据集合上的一次运行活动. 特点 ·操作系统进行资源分配和调度的基本单位 ·进程是程序的一次 ...
- POI读写海量Excel
目前处理Excel的开源javaAPI主要有两种,一是Jxl(JavaExcel API),Jxl只支持Excel2003以下的版本.另外一种是Apache的Jakarta POI,相比于Jxl,PO ...
- SpringCloud之Eureka集群
前面我们介绍了SpringCloud注册中心Eureka,但是存在一个单点故障的问题,一个注册中心远远不能满足实际的生产环境,现在我们介绍一下如何搭建一个Eureka集群. 一:集群环境搭建 我们先建 ...
- MySQL 5.6不删空用户的影响
目录 MySQL 5.6不删空用户的影响 问题 分析 测试 启动mysqld时没有加上--skip-name-resolve 启动mysqld时加上--skip-name-resolve 结论 MyS ...