首先打开软件找到你的没有错误的程序但是呢运行结果不对
使用F9设置断点,设置你认为有问题的函数的地方例如图片,其中红点即为断点
选择F10一步步运行程序
按F10单步执行,遇到要输入的数据就输入例如输入文件
然后选择F10继续执行,在右边可以查看各个数据的数值,例如查看字符数组
通过查看各个数值的值即可找到出错的原因
用release版本设置断点调试程序!如果是debug版本,需要在setting里设置相关是属性。你在网上搜搜如何设置调试即可!
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语言的一道上机改错题,请考生调试该程序,使其能按要求输出正确的结果。
① 程序功能说明
给定程序C003.C中函数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系统,编辑输出源程序,并以c003.c命名,结果如图14所示。
图14
b) 按功能键Ctrl+F11编译源程序,编译显示结果如图15所示。
图15
编译结果告诉我们,程序中存在一个错误,两个警告。其中:警告的原因都是因为系统函数没有包含头文件stdio.h,错误的原因是第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;”。