1.编程题目
【例13.13】有5个小学生,每个学生有数学和语文二门功课。从键盘上输入学生学号、姓名及成绩,计算出平均成绩后,输出每个人的平均成绩,然后将数据全部存入磁盘文件“stud”之中。
下面是为它设计的源程序清单。
#include <stdio.h> #define TOTAL 4 struct student { char num[6] ; char name[20] ; int score[2] ; int ave ; } stu[TOTAL] ; void main ( ) { FILE *fp ; int i ,j ,sum ; char *cnum={" 数学" ," 语文"} ; i=j=sum=0 ; for (i=0 ; i<=TOTAL ; i++ ) { printf ("\n 请输入学生%d 的成绩:\n" ,i+1 ); printf (" 学号:" ); scanf ("%s" ,stu[i].num ); printf (" 姓名:" ); scanf ("%s" ,stu[i].name ); sum=0 ; for (j=0 ;j<=1 ;j++ ); { printf ("%s 成绩:" , cnum[j] ); scanf ("%d" ,&stu[i].score[j] ); sum+=stu[i].score[j] ; } if (sum%2==0 ) sum=sum/2 ; sum= (sum+1 )/2 ; stu[i].ave=sum ; } printf (" 平均成绩\n" ); for (i=0 ;i<=TOTAL ;++i ) printf ("%s\t%d\n" ,stu[i].name ,stu[i].ave ); fp=fopen ("stud" , "w" ); for (i=0 ; i<=TOTAL ; i++ ) if (fwrite (&stu[i] ,sizeof (struct student ),1 ,fp )!=1 ) printf (" 文件写出错 \n" ); fclose (fp ); }
程序编译通过,运行后出现如下情况,请通过跟踪程序执行情况找出错误。
调试示例:
请输入学生1的成绩:
学号: 1001 姓名: LiMing (null )成绩:89
2.使用VC跟踪查错
从输出结果上分析,应输出“数学成绩:”时出错。如图13-11所示,在右边窗口设立观察数组cnum,然后在要求输入成绩的printf语句处设立断点,或者简单地将光标置于此处,按Ctrl+F10键,使程序运行并按要求输入学号和姓名。当程序运行到此处时,得到如图13-11所示的结果。显然,当前的j=2,不是预定的j=0。这是因为for语句右边多了“;”号,造成for语句空循环,cnum[2]超出定义范围。

图13-11 观察数组cnum示意图
注意:为了加快查错速度,将TOTAL重新定义为1。
下面是改错之后的运行示例(还有错误)。
请输入学生1 的成绩: 学号:1001 姓名:LiMing 数学成绩:99 语文成绩:89 请输入学生2 的成绩: 学号:1002 姓名:ZhangHong 数学成绩:88 语文成绩:87 平均成绩: LiMing 47 ZhangHong 88
运行结果是当sum为偶数时不对,跟踪监视sum,如图13-12所示。从图中可见,if语句少了配套的else语句。

图13-12 跟踪监视sum变量和stu结构成员示意图
注意:调试完毕,将TOTAL改回原值。
3.小结
(1)应根据错误结果决定查错范围。
(2)正确选择要观察的变量表达式。
(3)选择各种可能的测试数据。