1设置断点,在你有疑问的地按设置一个断点,如果有几个地方要看看运行的情况,都设置断点2按F5调试运行,运行到设置断点的地方,你就可以看看变量的赋值情况3按F5继续调试
在vc环境中,对程序如main中的某处按f9下个断点,然后按f5运行起来,会断在你下断点的地方,按f10就是一条一条语句地执行,即步过;f11是在遇到函数调用时进入函数的实现处,即步入
在这个函数中按F9设断点,按F5进入调试,然后再F10或F11单步调试。
这里我对F10和F11作个分析吧
F10是单步调试命令,但不进入一个函数。
F11是调试时跟踪进入函数里的一个命令。当你要进入的这个函数是API函数时,因为有的API函数没有提供源代码,只提供了lib库,所以你要进入这个函数内部时,先会提醒你给出源代码的路径,你没有给出,所以就只能显示这个函数的汇编指令了(lib的反汇编)。
调试时F11只是给你需要进入自己写的函数时用到的命令,遇到API函数时就不要用F11了,用F10就可以了。
在MFC中的执行顺序是这样的,首先Windows调用WinMain函数,WinMain里面调用AfxWinMain函数,注意你的代码现在来了,AfxWinMain函数调用对应你程序的APP类(这个类是基于CWinApp的,CWinApp又是基于CWinThread的)的InitInstance函数,如果InitInstance返回TRUE,就调用CWinThread的Run函数,这个函数你可以重载,但是一般不重载。在Run函数里面是Windows的消息循环,就是Win API编程里面的那个while循环以及TranslateMessage和DipatchMessage,当然MFC弄得比较复杂,有一个PumpMessage的机制。当程序收到WM_QUIT消息之后,Run函数返回,紧接着CWinThread::ExitInstance会被调用,如果你重载了ExitInstrance则会调用你的。最后程序结束。如果InitInstance返回FALSE,那么Run函数就不会执行,直接调用ExitInstance,然后程序结束。
1.VC调试功能简介
当一个C源程序编辑完成之后,你可以用上节讲的方法进行编译、运行。如果程序无编译错误,但无运行结果,或运行结果有误时,你就需要调用VC的编译调试工具来调试你的程序,以便找出出错的原因,从而达到正确的运行结果。
VC为调试C程序提供了多种工具和多组方法,常用的方法有菜单法、工具栏法和功能键法。实际上,这三种方法是相似或相同的,只是根据用户的熟悉程度和习惯用法选择其中之一,来完成你的调试过程。作者习惯使用功能键法,因为使用功能键既方便 *** 作,又能节省调试程序的时间,使调试过程在较短的时间内完成。下面结合调试工具来介绍以上立法。
在VC窗口下的菜单栏和工具栏的空白处,点右键激活快捷菜单,选择“编译”菜单项,这时VC窗口就出现了调试工具栏,
调试工具栏中的工具可分为两部分:控制程序运行工具和设置观察窗口工具。
① 对于控制程序运行工具,从左到右的常用按钮、功能键及功能说明依次是:
●Restart 重新执行程序,功能键是 Ctrl+Shift+F5。无论C源程序处于任何状态(编辑、运行、调试),按下此按钮均可使程序从编译开始,逐步进入调试程序状态。
●Stop Debugging 停止程序调试,功能键是Shift+F5。当调试过程处于跟踪程序执行的状态时,按下此按钮,将停止调试程序,返回编辑状态。编辑状态下此按钮无效。
● Show Next Statement 指示当前程序运行的语句行。
● Step Into 单步运行并且可进入函数内部运行,功能键是F11。程序在调试过程中,按下此按钮可单步跟踪程序运行,与Stp Over按钮不同的是,该功能可进入函数内部,继续函数内部的语句行跟踪。
注意:使用此按钮时,当 位于有库函数调用的语句行,不用F11功能,以免进入库函数的汇编程序块中,取而代的是F10功能键。
● Step Over 单步运行程序,功能键是F10。本按钮的功能类似于F11,但它不进入函数内部,它将每一条语句看作一步,包括函数调用语句。
●Step Out 从当前函数中退出,功能键是Shift+F11。当程序运行至某个函数内部时,按下此按钮后,调试状态即从函数内部退出,返回到调用该函数的主函数的当前语句。
●Run to Cursor 运行到当前光标位置,功能键是Ctrl+F10。当程序处于调试状态时,为了跳过某程序段,可预先将光标定位在某语句行上,按下此按钮,即可使程序直接运行到当前光标位置,从而节省了时间,加快了调试程序的步骤。
② 对于设置观察窗口工具,其功能主要是为配合程序跟踪运行,设置一些观察点,以便定位出错的位置,从而找到出错的原因。
● QuickWatch 快速观察表达式的值,功能键是Shift+F9。当程序运行到某个关键语句行时,你可以按下该按钮,即在屏幕上显示“QuickWatch”窗口,其中:E表达式下拉列表框中的a,是由用户输入的当前源程序中的一个数组名;V 当前值列表中的“Name”和“Value”列的值就是a数组中所有元素的元素名和元素值。
●Watch 设置观察点。当用户按下该按钮,屏幕显示观察窗口,其中的“Name”列和“Value”列为空。这时,用户可以在Name列中输入用户待观察的观察点,即程序中某个变量的名字,然后回车,在Value列就显示出该变量的当前值。观察点可以设置多个,多个观察点还可以分别放在不同的观察标签内(Watch1、Watch2…)。
● Variables 变量列表,当按下此按钮,屏幕显示如所示的变量列表窗口。窗口中的“Name”列和“Value”列中列出了当前函数中的所有变量名和相应的值,其中:简单变量只显示变量名和它的值;数组名前面有一个“ ”符号,Value列显示它的地址值。
●Registers 寄存器列表,按下此按钮,屏幕上显示的寄存器窗口,窗口中列出了所有寄存器的内容。
●Memory 内存列表,按下此按钮,屏幕上显示所示的内存列表窗口,其中“A地址”文本框中显示的是内存的当前地址值,下面的列表框中显示的是从指定地址开始的所有内存区域的值,表示其值不确定(没有赋确定的值)。用户可以在程序运行时,在“Watch”窗口中找到某个变量的地址或数组名的值(数组名本身是一个地址量),然后,将该值输出“A地址”的文本框中,在内存列表区立即就能看到它的存储值,不过该值是一个十六进制的数,并且,一个整型数占据四个字节的存储区域。详细内容可参考下面的例子。
图13
2.使用VC调试C程序的方法
以下程序是全国计算机等级考试二级C语言的一道上机改错题,请考生调试该程序,使其能按要求输出正确的结果。
① 程序功能说明
给定程序C003C中函数fun的功能是:从s所指字符串中,找出t所指子串的个数作为函数值返回。
例如,当s所指字符串中的内容为:"abcdabfab",t所指字符串的内容为:"ab",则函数返回整数3。
请改正程序中的错误,使它能得出正确的结果。
注意: 不要改动main函数, 不得增行或删行, 也不得更改程序的结构!
② 源程序
#define N 80
int fun(char s, char t)
{
int n=0; char p , r;
while ( s )
{
p=s;
r=p;
while(r)
if(r==p)
{
r++;
p++;
}
else break;
if(r = O)
n++;
s++;
}
return n;
}
main()
{
char a[N],b[N]; int m;
printf("Enter string a : ");
gets(a);
printf("Enter substring b : ");
gets( b );
m=fun(a, b);
printf(" The result is : m=%d ",m);
}
③ 调试过程
a) 启动VC系统,编辑输出源程序,并以c003c命名,结果如图14所示。
图14
b) 按功能键Ctrl+F11编译源程序,编译显示结果如图15所示。
图15
编译结果告诉我们,程序中存在一个错误,两个警告。其中:警告的原因都是因为系统函数没有包含头文件stdioh,错误的原因是第16行的标识符(identifierf)’O’没有定义。需要说明的是,这里的错误很特别:从程序字面上看,这里的O好象是数字0,而一般考生也分辨不出或不会认为是O。但是,既然编译系统给出错误信息,就应该根据该错误信息来修改程序。在源程序前面增加一行文件包含命令“#include ”,再把字母O改写成字符0(这是缺乏编程经验的考生的共同作法),再一次编译程序,结果告诉我们程序编译成功。
然后,按Ctrl+F5功能键,运行程序,在提示输入的屏幕上输入题目要求的两个字符串,屏幕显示如图16所示,结果再一次告诉考生:程序结果有错,即程序中存在逻辑错误。
图16
c) 接下来,我们对程序作运一步调试,以找出程序出错的真正原因。
调试一个存在逻辑错误的程序,首先要确定程序中可能出现错误的大概位置。根据题意说明可确定错误存在于函数fun中。根据这一判断,我们先将光标定位在fun函数的第一条可执行的语句行上,然后,按下功能键Ctrl+F10,让程序运行到光标位置。注意:这个过程中间要进入输入屏幕状态,等待输入a和b字符串,请考生按要求输入,用回车符确认。当看到任务栏的VC图标在闪烁,请将窗口切换到VC状态,如图17所示:
图17
接下来,边按功能键F10,边观察屏幕下方变量(Variables)子窗口中p字符串和r字符串的变化,同时还要注意VC窗口左边的**指点针箭头。一直重复以上过程,你会发现,**箭头始终没有指向“n++;”语句。我们要找的第一个逻辑错误点就是if语句后面的表达式。按照正常的情况,if后面的表达式应该是关系表达式或逻辑表达式,而这里的表达式是赋值表达式,正确的语句应该是:
if(r == 0)
n++;
修改之后再按Ctrl+F5运行程序,程序结果如图18所示。
为了利用VC的调试功能和手段,更好地观察其它相关变量的变化规律,在上述过程中,还可以在VC的观察(Watch)窗口输入其它变量,在跟踪程序执行过程中观察其变化。
图18
这种结果也不对,这是第一次错误结果的另一个极端:从m=0变到m=10。
如何查找其中的原因?不仿再回顾一下刚才在跟踪程序运行时,变量(Variables)窗口中的p和r字符串的值的变化情况,再结合程序中r字符串的作用,不难看出,p和r应该是不同的字符串,且p字符串是指向s字符串,而r字符串则应该指向t字符串。正确的结果应该是:将语句“r=p;”改成“r=t;”。
一般多数情况下,这个是不需要设置的。
“可执行调试对话框” 对于DLL工程,需要指定调试中的调用方,EXE工程默认为自己
“工作目录” 可以空,默认为工程目录
“程序变量” 默认空,这个就是命令行参数,调试的时候可以带着进去,多数程序不需要。
“远程可执行路径和文件名” 默认空,非RPC程序不需要
f9在某行代码处下断点,程序运行到这里会中止
可以下多个断点
f5
:开始调试,程序会运行到第一个断点
f10:逐步执行,如果遇到我们自己写的函数的调用,如果函数里面有断点就跟进函数,如果没有断点,就越过,如果是库函数,则越过
f11:单步执行,即使函数里面没有断点,也会跟进去
run
to
cursor:在某行代码处,右击,选择run
to
cursor,则运行到该行代码处,这个好用!
shift
+f11:跟进去的时候,跳出来
同时有多个相关的窗口:memory查看内存
输出窗口
watch窗口查看变量值
寄存器窗口
栈窗口等
以上就是关于VC6.0怎样进行调试C程序(要详细的)全部的内容,包括:VC6.0怎样进行调试C程序(要详细的)、VC怎么进行逐步调试、VC++6.0中怎么使用单步调试等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)