编程实习报告

《编程实习》实习报告

学    号:__________________

班    级:__________________

学生姓名:__________________

起始日期:__________________

完成日期:__________________

一、任务要求

用字符串指针实现学生成绩管理系统

完成函数

void DeleteStudent(char*** students,int*** marks);

void SortClass(char** students,int** marks);

void ShowClass(char** students,int** marks);

void EditMarks(char** students,int** marks);

二、详细设计

void InsertStudent(char*** students,int*** marks);

插入学生姓名

基本想法:

先读取学生姓名,判断指针是否为空,为空则建立内存。不为空则再开拓新的内存空间,将读取的学生与名单进行一一对照。若有相同的,则显示已存在该学生,若没有相同的,则开拓内存给新到的学生,并对名单进行排序,最后释放内存。

编程实习报告

void DeleteStudent(char*** students,int*** marks);

删除学生信息

基本想法:   

先读取要删除的学生姓名,将读入的学生姓名与已存在的学生进行比较,如相同,记住该学生所在位置,判断该学生下一个是否为空,若为空,就可以直接把该学生内存释放掉。若不是,则用一个while  将后面的所有学生向前移一位 直到NULL,再释放最后的内存,最后再释放学生姓名的那个内存

编程实习报告

void SortClass(char** students,int** marks);

排序   < 根据学生姓名>   

基本想法:   

采用冒泡法来进行排序。N次排序 先进行n-1次比大小,找到最小的,与第一个交换,再进行n-2次。。。

编程实习报告

void ShowClass(char** students,int** marks);

显示所有学生信息

基本想法:直接用printf输出。

编程实习报告

void EditMarks(char** students,int** marks);        

编辑学生成绩

基本想法:

先读取要编辑的学生姓名,然后与所有的学生姓名进行比较,判断是否在名单内,若不在,就输出不在,否则  就再读取该学生的5个成绩到 marks

编程实习报告

三、编码实现

void DeleteStudent(char*** students,int*** marks)

{

 int found, i,j;

 char** students1;

  int** marks1;

 students1 = *students;

 marks1 = *marks;

 char *name;

 printf("enter names of students to be deleted separated by commas\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 %s not in the Class List\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);     //释放姓名内存

}    

void ShowClass(char** students,int** marks)

{

 int  i, 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;

void ShowClass(char** students,int** marks)

 int i;

 fflush(stdout);

 if(students==NULL)           //指针为空 则返回

 { 

  printf("Class is Empty!\n");  return;

 } printf("Class List:\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]);   

  else 

  printf("%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;

void EditMarks(char** students,int** marks)     //编辑学生成绩

{

 int found, i,score; 

 char** students1;

 int** marks1;

 students1 = students;

 marks1 = marks;

 char *name;

 printf("Enter student name whose  marks are to be edited:\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 %s not in the Class list\n",name);

 while (found)                 //读取输入的五个成绩

 {

  printf("to leave the 1st mark   unchanged,press <enter> \n");  

  printf("otherwise type new mark and press <enter>\n");  

  scanf("%d",&score);  

  while((score>=0 && score <=100) != 1)  

  {   

   printf("incorrect mark entered,re-do:\n");    

   scanf("%d",&score); 

  } 

  marks[i][0]=score;  

  printf("to leave the 2nd mark   unchanged,press <enter> \n"); 

  printf("otherwise type new mark and press <enter>\n");

  scanf("%d",&score);  

  while((score>=0 && score <=100) !=1)  

  {   

   printf("incorrect mark entered,re-do:\n");   

   scanf("%d",&score);  

  } 

  marks[i][1]=score;   

  printf("to leave the 3rd mark   unchanged,press <enter> \n"); 

  printf("otherwise type new mark and press <enter>\n");

  scanf("%d",&score);  

  while((score>=0 && score <=100) !=1) 

  {

   printf("incorrect mark entered,re-do:\n"); 

   scanf("%d",&score);  

  } 

  marks[i][2]=score;  

  printf("to leave the 4th mark   unchanged,press <enter> \n"); 

  printf("otherwise type new mark and press <enter>\n"); 

  scanf("%d",&score);  

  while((score>=0 && score <=100) !=1) 

  {  

   printf("incorrect mark entered,re-do:\n");  

   scanf("%d",&score);  

  } 

  marks[i][3]=score;   

  printf("to leave the 5th mark   unchanged,press <enter> \n"); 

  printf("otherwise type new mark and press <enter>\n"); 

  scanf("%d%c",&score);                          //吃掉回车键       

  while((score>=0 && score <=100) !=1)  

  {

   printf("incorrect mark entered,re-do:\n");  

   scanf("%d%c",&score); 

  }

  marks[i][4]=score; 

  return;

 }

}

四、程序调试

1.在调试的时候,刚运行的时候在什么都没有输入的时候,马上按2,发现程序就出现错误,我就在delete里面先加入一个判断 指针是否为空  为空就返回 来避免错误

2.在editmarks这个函数中 我采用scanf这个函数来读取成绩,在读取第五个成绩的时候发现读完后会在函数主菜单里出现一次的错误,询问同学,发现应该在第五个输入成绩的时候在%s后面再加一个%c  来吃掉一个回车键   这样主菜单就不会出现菜单错误的情况  

五、总结

 编程实习中 ,首先要看懂老师所给的部分程序,先了解老师给整个程序的基本方法,比如这个函数是用多级指针来完成这个程序 ,而不是用结构体来做链表来实现的,只有这个先弄懂这些才能做到心中有数。  在编程的过程中,要有系统的想法,知道整个框架是怎么构成的。 另外在编程基本完成后 要进行全面的调试,针对各个情况都进行尝试,尽可能避免出现错误

 本次编程学习到了很多知识,特别感受到了链表在C语言中比数组来的更加方便,虽然完成了本次实习目的,但是设计出的软件还有很大缺陷,不是很完善,在几个地方不是很人性化,有待完善。本次实习收获很多,受益匪浅。

六、思考题

    为什么插入一个学生、删除一个学生的函数(insertstudents、deletestudents)的参数要要三重指针,而其他函数只用二重指针。

答:

两个的不同就是insert和delete函数需要操作那个指针本身,而show之类的函数只需要能得到指针指向的数据就行。

Students本身是两级指针,在函数中如不调用三级指针就不能对指针本身进行操作,这就好比在 主函数中有两个变量 I 和J  在其他子函数中要对I 和J 进行改变则必须调用I和J的地址  即指针   这样在主函数的I和J 才能被改变      而其他sort   show  都是只用对指针所指向进行改变,  所以只用二级指针就可以

相关推荐