《编程实习》实习报告学号:.班级:.学生姓名:.起始日期:.完成日期:.一、任务要求用字符串指针实现学生成绩管理系统,具体完成的功能见可执行程序Student.exe。完成函数voidDeleteStudent(char***students,int***marks);voidSortClass(char**students,int**marks);voidShowClass(char**students,int**marks);voidEditMarks(char**students,int**marks);二、详细设计(分析各函数的功能,设计各函数的处理过程及其流程图)voidInsertStudent(char***students,int***marks);插入学生姓名基本想法:先读取学生姓名,判断指针是否为空,为空则建立内存。否则再开拓新的内存空间,然后将读取的学生与名单一一比较,若相同,则显示已存在该学生,若没有,则开拓内存给新到的学生,并对名单进行排序。voidDeleteStudent(char***students,int***marks);删除学生信息基本想法:先读取要删除的学生姓名,将读入的学生姓名与已存在的学生进行比较,如相同,记住该学生所在位置,判断该学生下一个是否为空,若为空,就可以直接把该学生内存释放掉。若不是,则用一个while将后面的所有学生向前移一位直到NULL,再释放最后的内存,最后再释放学生姓名的那个内存voidSortClass(char**students,int**marks);排序根据学生姓名基本想法:采用冒泡法来进行排序。N次排序先进行n-1次比大小,找到最小的,与第一个交换,再进行n-2次。。。。voidShowClass(char**students,int**marks);显示所有学生信息基本想法:直接用printf输出,voidEditMarks(char**students,int**marks);编辑学生成绩基本想法:先读取要编辑的学生姓名,然后与所有的学生姓名进行比较,判断是否在名单内,若不在,就输出不在,否则就再读取该学生的5个成绩到marks三、编码实现voidDeleteStudent(char***students,int***marks){intfound,i,j;char**students1;int**marks1;students1=*students;marks1=*marks;char*name;printf(enternamesofstudentstobedeletedseparatedbycommas\n);name=ReadLine();//读姓名if(students1==NULL)return;for(found=i=0;students1[i]!=NULL;i++)//判断是否已经存在该学生{if(strcmp(students1[i],name)==0)//判断函数相同为0{found=1;break;}}if(!found)//如果不同{printf(student%snotintheClassList\n,name);return;}if(students1[i+1]!=NULL)//判断下一个学生是否为空{j=i+1;while(students1[j]!=NULL)//不为空时,将学生信息向前移一位{students1[j-1]=students1[j];marks1[j-1]=marks1[j];j++;}students1[j-1]=NULL;marks1[j-1]=NULL;free((void*)students1[j-1]);//释放内存free((void*)marks1[j-1]);}else{students1[i]=NULL;marks1[i]=NULL;free((void*)students1[i]);free((void*)marks1[i]);}*students=students1;*marks=marks1;free((void*)name);//释放姓名内存}voidSortClass(char**students,int**marks){inti,j,k;char**students1,*stu1;int**marks1,*mar1;students1=students;marks1=marks;for(i=0;students1[i+1]!=NULL;i++)//最小冒泡排序法{k=i;for(j=i+1;students1[j]!=NULL;j++)if(strcmp(students1[j],students1[k])0)k=j;stu1=students1[k];students1[k]=students1[i];students1[i]=stu1;mar1=marks1[k];marks1[k]=marks1[i];marks1[i]=mar1;}students=students1;marks=marks1;}voidShowClass(char**students,int**marks){inti;fflush(stdout);if(students==NULL)//指针为空则返回{printf(ClassisEmpty!\n);return;}printf(ClassList:\n);printf(students:第一门第二门第三门第四门第五门总分\n);for(i=0;students[i]!=NULL;i++){if(marks[i][0]==-1&&marks[i][1]==-1&&marks[i][2]==-1&&marks[i][3]==-1&&marks[i][4]==-1)printf(%s:,,,,,\n,students[i]);elseprintf(%s:%d,%d,%d,%d,%d%d\n,students[i],marks[i][0],marks[i][1],marks[i][2],marks[i][3],marks[i][4],(marks[i][0]+marks[i][1]+marks[i][2]+marks[i][3]+marks[i][4]));}return;}voidEditMarks(char**students,int**marks)//编辑学生成绩{intfound,i,score;char**students1;int**marks1;students1=students;marks1=marks;char*name;printf(Enterstudentnamewhosemarksaretobeedited:\n);name=ReadLine();for(found=i=0;students1[i]!=NULL;i++){if(strcmp(students1[i],name)==0)//相同为0{found=1;printf(editing:%s\n,name);break;}}if(!found)printf(student%snotintheClasslist\n,name);while(found)//读取输入的五个成绩{printf(toleavethe1stmarkunchanged,pressenter\n);printf(otherwisetypenewmarkandpressenter\n);scanf(%d,&score);while((score=0&&score=100)!=1){printf(incorrectmarkentered,re-do:\n);scanf(%d,&score);}marks[i][0]=score;printf(toleavethe2ndmarkunchanged,pressenter\n);printf(otherwisetypenewmarkandpressenter\n);scanf(%d,&score);while((score=0&&score=100)!=1){printf(incorrectmarkentered,re-do:\n);scanf(%d,&score);}marks[i][1]=score;printf(toleavethe3rdmarkunchanged,pressenter\n);printf(otherwisetypenewmarkandpressenter\n);scanf(%d,&score);while((score=0&&score=100)!=1){printf(incorrectmarkentered,re-do:\n);scanf(%d,&score);}marks[i][2]=score;printf(toleavethe4thmarkunchanged,pressenter\n);printf(otherwisetypenewmarkandpressenter\n);scanf(%d,&score);while((score=0&&score=100)!=1){printf(incorrectmarkentered,re-do:\n);scanf(%d,&score);}marks[i][3]=score;printf(toleavethe5thmarkunchanged,pressenter\n);printf(otherwisetypenewmarkandpressenter\n);scanf(%d%c,&score);//吃掉回车键while((score=0&&score=100)!=1){printf(incorrectmarkentered,re-do:\n);scanf(%d%c,&score);}marks[i][4]=score;return;}}四、程序调试(说明调试过程、问题及其解决方法)1.在editmarks这个函数中我采用scanf这个函数来读取成绩,在读取第五个成绩的时候发现读完后会在函数主菜单里出现一次的错误这时我上网查了资料发现应该在第五个输入成绩的时候在%s后面再加一个%c来吃掉一个回车键这样主菜单就不会出现菜单错误的情况2.在调试的时候,刚运行的时候在什么都没有输入的时候,马上按2,,发现程序就出现错误,我就在delete里面先加入一个判断指针是否为空为空就返回来避免错误五、总结编程实习中,首先要看懂老师所给的部分程序,先了解老师给整个程序的基本方法,比如这个函数是用多级指针来完成这个程序,而不是用结构体来做链表来实现的,只有这个先弄懂这些才能做到心中有数。在编程的过程中,要有系统的想法,知道整个框架是怎么构成的。另外在编程基本完成后要进行全面的调试,针对各个情况都进行尝试,尽可能避免bug的错误六、思考题:为什么插入一个学生、扫除一个学生的函数(insertstudents、deletestudents)的参数要要三重指针,而其他函数只用二重指针?回答:两个的不同就是insert和delete函数需要操作那个指针本身,而show之类的函数只需要能得到指针指向的数据就行。Students本身是两级指针,在函数中如不调用三级指针就不能对指针本身进行操作,这就好比在主函数中有两个变量I和J在其他子函数中要对I和J进行改变则必须调用I和J的地址即指针这样在主函数的I和J才能被改变而其他sortshow都是只用对指针所指向进行改变,所以只用二级指针就可以。