如何用VC6.0调试代码(入门)
vc++6.0调试方法(附有快捷键)
调试程序可以帮助了解程序是怎样运行的。
1、如何快速地规范代码缩进格式选中所需要规范的代码,按shift+F82、如何在Release状态下进行调试Project->Setting…->Project Settings对话框,选择Release状态。
“C/C++”标签页中的Category选General,Optimizations选Disable(Debug),Debug info选Program Database。
在“Link”标签页中选中Generate debug info复选框。
注:只是一个介乎Debug和Release的中间状态,所有的ASSERT、VERIFY都不起作用,函数调用方式已经是真正的调用,而不查表,但是这种状态下QuickWatch、调用队列跟踪功能仍然有效,和Debug版一样。
3、Release和Debug有什么不同。
Release版称为发行版,Debug版称为调试版。
Debug中可以单步执行、跟踪等功能,但生成的可执行文件比较大,代码运行速度较慢。
Release版运行速度较快,可执行文件较小,但在其编译条件下无法执行调试功能。
Release的exe文件链接的是标准的MFC DLL(Use MFC in a shared or static dll),比如MFC42.DLL。
这些DLL在安装Windows的时候,已经配置,所以这些程序能够在没有安装Visual C++ 6.0的机器上运行。
而Debug版本的exe链接了调试版本的MFC DLL文件,如MFC42D.DLL。
在没有安装Visual C++6.0的机器上不能运行,因为缺MFC42D.DLL等,除非选择use static dll when link。
4、ASSERT和VERIFY有什么区别ASSERT里面的内容在Release版本中不编译,VERIFY里面的内容仍然编译,但不再判断真假。
所以后者更安全一点。
vc++6.0环境下程序调试教程
更多共享就在:/avbbtv/home,个人整理,没有版权,欢迎共享---avbbtv如何在Visual C++ 6.0 环境下进行简单的C语言程序调试桂林电子科技大学波仔*****************文章简介本文主要介绍如何在VC6.0 环境下进行简单的C 语言程序调试。
作为阅读本文的基础,读者应该熟悉如何在VC6.0 环境下建立Win32 Console Application(Win32控制台程序) 类型的工程。
请结合文章给出的案例,按照文档中的描述一步一步做。
如果只是阅读,则收效甚微。
在做完文章给出的案例后,你应该尝试着将文章中介绍的知识和技巧应用到你实际开发的程序中。
如果阅读完一遍后,对调试基本概念还是不了解,建议你再多看几遍。
在介绍如何进行C 语言程序调试( debugging)前,首先介绍程序调试的概念。
调试(debug)一词在计算机领域最早被提及,源于美国人Admiral Grace Hopper(葛丽丝·霍普、COBOL 语言发明者、电脑科学家) 。
二十世纪四十年代(1940s) Grace Hopper在哈佛大学为名为马克2 号(Mark II) 的计算机( 由IBM 公司制造) 编写程序时,有一次在排除计算机故障时,发现一只飞蛾被夹在触点原件之间,导致计算机无法运行。
于是她诙谐的把计算机故障称之为“臭虫(bug)”,把排除程序故障称之为debug 。
从此之后,在计算机领域,程序调试或查找程序故障称为debug 。
进行程序开发时,很多情况是程序通过编译、链接( 亦即不存在语法错误) ,但是在运行时往往得不到正确的结果( 需要多组输出数据进行测试)。
这时往往意味着程序存在逻辑错误( 与语法错误对应,通常是指程序所体现出的逻辑不符合开发者要求,或者是开发者本身对程序所要解决的某一问题的理解存在逻辑偏差) ,而查找逻辑错误的过程可称之为程序调试。
程序案例下面以一个程序案例为例,介绍如何在VC6.0 下进行程序调试。
使用VC6.0调试程序
结构体类型的定义
struct 结构体类型名 { 类型标识符 成员名1;
类型标识符 成员名2; ……
类型标识符 成员名n; };
如: struct student { char name[10];
long id; char gender; int age; }
注意: struct student 应作为一个类型整体, name[10]、id、gender、age都是其成员。 struct及花括号后的“;”不能省。
a
因此,在C语言中,将地 址形象化地称为指针
2012 35
b
….
2010 p
2012 q
定义一个指针变量
指针变量的定义一般形式为:
基类型 *指针变量名;
例如: int i, j, *pi, *pj; float x, y, *p1, *p2;
指针变量的赋值:使得指针变量指向变量 指针变量名=&变量名;
设有一个函数process,在调用它时,每次实现不同的功 能。输入a和b两个数,第一次调用时找出a与b中的大者,第
二次找出小者,第三次求和。
#include<stdio.h> void main() {int max(int,int); int min(int,int); int add(int,int); int process(int, int, int (*fun)()); int a,b; printf("enter a and b:"); scanf("%d%d",&a,&b); printf("\nmax="); process(a,b,max); printf("\nmin="); process(a,b,min); printf("\nsum="); process(a,b,add); }
VC6.0调试方法
VC6.0调试⽅法
1.打开你要调试代码的⼯作空间。
2.按快捷键F5或点击以下图⽚上标记的图标进⼊调试模式。
3.打开调试⼯具条,⼀般情况下当你按F5键后会⾃动弹出,如果没有弹出的话,右击⼯具栏空⽩处,会弹出下图,选中调试,就会出现调试⼯具条。
4.接下来,在监视窗⼝中添加你要监视数据变化的变量。
5.按F11逐语句的调试代码,如果某⼀语句是⼀函数,你不希望进⼊该函数时,F10逐过程来查看,在代码的调试过程中,通过监视窗⼝查看变量值的变化,从⽽确定代码是否有问题。
6.如果希望跳出某⼀函数时,按快捷键Shift+F11,或者直接点击调试⼯具条上的按钮就可以跳出该函数了。
7.如果只是希望调试某⼀部分代码的话,可以设置断点来调试,调试⽅法如上,只是在要调试的代码之间⽤断点来分开。
设置断点时,光标放在你要设置断点的那⾏,按F9或点击编译微型条上⾯的类似⼿状的按钮即可。
Visual C++ 6.0程序调试
Visual C++ 6.0程序调试在编写较长的程序时,能够一次成功而不含有任何错误决非易事,对于程序中的错误,系统提供了易用且有效的调试手段。
调试是一个程序员最基本的技能,不会调试的程序员就意味着即使学会了一门语言,却不能编制出任何好的软件。
1、调试程序环境介绍①进入调试程序环境选择主菜单“编译(Build)”中的“开始调试(Start Debug)”命令,选择下一级提供的调试命令,或者在菜单区空白处单击鼠标右键,在弹出的菜单中选中“调试(Debug)”项。
激活调试工具条,选择需要的调试命令,系统将会进入调试程序界面。
同时提供多种窗口监视程序运行,通过单击“调试(Debug)”工具条上的按钮,可以打开/关闭这些窗口,参考图8。
②Watch(观察)窗口单击调试(Debug)工具条上的Watch按钮,就出现一个Watch窗口,系统支持查看程序运行到当前指令语句时变量、表达式和内存的值。
所有这些观察都必须是在断点中断的情况下进行。
观看变量的值最简单,当断点到达时,把光标移动到这个变量上,停留一会就可以看到变量的值。
还可以采用系统提供一种被称为Watch的机制来观看变量和表达式的值。
在断点中断状态下,在变量上单击右键,选择Quick Watch,就弹出一个对话框,显示这个变量的值。
在该窗口中输入变量或者表达式,就可以观察变量或者表达式的值。
注意:这个表达式不能有副作用,例如“++”和“- -”运算符绝对禁止用于这个表达式中,因为这个运算符将修改变量的值,导致程序的逻辑被破坏。
③Variables(变量)窗口单击调试(Debug)工具条上的“Variables“按钮弹出Variables窗口,显示所有当前执行上下文中可见的变量的值。
特别是当前指令语句涉及的变量,以红色显示。
④Memory(内存)由于指针指向的数组,Watch窗口只能显示第一个元素的值。
为了显示数组的后续内容,或者要显示一片内存的内容,可以使用memory功能。
Visual C++ 6.0 调试工具使用
Visual C++ 6.0 调试工具使用在开发程序的过程中,需要不断地调试自己的程序,或检查错误,或测试程序的稳定性,这就需要借助调试工具来进行。
选择一个好的调试工具并能够熟练地使用它,将会使程序开发变得更加容易,从而大大提高程序开发的效率。
目前有许多调试工具,集成在Visual C++中的调试工具便具有相当强大的功能。
1.1 设置工程的调试属性在Visual C++中建立一个工程(Project)时,Visual C++都会自动创建一个Debug 目录,在该目录下存放在开发过程进行调试时生成的文件以及生成的可执行文件,不妨将此时生成的可执行文件称为Debug版本。
在Debug 版本当中,包含着Microsoft 格式的调试信息,而且不进行任何代码优化。
一般情况下,在程序的开发过程中使用Debug 模式。
在应用程序开发完成之后,要将程序发行时,需要编译形成另一种版本的可执行文件,称为Release 版本,在Release 版本中对可执行程序的二进制代码进行了优化,其中不包含任何的调试信息。
要建立Release 版本的可执行文件,可以选择菜单Project 中的Setting 命令,这时屏幕上面弹出Project Settings 对话框,如图1-1 所示。
在Settings For 下拉列表中选择Release,按OK 按钮退出。
如果要在Visual C++中调试程序,则工程的应设为Debug 版本。
一般Visual C++建立一个工程(Project)时,默认采用Debug 版本。
图1-1 设置工程的调试属性1.2 学习设置断点进行单步调试通常,一个应用程序是连续运行的,但是在程序调试的过程中,往往需要在程序的运行过程的某一阶段来观测应用程序的状态,所以必须使程序在某一地点停下来。
在Visual C++ 中,可以通过设置断点来达到这样的目的。
在设置好断点之后,当程序运行到设立断点处时就停止运行,此时就可以利用各种工具来观察程序的状态,也可以设置各种条件使程序按要求继续运行,这样就可以进一步观测程序的流向。
VC++6.0_使用方法(图片解析,非常好懂)
第一部分C语言编程环境简介第1章计算机程序设计实验的一般步骤1.1 计算机程序设计实验的目的C语言程序设计是一门实践性很强的课程,该课程的学习有其自身的特点,学习者必须通过大量的编程训练,在实践中掌握程序设计语言,培养程序设计的基本能力,并逐步理解和掌握程序设计的思想和方法。
具体的说,通过上机实践,应该达到以下几点要求:1.使学习者能很好地掌握一种程序设计开发环境的基本操作方法(例如(Visual C++6.0),掌握应用程序开发的一般步骤。
2.在程序设计和调试程序的过程中,可以帮助学习者进一步理解教材中各章节的主要知识点,特别是一些语法规则的理解和运用,程序设计中的常用算法和构造及应用,也就是所谓“在编程中学习编程”。
3.通过上机实践,提高程序分析、程序设计和程序调试的能力。
程序调试是一个程序员最基本的技能,不会调试程序的程序员就意味着他即使会一门语言,却不能编制出任何好的软件。
通过不断的积累经验,摸索各种比较常用的技巧,可以提高编程的效率和程序代码的质量。
下面介绍计算机程序设计实验的一般步骤:1.2 计算机程序设计实验的准备上机前需要做好如下准备工作,以提高上机编程的效率。
(1)在计算机上安装一种程序设计开发工具,并学会基本的操作方法。
(2)复习与本次实验相关的教学内容和主要知识点。
(3)准备好编程题程序流程图和全部源程序代码,并且先进行人工检查。
(4)对程序中有疑问的地方做出标记,充分估计程序运行中可能出现的问题,以便在程序调试过程中给予关注。
(5)准备好运行和调试程序所需的数据。
1.3 计算机程序设计实验的步骤(1)运行程序设计开发工具,进入程序设计开发环境。
(2)新建一个文件,输入准备好的程序。
(3)不要立即进行编译和连接,应该首先仔细检查刚刚输入的程序,如有错误及时改正,保存文件后再进行编译和连接。
(4)如果在编译和连接的过程中发现错误,根据系统的提示找出出错语句的位置和原因,改正后再进行编译和连接。
VC++6.0使用手册(史上最全)
图1-1Visual C++界面开项目工作区文件时其他文件随即会自动打开。
在此文件夹下还会创建 Res(资源)、Debug(调试)、Release(发行)等子文件夹。
2.2编辑 在编辑窗口打开、浏览文件、输入、修改、复制、剪切、粘贴、查找、替换、撤销等操作,可以通过菜单完成,也可以通过工具栏按钮完成,这些与 Word 之类的 windows 编辑器用法完全相同,这里就不再重复叙述了。
2.3辅助VC 不仅提供了“语法着色”帮助我们阅读程序,还可以通过一些快捷键检查常见的括号不匹配错误。
MSDN 也可以在编辑过程中提示存在的变量名、函数名。
很多程序员借助类似 Visual Assist X 的工具辅助开发,减少程序出错的可能性。
3.开发 C 程序3.1开发单个 C 语言程序1. 创建一个工作文件夹。
由于开发过程会产生一系列文件,建议每开发一个新的 C 程序都创建一个工作文件夹。
还可以将所有工作文件夹集中到一起,如E:\LXH\EX01-01 、E:\LXH\EX03-02 等。
2. 启动 Visual C++。
3. 新建一个 C 语言源程序。
选择菜单:File 下的 New 菜单项,出现如图 1-2 所示 new(新建)对话框。
图1-2选择菜单File下的New菜单项选择 Files标签下的 C++Source File 在“E:\LXH\EG01-01”文件夹中创建C 程序:eg01-01.c,如图 1-3 所示。
图1-3Files标签4. 输入、编辑源程序。
注意不要输入中文标点符号,要及时按 Ctrl+S 保存文件,如图 1-4 所示。
图1-4输入源程序5.编译、连接。
点击“BuildMiniBar”工具栏上的“Build”按钮进行编译、连接。
也可以选择菜单 Build 下的 Build (F7) 菜单项或Rebuild All菜单项。
更简捷的方法是直接按 F7 功能键。
Visual C++将提示创建默认工作区,如图 1-5 所示。
vc6.0安装教程与调试技巧
vc6.0安装教程与调试技巧vc6.0的安装过程1.首先解压安装文件的压缩包2.然后再选择安装的版本,VC6CN 表示的是中文版,VC6EN表示英文版。
3.打开VC6CN文件夹,其中有如下图标,鼠标双击。
4.如下图所示就是我们安装的第一步,单击下一步。
5.选择“接受协议”后单击下一步。
6.本软件属于破解版,故无需输入产品ID号码,直接单击下一步。
7.选择“安装visual c++6.0中文企业版(I)”,这就是我们要安装的程序,单击下一步。
8.单击下一步。
9.如下界面,单击“继续”,开始安装软件。
10.点击“确定”。
11.选择“是”,继续安装。
12.选择“typical”继续安装13.选择“ok”。
14.选择“确定”15.选择“确定”16.取消“安装MSDN”前面的勾号,选择“退出”。
17.选择“是”,取消MSDN的安装。
18.程序安装完毕,再电脑的“开始菜单”中,选择“所有程序”,在“Microsoft Visual C++ 6.0”目录中选择“Microsoft Visual C++6.0”就可以运行程序了。
也可以将这个图标发送到桌面快捷方式,这样就可以直接在桌面上运行程序。
调试技巧调试程序可以帮助的了解程序是怎样运行的。
1、如何快速地规范代码缩进格式选中所需要规范的代码,按shift+F82、如何在Release状态下进行调试Project->Setting…->Project Settings对话框,选择Release 状态。
“C/C++”标签页中的Category选General,Optimizations 选Disable(Debug),Debug info选Program Database。
在“Link”标签页中选中Generate debug info复选框。
注:只是一个介乎Debug和Release的中间状态,所有的ASSERT、VERIFY都不起作用,函数调用方式已经是真正的调用,而不查表,但是这种状态下QuickWatch、调用队列跟踪功能仍然有效,和Debug版一样。
【Visual C++】Visual_C++6.0调试功能图解教程
Visual C++ 6.0调试功能这是我自己在学习时整理的,希望对大家有用.其中有几个部分的内容,如下:※My Note全部由我截图并参考资料进行说明,这其中有大量的内容是调试过程中体会总结才写的.有不当之处请大家更正.※From 《Visual C++ Debugger》这本书写得非常的不错,从里面截了一些有用的图,主要是强烈推荐大家阅读这本书.※Debug Menu From MSDN这是我从Visual C++ 6.0 MSDN Library October 2001中查来的,在My Note中有很多是从那里参考的.强烈推荐大家看这份英文说明.※From 《visual C++ 6.0开发工具与调试》这是我从网络上搜索到的,问题很经典,强烈推荐大家参看学习,避免不必要的错误.My Note○常用功能:1.Restart(Ctrl+shift+F5):此debugger功能将从程序的开始(第一有效行)处全速执行,而不是从当前所跟踪的位置开始调试,这时所有变量的当前值都将被丢弃,debugger会自动停在程序的main()开始处.这时如果选择Step Over(F10)就可以逐步执行main()函数了.2. Stop Debugging(Shift+F5):此debugger功能将终止(所有)调试,并返回到常规编辑状态.3. Break(此功能常常在遇到调用函数的语句时可见.):此功能将在调试过程中的debugger当前位置挂起程序的执行,然后就可以在调试状态一修改程序的代码,接着可以用Apply Code Changes(Alt+F10)来应用修改的代码到正在调试的程序当中.如果,当前(需要,待)可以(从DOS等窗口)输入值,挂起后将不能再输入.4.Apply Code Changes(Alt+F10):此功能可以在程序正在调试程序过程中应用(挂起)修改后的源代码.如,选择Break功能并修改代码后,只要选择Apply CodeChanges(Alt+F10)就能将修改后的代码应用到正在调试的程序当中.5. Show Next Statement(Alt+Num*):此功能将显示程序代码的下一条语句,如果源代码中找不到,则在Disassembly窗口中显示语句.当在Disassembly窗口中显示时,可以单击Disassembly 返回到源代码窗口.6.Step Into(F11):此功能可以单步进入到在调试过程中所跟踪的调用函数的语句的函数内部.如,当前语句是”d.Display()”,选择Step Into(F11)后,Debugger将进入Display()函数内部并停在Display()函数内部的第一条语句上.(此时,就可以Step Over(F10)对Display()函数进行单步调试了.)7. Step Over(F10):此功能可以单步对所在函数单步调试,如果调试的语句是一个调用函数的语句时,Debugger将全速执行所调用的函数,单步(一步)通过所调用的函数,Debugger停该调用语句的下一条语句上.8.Step Out(Shift+F11):此功能将使Debugger切换回全速执行到被调用函数结束,并停在该函数调用语句的下一条语句上.当确定所调用的函数没有问题时可以用这个功能全速执行被调用函数.9. Run to Cursor(Ctrl+F10):此功能将全速执行到包含插入点光标所在的行,可以作为在插入点光标处设置常规断点的一种选择.注意,当光标处不是一个有效的执行语句时此功能将不起作用.10.Go(F5):此功能将全速执行程序直到遇到一个断点或程序结束,或直到程序暂停等待用户输入.注意,此功能最能有效的调试循环,常将断点设置在循环体内,重复的按F5全速执行循环体可以测试循环过程中的产生的变化.11.Step Into Specific Function:此功能可以可以单步通过程序中的指令,并进入指定的函数调用,此功能对于函数的嵌套层不限.From 《Visual C++ Debugger》Debug Menu From MSDNStart Debug Commands (Build menu)When you begin debugging, the Debug menu appears, replacing the Build menu on the menu bar. You can then control program execution using the commands listed in the following table.Debug Menu Commands that Control Program ExecutionThe following additional commands appear on the Debug menu:From 《visual C++ 6.0开发工具与调试》1、如何快速地规范代码缩进格式选中所需要规范的代码,按shift+F82、如何在Release状态下进行调试Project->Setting=>ProjectSetting对话框,选择Release状态。
VC6.0使用说明(新建工程、调试)
1. 启动VC6.0,出现如下界面
第一步:File
VC6.0编程步骤
2. 选择菜单“文件(File)” “新建(New…)”,出现如下 窗口 选择”Projects”
填写工程名称 选择工程保存位置 强烈建议工程保 存在自己单独的 一个文件夹里, 一道题一个文件 夹 选中这些选项 通常是已经选好的 以上信息都正确后,最后按 下此按钮,进入下一步
• F9 • Shift+F5
设置/取消 断点 结束程序调试,返回程。将光 标移至断点设置处, 按F9设置或取消断点。 在调试过程中,黄色箭 头指向的代码行是还没 有执行的代码行。在本 题中,swap1函数已经 执行完了,而swap2还 没有开始执行。
2,按F5运行至 设置断点处。
当一切都正确后,按下此 按钮,进入下一步
VC6.0编程步骤
6. 当上一步按下“确定”按钮后,将出现如下 所示界面 编译并运行程序
快捷键:Ctrl+F5
编译
链接 快捷键:F7
注意该白色窗体,可用 于输入代码,见下一步
VC6.0编程步骤
7. 输入程序代码
按F7进行编 译链接,进 入下一步
请在选中多行代码 的情况下,测试这 三个按钮的功能。
程序代码
VC6.0编程步骤
8. 代码编译链接
本例中,我们故意在printf函数后面 遗漏分号,以及省略return语句。于 是在按F7进行编译后,出现如下错 误提示及警告(warning)。
如果错误较多, 可以点击这里 上下滑动查看 信息。
VC6.0编程步骤
8. 代码编译链接
2
通过单击错误信息, 在编辑框内将出现一 个箭头,标明该错误 信息可能出现的位置。
VC++6.0中如何编译运行及调试C语言程序
VC++6.0中如何编译运行调试C语言程序1.启动VC++6.0 (如下图)2.单个源文件的编译运行例如下面的源代码#include<stdio.h>void main(){ int i,sum=0;for(i=1;i<=10;i++){sum=sum+i;}printf("sum=%d\n",sum);}打开VC++6.0,如图1所示(图1)选择“文件”→“新建”,打开如图2所示(图2)选择“文件”项,如图3所示(图3)选择“C++ Source File”项,并在“文件名”项目下输入“sum.c”如图4所示(图4)单击“确定”,打开如图5所示(图5)输入如上源代码,如图6所示(图6)选择按编译按钮调试程序,看看有没有错误,有的话改正,没有的话就可以再按连接按钮检查连接(多文件工程时常用,检查文件间是否正常连接)。
(图7)在下端的输出窗口会有错误和警告的提示,如果没有错误选择“执行”(或按Ctrl+F5组合键)即可出现运行结果,如图8所示(图8)3.多个源文件的编译运行以上是运行单个源文件的情况,但是在程序设计时,往往是由几个人各自独立编写不同的程序,显然这些程序是不能写在一起进行编译的,这时就需要建立项目工作区来完成几个独立程序的编译,具体方法如下。
首先建立两个文本文件,分别命名为“file1.c”和“file.c”,分别在两个文件中输入如下两个源代码,然后保存。
源代码1:#include<stdio.h>void main(){void sum();sum();}源代码2:#include<stdio.h>void sum(){int i,sum=0;for(i=1;i<=10;i++){sum=sum+i;}printf("sum=%d\n",sum);}打开VC++6.0,选择“文件”→“新建”打开如图9所示(图9)选择“工作区”项,并在“工作空间名称”项目下输入“sum”如图10所示(图10)单击“确定”,打开如图11所示(图11)在左侧的“工作区窗口”显示了新建立的工作区选择“文件”→“新建”打开如图9所示,在“工程”项目下选择“W in32 Console Application”项,并在“工程名称”项目下输入工程名称,如“sum”,选择“添加到当前工作空间”项,如图12所示(图12)单击“确定”,打开如图13(图13)选择“一个空工程”项,单击“完成”,打开如图14所示(图14)单击“确定”,打开如图15所示(图15)在左侧的“工作区窗口”显示了新建立的工程选择“工程”→“添加到工程”→“文件”,打开如图16所示选择刚刚创建的两个文件,单击“确定”,打开如图17所示选择“组建”→“组建”(或按F7键),打开如图18所示(图18)在下端的输出窗口会有错误和警告的提示,如果没有错误选择“组建”→“执行”(或按Ctrl+F5)即可出现运行结果,如图19所示(图19)4.如何快速地规范代码缩进格式选中所需要规范的代码,按Alt+F8。
VC++6.0调试方法大全
一、调试基础调试快捷键F5:开始调试Shift+F5: 停止调试F10:调试到下一句,这里是单步跟踪F11:调试到下一句,跟进函数内部Shift+F11: 从当前函数中跳出Ctrl+F10: 调试到光标所在位置F9:设置(取消)断点Alt+F9: 高级断点设置跟踪调试1、尽量使用快捷键时行调试2、观察调试信息3、高级中断设置异常调试重试->取消->调试函数堆栈,用variables或者call stack 窗口Release调试1、经常测试你的Debug和Release版本2、不要移除调试代码,如用ASSERT, TRACE等。
3、初始化变量,特别是全局变量,malloc的内存,new的内存4、当你移除某个资源时,确保你移除了所有跟这个资源相关的申明(主要是在resouce.h文中)5、使用3或者4级的警告级编译你的代码,并确保没有警告,project->setting->c/c++->warninglevel(中文版是项目->属性->C/C++->常规->警告等级)6、_debug改成NDEBUG进行调试,project->setting->C/C++->Preprocessordefinitions(中文版是项目->属性->C/C++->预处理器->预处理定义)(这里是debug和Release编译的重要不同之一)7、在Release中调试源代码,project->setting->C/C++->debug info选择programDataBase (中文版是项目->属性->C/C++->常规->调试信息格式->用于“编辑并继续”的程序数据库),project ->setting->link选上Generate debug info(中文版是项目->属性->链接器->调试->生成调试信息)8、走读代码,特别关注堆栈和指针二、TRACE宏当选择了Debug目标,并且afxTraceEnabled变量被置为TRUE时,TRACE宏也就随之被激活了。
vc6.0调试技巧
/Zi
Program Database
创建一个程序库(PDB),包括类型信息和符号调试信息。
/ZI
Program Database for Edit and Continue
除了前面/Zi的功能外,这个选项允许对代码进行调试过程中的修改和继续执行。这个选项同时使#pragma设置的优化功能无效
Life is like a box of chocolate, you never know what you are going to get.
二、调试的一些技巧
1、使用ASSERT和VERIFY(原则:尽量简单)
ASSERT:它接收一个表达式,如果这个表达式为TRUE,则无动作,否则中断当前程序执行。对于系统中出现这个宏导致的中断,应该认为你的函数调用未能满足系统的调用此函数的前提条件。例如,对于一个还没有创建的窗口调用SetWindowText等。
vc6.0调试技巧
一、基本的调试设置
1、CTRL+F10:运行到当前光标处 DEBUG模式下 用F9在要看的语句上打好断点,F5调试运行,F10单步运行。
2、设置
为了调试一个程序,首先必须使程序中包含调试信息。一般情况下,一个从AppWizard创建的工程中包含的Debug Configuration自动包含调试信息,但是是不是Debug版本并不是程序包含调试信息的决定因素,程序设计者可以在任意的Configuration中增加调试信息,包括Release版本。
LocalFree( lpMsgBuf );
LPVOID lpMsgBuf;
但是也要注意:由于用GetLastError插得代码七零八碎。在Watch窗里使用变量@err时就可以立即看到当前的LastError码。
vc++6.0使用技巧(别人总结 有待验证)
摘自别人的总结(有待验证)调试程序可以帮助的了解程序是怎样运行的。
1、如何快速地规范代码缩进格式选中所需要规范的代码,按shift+F8(错,应该是【Alt+F8】)2、如何在Release状态下进行调试Project->Setting…->Project Settings对话框,选择Release状态。
“C/C++”标签页中的Category选General,Optimizations选Disable(Debug),Debug info选Program Database。
在“Link”标签页中选中Generate debug info复选框。
注:只是一个介乎Debug和Release的中间状态,所有的ASSERT、VERIFY都不起作用,函数调用方式已经是真正的调用,而不查表,但是这种状态下QuickWatch、调用队列跟踪功能仍然有效,和Debug版一样。
3、Release和Debug有什么不同。
Release版称为发行版,Debug版称为调试版。
Debug中可以单步执行、跟踪等功能,但生成的可执行文件比较大,代码运行速度较慢。
Release版运行速度较快,可执行文件较小,但在其编译条件小无法执行调试功能。
Release的exe文件链接的是标准的MFC DLL(Use MFC in a shared or static dll),比如MFC42.DLL。
这些DLL在安装Windows的时候,已经配置,所以这些程序能够在没有安装Visual C++ 6.0的机器上运行。
而Debug版本的exe链接了调试版本的MFC DLL文件,如MFC42D.DLL。
在没有安装Visual C++6.0的机器上不能运行,因为缺MFC42D.DLL等,除非选择use static dll when link。
4、ASSERT和VERIFY有什么区别ASSERT里面的内容在Release版本中不编译,VERIFY里面的内容仍然编译,但不再判断真假。
VC6.0 IDE的使用和程序调试技巧
项目工作区窗口
ClassView页
FileView页 ResourceView页
FileView页
ClassView页
File->New->Proj32 Application
基于WINDOWS平台的32位开发环境开发应用程序,SDK程序。 入口函数为WinMain
文件类型 Active Server Page Bitmap File C/C++ Header File HTML Page Resource Script Resource Template
Visual C++6.0 可以创建的文件类型 说明 文件类型 网页制作 Binary File 创建位图文件 C++ Source File 创建 C/C++头文件 Cursor File 创建 HTML 文件 Icon File 创建资源脚本文件 Text File 创建资源模板文件 SQL Script File
6:使用单步执行到程序结束
设置断点以后,调试运行程序时,程序 开始执行,并且运行到断点处暂停下来, 此时我们有机会观察程序的运行情况, 并且诊断程序目前的状态是否如我们所 预期的那样。 不过我们先不着急观察程序的状态,而 是来看看如何控制程序的运行,以便在 我们需要的时候让程序暂停下来,并且 以我们需要的方式走走停停!
方法是使用单步执行手段stepover让程序向前走一步停止调试停止调试并重新启动调试单步执行当前位置对比调试运行时出现的调试菜单debug和调试工具栏根据图标查找对应项设置断点调试运行程序此时程序暂停在断点处等待选择debug菜单找到最后一项quickwatch并点击输入想要观察的变量变量名变量的值点击addwatch点击addwatch看到如下画点击单步执行按钮或者菜单程序则向前单独运行一个步骤每向前执行一步就会暂停下来这样我们就有充足的时间观察所关心的变量名称按下f5键可以让程序从当前位置向前执行直到遇见下一个断点或者程序结束下面是赠送的ppt模板不需要朋友可以下载后编辑删除
使用VC6.0对C语言程序进行调试的基本手段
使用VC6.0对C语言程序进行调试的基本手段(1)设置固定断点或临时断点所谓断点,是指定程序中的某一行,让程序运行至该行后暂停运行,使得程序员可以观察分析程序的运行过程中的情况。
这些情况一般包括:①在变量窗口(Varibles)中观察程序中变量的当前值。
程序员观察这些值的目的是与预期值对比,若与预期值不一致,则此断点前运行的程序肯定在某个地方有问题,以此可缩小故障范围。
例如以下程序是计算cos(x)并显示,运行时发现无论x输入为多少,结果都是0.046414。
#include <stdio.h>#include <math.h>void main(){int x;printf("Please input x:");scanf("% d", &x);printf("cos(x)=%f\n", cos(x));}在该程序中,若你没有看到问题——程序较长、较复杂时很难看出问题所在,则应该使用调试手段定位故障位置。
②在监控窗口(Watch)中观察指定变量或表达式的值。
当变量较多时,使用Varibles 窗口可能不太方便,使用Watch窗口则可以有目的、有计划地观察关键变量的变化。
③在输出窗口中观察程序当前的输出与预期是否一致。
同样地,若不一致,则此断点前运行的程序肯定在某个地方有问题。
④在内存窗口(Memory)中观察内存中数据的变化。
在该窗口中能直接查询和修改任意地址的数据。
对初学者来说,通过它能更深刻地理解各种变量、数组和结构等是如何占用内存的,以及数组越界的过程。
⑤在调用堆栈窗口(Call Stack)中观察函数调用的嵌套情况。
此窗口在函数调用关系比较复杂或递归调用的情况下,对分析故障很有帮助。
(2)单步执行程序让程序被一步一步(行)地执行,观察分析执行过程是否符合预要求。
例如,以下程序预期的功能是从键盘上读入两个数(x和y),判断x和y是否相等,相等则在屏幕上显示x=y,不相等则显示x<>y。
VC++6.0 Debug单步调试简单入门
本篇文章为大家简单介绍如何使用VC++6.0的Debug来设置断点,进行单步调试。
熟练使用Debug单步调试后,你找出并改正bug的速度和效率将大大提高,所谓磨刀不误砍柴工呀!相信大家对谭浩强童鞋都不陌生,想当年,是他引领我们步入了C的殿堂,我们从他那里学会了如何写代码,他却没有教我们如何Debug,而我们伟大的老师,也对此只字不提。
相信很少有人可以一次性写出完全正确的代码。
对于我们这些个菜鸟来说,写出不带bug的代码倒是一件很不正常的事情。
也许你知道有 Debug这么个东西,但却不知道该怎样用;也许你还停留在在代码中添加N个printf来输出查看到底是哪里出了问题;也许……总之,经验表明,你花费时间看完这篇文章并学会简单的使用Debug,绝对不是浪费时间!废话少说,进入正题:编译0 error(s), 0 warning(s)链接0 error(s), 0 warning(s)当你按捺不住激动滴心情点击运行后,发现结果并不是你想要的结果……郁闷了。
然后你在代码中加了n条printf来查看变量的结果……n多循环……运行,再加printf,again and again……终于,要抓狂了……好吧,同学,如果你会用Debug,也许你不用这么纠结。
下面通过一简单例子说明如何使用Debug的一些“基本”(我也只是刚入门的小菜鸟,高级的修行要靠自己的了)功能:写了如图中的一个简单程序,编译链接都没有错误,运行结果却不理想(不正确)需要指出的是,主函数不要再用void main()了,这种只有在你学的环境才不会出错,到别的(linux编译器)地方编译是通过不了的。
main函数必须要有返回值,如写成int main()在函数结尾时加一个return 0;,这样,所有编译器都不会报错了。
最终结果确定是逻辑错误,如果不用单步调试,很难找出这种错误的。
这里先提到一个断点的概念,顾名思义,既是在你需要的地方让它断开,如果你在某一行代码处添加了断点,那么程序运行到断点处即会暂停,不再继续往下运行,直到接到你继续运行的命令。
Visual C++ 6.0调试功能 图解教程(2)--实例
Visual C++ 6.0调试功能图解教程(2)--实例一使用说明程序名为 NO3.exe.运行环境为DOS,执行后显示:在"请输入你的选择后(1.2.3.4.5.6)"后输入数字选择执行的功能.测试结果:1.选择1.后输入:1234567892.选择2后输入分别输入1,3.重复1)操作后选择2,分别输入10,10.3.4.重复1)操作后选择3.分别输入1,abcde再重复1)操作后选择3.分别输入9,abcde1.2.再重复1)操作后选择4,分别输入1,3再重复1)操作后选择4,分别输入0,3再重复1)操作后选择4,分别输入10,35) 再重复1)操作后选择5,分别输入1,abcde再重复1)操作后选择5,分别输入9,abcde再重复1)操作后选择5,分别输入0,abcde再重复1)操作后选择5,分别输入10,abcde6)运行No3.exe后选择6或输入非"1,2,3,4,5"的数字调试过程:1.本调试主要针对置换操作功能进行演示:1.将光标移置String:: Replace(String t1,int pos)函数的第一条语句处Ctrl+F10开始调试2.在DOS窗口中选择1后输入"123456789".接着选择5分别输入1,abcde.这时Debugger停留在String:: Replace(String t1,int pos)的第一条语句处:3.在Watch窗口的名称栏分别输入:str,t1.str,q,out,pos,(-pos) +1,pos – size,j,i.进行观察.4.按F10开始单步调试.1.按F10三次后Debugger停留在最后一个判断语句处.同时Watch窗口中个名称的值分别为:2.接着单步调试,for()函数完后,Debugger停留在"delete t1.str;"语句处.这时Watch窗口中个各名称的值分别为:接着两次F10,这时t1.str和out的值已经改变,Debugger停留在String:: Replace(String t1,intpos)的结束处.3.再按一次F10,Debugger停留在main()函数的switch(k)里的case 5的if()语句处:F10到调用Display()函数的语句处后F11跟进Display()的内部.在Watch窗口的名称中输入str,I,len进行观察.单步调试到Display()函数结束,Debugger停留在Display()函结束处.在Watch窗口中str,I,len的值分别为:同时DOS窗口中显示如下:5.按Shift+F5退出调试.完成调试操作.参考源码:2.1Code:2//3.h3#include <iostream.h>4#include <string.h>5#include <stdlib.h>6//using namespace std;7int out; // 定义一个全局变量8class String9{10public:11 String(){}12 ~String(){}13 String SubString(int pos,int num); //取子串函数14void Insert(String t,int pos); //插入子串函数 15void Delete(int pos,int num); //删除子串函数 16void Creat(); //生成字符串函数 17void Display(); //打印子串函数18 Replace(String t1,int pos); //置换子串函数19private:20char *str;21int size;22 };2324//3.cpp25#include "3.h"26//生成新字符串函数27void String:: Creat()28 {29char s[100];30 cin>>s;31 size=strlen(s);32 str=new char[size + 1];33if(str==0)34 cout<<"没有申请到空间!"<<endl;35 strcpy( str, s);36//strcpy_s(str,sizeof(str)/sizeof(str[0]),s);3738 }39//输出40void String::Display()41{42int len = size;43int i;44for( i=0;i < size;i++ )45 cout<<str[i];46 cout<<endl;47 cout<<"字符串的总长度为:"<<len<<endl;48}49//求子串50//void String String::SubString(int pos,int num)51String String::SubString(int pos,int num)52{53 String temp;54int left=size-pos + 1;//从pos位置开始所有余下的字符串长度55char *p,*q;56if( pos > size )57 {58 cout<<"错误!"<<endl;59 cout<<"指定位置超过字符串长度为:"<< pos - size<<endl;//提示所取子串的错误位置60 exit (1);//异常退出61 }62else if( num > left )63 num = left;64 temp.str=new char[num+1];//重新分配内存空间65if(temp.str==0)66 cout<<"没有申请到空间!"<<endl;67 p=temp.str;68for(int i = pos-1;i < pos+num-1;i++)69 {70 q = &str[i];71 *p = *q;72 p++;73 }74 *p=0;75 temp.size = num;76return temp;77}7879//插入运算:在串对象s的pos位置后插入一个串t80void String::Insert(String t,int pos)81{82//String temp;83int i_len = t.size;84 cout<<"插入字符串的长度为:"<<i_len<<endl;8586char *q;87 q = new char( size + 1);88 strcpy(q,str);8990 delete str;91 str = new char( size + t.size + 1); //字符串长度要在原长上增加插入串的长度929394 strcpy(str,q);9596//依次后移,空出长度为插入字符串的长度的空间9798for(int j = size-1;j > pos-1;j--)99 {100int i = j + t.size;101 str[ i-- ] = str[ j ];102 }103104 j = pos;105for(int i = 0;i < t.size;)106 {107 str[j++] = t.str[i++];108 }109110 size+=t.size;111 str[size + 1]='\0';112113}114115116//删除 :删除串中的一个子串117void String:: Delete(int pos,int num)118{119//用if else if语句判断删除的位置是否越界120if(pos <= 0)121 {122 cout<<"无法完成删除操作!"<<endl<<"删除位置低于字符串长度为:"< < (-pos) +1<<endl;123 exit (1);124 }125else if( pos > size )126 {127 cout<<"无法完成删除操作!"<<endl<<"删除位置超过字符串长度为:"< < pos - size <<endl;128 exit (1);129 }130else if(pos >= 0 && pos <= size )131 {132int i = pos - 1;133for(int j = (pos + num -1); j <= size ; j++) //从删除到的位置开始前移134 {135 str[i] = str[j];136 i++;137 }138 }139 size = size-num; //只取删除后余下的字符个数140}141142//置换:置换串中的一个子串143 String:: Replace(String t1,int pos)144{145//用if else if语句判断置换的位置是否越界146if(pos <= 0)147 {148 cout<<"无法完成转换操作!"<<endl<<"置换位置低于字符串长度为:"<< (-pos) +1 <<endl;149 exit (1);150 }151else if(pos > size)152 {153 cout<<"无法完成置换操作!"<<endl<<"置换位置超过字符串长度为:"< < pos - size <<endl;154 exit (1);155 }156157//当置换的位置加上置换给的子串长度之和超过原字符串的长度时158 //在将不被置换的字符串长度的拷后追加新字符串的长度159else if( (t1.size+pos) >size )160 {161162char *q; //定义指针数组q用来转存原先将不被置换的字符串163 q = new char[ pos +1] ; //给q分配足够的空间为将不被置换的字符串的长度164for( int i = 0;i < pos-1;i++ )165 {166 q[i] = str[i];167168 }169170 q[pos-1] = '\0';171 delete []str; //释放原字符串空间172 strcat(q,t1.str); //通过strcat函数将输入的子串与原子串的拷贝173 cout<<"置换后的字符串为: "<<q<<endl;174return out = 0;175 }176177else if( (t1.size+pos) <= size )178 {179int j = pos - 1;180for(int i = 0;i < t1.size;i++)181 str[j++] = t1.str[i];182 delete t1.str;183return out = 1;184 }185186187}188//主函数189int main(int argc, char* argv[])190{191int pos,num,k;192 String s,s1,s2,t,t1;193do{194 cout<<"\n\n 1.生成字符串" ;195 cout<<"\n\n 2.取子串";196 cout<<"\n\n 3.插入子串s1";197 cout<<"\n\n 4.删除子串";198 cout<<"\n\n 5.置换子串";199 cout<<"\n\n 6.结束程序";200 cout<<"\n******************************** ";201 cout<<"\n 请输入你的选择(1,2,3,4,5,6)";202 cin>>k;203switch(k){204case 1:{205 cout<<"请输入一个字符串:";206 s.Creat();207 cout<<"字符串为: ";208 s.Display();209 }break;210case 2:{211 cout<<"请输入子串的截取位置pos及子串长度num"<<endl; 212 cin>>pos>>num;213 t = s.SubString(pos,num);214 cout<<"你所取的子串为:";215 t.Display();216 }break;217case 3:{218 cout<<"请输入子串插入位置pos"<<endl;219 cin>>pos;220 cout<<"请输入要插入的子串: ";221 s1.Creat();222 s.Insert(s1,pos);223 cout<<"插入后的字符串为: ";224 s.Display();225 }break;226case 4:{227 cout<<"请输入要删除子串的开始位置pos及子串长度num"<<end l;228 cin>>pos>>num;229 s.Delete(pos,num);230 cout<<"删除后的字符串为: ";231 s.Display();232 }break;233case 5:{234 cout<<"请输入子串置换位置pos"<<endl; 235 cin>>pos;236 cout<<"请输入要置换的子串: ";237 s2.Creat();238 s.Replace(s2,pos);239if( out != 0 )240 {241 cout<<"置换后的字符串为: "; 242 s.Display();243 }244 }break;245default:break;246 } //switch247 cout<<"\n--------------------------------- "; 248}while(k>=1&&k<6);249 cout<<"\n 再见!";250 cout<<"\n 按任意键,返回。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
概述
调试是一个程序员最基本的技能,其重要性甚至超过学习一门语言。
不会调试的程序员就意味着他即使会一门语言,却不能编制出任何好的软件。
这里我简要的根据自己的经验列出调试中比较常用的技巧,希望对大家有用。
本文约定,在选择菜单时,通过/表示分级菜单,例如File/Open表示顶级菜单File的子菜单Open。
设置
为了调试一个程序,首先必须使程序中包含调试信息。
一般情况下,一个从AppWizard创建的工程中包含的Debug Configuration自动包含调试信息,但是是不是Debug版本并不是程序包含调试信息的决定因素,程序设计者可以在任意的 Configuration中增加调试信息,包括Release版本。
为了增加调试信息,可以按照下述步骤进行:
打开Project settings对话框(可以通过快捷键ALT+F7打开,也可以通过IDE菜单Project/Settings打开)
选择C/C++页,Category中选择general ,则出现一个Debug Info下拉列表框,可供选择的调试信息方式包括:
None 没有调试信息
Line Numbers Only 目标文件或者可执行文件中只包含全局和导出符号以及代码行信息,不包含符号调试信息
C 7 Compatible 目标文件或者可执行文件中包含行号和所有符号调试信息,包括变量名及类型,函数及原型等
Program Database 创建一个程序库(PDB),包括类型信息和符号调试信息。
Program Database for Edit and Continue 除了前面/Zi的功能外,这个选项允许对代码进行调试过程中的修改和继续执行。
这个选项同时使#pragma设置的优化功能无效
选择Link页,选中复选框"Generate Debug Info",这个选项将使连接器把调试信息写进可执行文件和DLL 。
如果C/C++页中设置了Program Database以上的选项,则Link incrementally可以选择。
选中这个选项,将使程序可以在上一次编译的基础上被编译(即增量编译),而不必每次都从头开始编译。
断点
断点是调试器设置的一个代码位置。
当程序运行到断点时,程序中断执行,回到调试器。
断点是最常用的技巧。
调试时,只有设置了断点并使程序回到调试器,才能对程序进行在线调试。
设置断点:可以通过下述方法设置一个断点。
首先把光标移动到需要设置断点的代码行上,然后按F9快捷键弹出Breakpoints对话框,方法是按快捷键CTRL+B或ALT+F9,或者通过菜单Edit/Breakpoints打开。
打开后点击Break at编辑框的右侧的箭头,选择合适的位置信息。
一般情况下,直接选择line xxx就足够了,如果想设置不是当前位置的断点,可以选择
Advanced,然后填写函数、行号和可执行文件信息。
去掉断点:把光标移动到给定断点所在的行,再次按F9就可以取消断点。
同前面所述,打开Breakpoints对话框后,也可以按照界面提示去掉断点。
条件断点:可以为断点设置一个条件,这样的断点称为条件断点。
对于新加的断点,可以单击Conditions按钮,为断点设置一个表达式。
当这个表达式发生改变时,程序就被中断。
底下设置包括“观察数组或者结构的元素个数”,似乎可以设置一个指针所指向的内存区的大小,但是我设置一个比较的值但是改动范围之外的内存区似乎也导致断点起效。
最后一个设置可以让程序先执行多少次然后才到达断点。
数据断点:数据断点只能在Breakpoints对话框中设置。
选择“Data”页,就显示了设置数据断点的对话框。
在编辑框中输入一个表达式,当这个表达式的值发生变化时,数据断点就到达。
一般情况下,这个表达式应该由运算符和全局变量构成,例如:在编辑框中输入 g_bFlag 这个全局变量的名字,那么当程序中有g_bFlag= !g_bFlag时,程序就将停在这个语句处。
消息断点:VC也支持对Windows消息进行截获。
他有两种方式进行截获:窗口消息处理函数和特定消息中断。
在 Breakpoints对话框中选择Messages页,就可以设置消息断点。
如果在上面那个对话框中写入消息处理函数的名字,那么每次消息被这个函数处理,断点就到达(我觉得如果采用普通断点在这个函数中截获,效果应该一样)。
如果在底下的下拉列表框选择一个消息,则每次这种消息到达,程序就中断。
值
Watch
VC支持查看变量、表达式和内存的值。
所有这些观察都必须是在断点中断的情况下进行。
观看变量的值最简单,当断点到达时,把光标移动到这个变量上,停留一会就可以看到变量的值。
VC提供一种被成为Watch的机制来观看变量和表达式的值。
在断点状态下,在变量上单击右键,选择Quick Watch,就弹出一个对话框,显示这个变量的值。
单击Debug工具条上的Watch按钮,就出现一个Watch视图(Watch1,Watch2,Watch3,Watch4),在该视图中输入变量或者表达式,就可以观察变量或者表达式的值。
注意:这个表达式不能有副作用,例如++运算符绝对禁止用于这个表达式中,因为这个运算符将修改变量的值,导致软件的逻辑被破坏。
Memory
由于指针指向的数组,Watch只能显示第一个元素的值。
为了显示数组的后续内容,或者要显示一片内存的内容,可以使用memory功能。
在 Debug工具条上点memory按钮,就弹出一个对话框,在其中输入地址,就可以显示该地址指向的内存的内容。
Varibles
Debug工具条上的Varibles按钮弹出一个框,显示所有当前执行上下文中可见的变量的值。
特别是当前指令涉及的变量,以红色显示。
寄存器
Debug工具条上的Reigsters按钮弹出一个框,显示当前的所有寄存器的值。
进程控制
VC允许被中断的程序继续运行、单步运行和运行到指定光标处,分别对应快捷键F5、F10/F11和CTRL+F10。
各个快捷键功能如下:
快捷键说明
F5 继续运行
F10 单步,如果涉及到子函数,不进入子函数内部
F11 单步,如果涉及到子函数,进入子函数内部
CTRL+F10 运行到当前光标处。
Call Stack
调用堆栈反映了当前断点处函数是被那些函数按照什么顺序调用的。
单击Debug工具条上的Call stack就显示Call Stack对话框。
在CallStack对话框中显示了一个调用系列,最上面的是当前函数,往下依次是调用函数的上级函数。
单击这些函数名可以跳到对应的函数中去。
其他调试手段
系统提供一系列特殊的函数或者宏来处理Debug版本相关的信息,如下:
宏名/函数名说明
TRACE 使用方法和printf完全一致,他在output框中输出调试信息
ASSERT 它接收一个表达式,如果这个表达式为TRUE,则无动作,否则中断当前程序执行。
对于系统中出现这个宏导致的中断,应该认为你的函数调用未能满足系统的调用此函数的前提条件。
例如,对于一个还没有创建的窗口调用SetWindowText等。
VERIFY 和ASSERT功能类似,所不同的是,在Release版本中,ASSERT不计算输入的表达式的值,而VERIFY计算表达式的值。
关注
一个好的程序员不应该把所有的判断交给编译器和调试器,应该在程序中自己加以程序保护和错误定位,具体措施包括:
对于所有有返回值的函数,都应该检查返回值,除非你确信这个函数调用绝对不会出错,或者不关心它是否出错。
一些函数返回错误,需要用其他函数获得错误的具体信息。
例如accept返回INVALID_SOCKET 表示accept失败,为了查明具体的失败原因,应该立刻用WSAGetLastError获得错误码,并针对性的解决问题。
有些函数通过异常机制抛出错误,应该用TRY-CATCH语句来检查错误
程序员对于能处理的错误,应该自己在底层处理,对于不能处理的,应该报告给用户让他们决定怎么处理。
如果程序出了异常,却不对返回值和其他机制返回的错误信息进行判断,只能是加大了找错误的难度。
另外:VC中要编制程序不应该一开始就写cpp/h文件,而应该首先创建一个合适的工程。
因为只有这样,VC才能选择合适的编译、连接选项。
对于加入到工程中的cpp文件,应该检
查是否在第一行显式的包含stdafx.h头文件,这是Microsoft Visual Studio为了加快编译速度而设置的预编译头文件。
在这个#include "stdafx.h"行前面的所有代码将被忽略,所以其他头文件应该在这一行后面被包含。
对于.c文件,由于不能包含stdafx.h,因此可以通过Project settings把它的预编译头设置为“不使用”,方法是:
弹出Project settings对话框
选择C/C++
Category选择Precompilation Header
选择不使用预编译头。