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)选择各种可能的测试数据。