1、计算机编程实验实验一学生成绩管理系统设计与测试信息与通信工程学院标准实验报告计算机编程实验一、实验室名称: 计算机实验中心二、实验项目名称:学生成绩管理系统设计与测试三、实验学时: 4四、实验原理:利用 C 语言集成开发环境设计学生成绩管理系统软件,并进行测试五、实验目的:1.练习结构、数组、指针、函数、文件等知识的综合运用;2.理解全局变量、局部变量、静态变量等内容。3.了解字符串函数的使用和预处理的作用。4.理解结构化程序设计方法,利用结构化程序设计方法,综合运用函数、数组、指针、结构等进行较复杂程序设计,能够实现一些简单的功能型程序。六、实验内容:1.设计表示学生信息的结构;2.确定函数
2、流程,清楚函数实现功能;3.熟悉文件的操作,编写函数从文件读取学生信息;4.编写统计函数,对读取的信息进行统计;5.编写输出函数,熟悉格式控制符的使用;6.设计测试文件,测试设计的结构和编写的函数;7.给出测试结果,程序评价。从文件中读取学生信息并打印。 完成以下编程实验, 调试运行程序并完成报告。设每个学生包含如下信息:属性名姓名学号C 成绩C 实验成绩C 总成绩类型字符串字符串整数整数整数(初始化为 0)1.设计一个表示学生信息的结构 struct studen;t2.编写函数从文件读入所有学生信息:a)函数定义 int ReadStudentInfo (const char* filen
3、ame, struct student*pStudents); 函数返回值:返回学生个数,失败返回 -1。输入参数 constchar* filename: 数据文件名; struct student* pStudents: 返回读取的学生信息,内存由 ReadStudentInfo函数分配, main 函数释放。b)建议函数流程:i.打开数据文件,失败返回 -1;ii.从头到尾扫描数据文件(即预读一遍)获得学生人数;iii.根据学生人数,利用 malloc 和 sizeof 等函数或运算符为 structstudent* pStudents分配内存;iv.利用 fseek函数,定位到文件头;
4、v.读取数据文件,并把每一条记录通过数组下标法或指针法保存到结构体数组 pStudents中;vi.关闭文件;vii.返回学生人数。c)数据文件格式说明:一行一条学生信息的记录,不同属性用空格隔开, 输入数据中无总成绩记录 。3.编写统计函数:a)函数定义 void Count(struct student pStudents, int num)。输入参数分别为保存学生的结构数组和学生人数。b)功能为:统计所有学生的总成绩和每个班(根据学号判断班级)的平均成绩;输入参数包括学生信息结构数组,学生人数,计算的每个学生的总成绩直接填充到对应的输入结构数组对应字段中。统计信息包括每个班的总人数、平均
5、成绩数组,用全局变量来表示。访问每个学生信息的时候,用指针来指向当前正在处理的学生。c)设计一个函数,实现根据学号计算班级,并在函数 Count中使用。4.编写信息输出函数:要求通过一定的格式控制符,使得输出美观。输出格式为:学生信息:序号 姓 名 学号班级 C 成绩 C 实验成绩 总成绩1 张三2 统计信息:序号 班级学生人数 平均成绩1 1 班 32 832 5.编写 main 函数实现:a) 定义变量,其中保存学生信息的数据文件直接在源代码中初始化; b) 读取学生信息,如果失败,打印失败信息并退出程序; c) 统计学生信息; d) 输出统计信息。 e) 释放内存。七、实验器材(设备、元
6、器件) :微型计算机一台,含操作系统,集成开发环境,文字处理软件等;八、实验步骤:九、实验数据及结果分析:代码结构及优化方案介绍:代码总体分为 ReadStudentInfo 、 Count、 printinformation 三部分,分别执行读取 txt 文件各部分到结构体、 按照学号判断班级、 打印输出功能, 最后集中再 main 函数中调用。优化方案:代码里有大量调用结构体的语句,但是一些函数直接访问地址,不确定会不会在之后改变地址, 所以用了一些缓冲区, 构建一些空的字符串, 将数据先读取到字符串里, 再进行使用, 减少对结构体地址造成的改变。 并且 Count部分的判断进行了调整,
7、没有再多余用一个函数嵌套判断, 而是直接判断, 调用了全局变量。代码如下:#include#include#include /定义结构体形式struct studentchar name50;char stuID50;int grade_C;int grade_EXP;int grade_All;/定义全局变量, per表示每班学生的个数, sum 表示班级总成绩int first_per = 0, first_ave, first_sum = 0;int second_per = 0, second_ave, second_sum = 0;int third_per = 0, third_a
8、ve, third_sum = 0;int forth_per = 0, forth_ave, forth_sum = 0;int fifth_per = 0, fifth_ave, fifth_sum = 0;int sixth_per = 0, sixth_ave, sixth_sum = 0;int ReadStudentInfo(const char* filename, struct student* pStudents)FILE* fp;/ 文件指针struct student* p;int stu_num = 0, i = 0;char temp, temp_line100 =
9、0 ;char temp_num20 = 0 ;/ 将读取数据缓存fopen_s(&fp, filename, r);fseek(fp, 0L, SEEK_SET);if (fp = NULL)printf(Fail to Readn);exit(-1);else while (temp = fgetc(fp) != EOF)if (temp = n)stu_num+;fseek(fp, 0L, SEEK_SET);*pStudents = (struct student*)malloc(stu_num * sizeof(*pStudents);p = *pStudents;fgets(tem
10、p_line, 100, fp);/ 读取了一行数据,光标直接跳到第一行没用的末尾了while (!feof(fp) & (i stuID, _countof(p-stuID);/ 使用 _countof 是用来计算字符数而不是字节数,赋值到每个 p 地址对应的部分fscanf_s(fp, %s, p-name, _countof(p-name);fscanf_s(fp, %s, temp_num, _countof(temp_num);p-grade_C = atoi(temp_num);fscanf_s(fp, %s, temp_num, _countof(temp_num);p-grad
11、e_EXP = atoi(temp_num);p-grade_All = 0.4 * p-grade_EXP + 0.6 * p-grade_C;p+;i+;fclose(fp);return stu_num;void Count(struct student pStudents, int num)int i;char compare20 = 0 ;for (i=0;igrade_All;first_ave = first_sum/first_per;if(!strncmp(compare,2017020902,10)second_per+;second_sum = second_sum +
12、(pStudents+i)-grade_All;second_ave = second_sum/first_per;if(!strncmp(compare,2017020903,10)third_per+;third_sum = third_sum + (pStudents+i)-grade_All;third_ave = third_sum/third_per;if(!strncmp(compare,2017020904,10)forth_per+;forth_sum = forth_sum + (pStudents+i)-grade_All;forth_ave = forth_sum/fo
13、rth_per;if(!strncmp(compare,2017020905,10)fifth_per+;fifth_sum = fifth_sum + (pStudents+i)-grade_All;fifth_ave = fifth_sum/fifth_per;if(!strncmp(compare,2017020906,10)sixth_per+;sixth_sum = sixth_sum + (pStudents+i)-grade_All;sixth_ave = sixth_sum/sixth_per;/打印函数void printinformation(struct student
14、pStudents, int num_stu)printf(n 学生信息 :nn);printf( n);printf( 序号 姓名 学号班级 C 成绩 C 实验成绩 总成绩 n);int i;for (i = 0; i num_stu; i+)pStudentsi.stuID,printf(%d %s %s %d %d %dn, i + 1, pStudentsi.name, pStudentsi.grade_C, pStudentsi.grade_EXP, pStudentsi.grade_All);printf(nn 统计信息 :nn);printf( n);printf( 序号班级学生
15、人数平均成绩 n);printf(11班%d%dn, first_per, first_ave);printf(22班%d%dn, second_per, second_ave);printf(33班%d%dn, third_per, third_ave);printf(44班%d%dn, forth_per, forth_ave);printf(55班%d%dn, fifth_per, fifth_ave);printf(66班%d%dn, sixth_per, sixth_ave);void main()int stu_num;const char location = data.txt;
16、struct student* pStudents = NULL;const char* filename = location;stu_num = ReadStudentInfo(filename, &pStudents);/ 返回跳过第一行后的行数,也就是学生的个数printf(%d, stu_num);Count(pStudents, stu_num);printinformation(pStudents, stu_num);free(pStudents);/释放内存getchar();/使终端停留return 0;十、实验结论:十二、对本实验过程及方法、手段的改进建议:报告评分:指导教师签字: