学生信息登记(c语言小项目)

http://mooc1.chaoxing.com/nodedetailcontroller/visitnodedetail?courseId=80433103&knowledgeId=87871933

 

http://mooc1.chaoxing.com/nodedetailcontroller/visitnodedetail?courseId=80433103&knowledgeId=87871936

 

学生信息登记管理

1.需求分析

 

  1. 知识点分析

 

 

程序处理的对象是学生,由于每个学生有姓名、性别等若干属性,所以属于复杂的数据类型,可以使用结构体处理。

学生人数确定,并且程序运行中不要求改变,可以考虑用数组加以存储。

通过实验可达到如下目标:

(1)进一步掌握数组的声明和使用

(2)掌握结构体的声明,结构体变量的声明和赋值

(3)掌握结构体成员的访问

(4)掌握结构体数组的使用

(5)使用结构体处理复杂的数据结构

 3.算法思想

 

算法思想

(1)程序要求反复运行,直接满足特定条件(输入特定值)退出。可以通过无限循环同时设置监视哨的方式控制程序运行。

while(1)

{

    语句(特定条件时:exit(0))

}

 (2)学生对象包含学号、姓名、性别等属性,因此应该定义为一个结构体。同时,其属性“成绩”包含3个科目的成绩:C语言、英语、高数,故“成绩”属性为复合属性,应考虑将其定义为一个结构体。即学生结构体中嵌套另一个成绩结构体,结构如下:

  

(3)学生人数确定,并且不会发生变化,可以将人数定义为宏(或者常量):

#define 宏符号 常量值;

(4)使用数组存储学生对象学生信息结构体 [常量值];
 (5)程序包括输入学生信息、显示操作菜单、排序、显示信息等功能,这些功能相对独立,根据结构化、模块化的编程思想,应该将它们单独编写函数。除输入学生成绩只运行一次外,其他的都应放到循环体中反复操作,直到程序中止。分而治之

 

(6)程序与用户交互中有不少接收用户输入环节,如:选择操作菜单项、选择排序等,考虑到用户可能输入出错,并且可能多次出错,所以也应该设置为无限循环,当输入错误时,给予适当提示,并继续显示操作菜单,直到用户选择一个正确的交互为止。

(7)考虑到输入的学生没有排序字段(按输入的顺序),在排序后,可能无法恢复最初的顺序。如果希望能够保持或随时恢复原来的顺序,可以给学生结构体外加一个排序的属性,或者将排序操作的结果放到新的数组中,这种方式可以认为是“保护现场”。本示例采用第2种方式。

(8)存储字符串类型数据时使用字符数组,特别需要注意的是:为存储字符串分配空间时,应在长度基础上加上结束标志符的存储空间。

例如:学号的长度是12位,则其声明为:char id[13]。

  1. 排序操作。经典的排序算法包括快速排序、归并排序、插入排序、冒泡排序等,由于参与排序的数据量不大,所以在时间复杂度和空间复杂度上不作过多考虑,本示例采用冒泡算法进行排序。

程序流程设计(绘制流程图软件用diagram designer )

  主程序开始,功能模块之间传递信息有传参和全局变量两种形式,我们采用全局变量。首先定义宏,结构体,和全局变量。显示菜单和选项(用全局变量choice)

  1. 项目实现
  2. 打开vc++6.0新建Win32 Consolle Application 控制台应用程序。
  3. #include"stdio.h"
    #include"conio.h"//接收用户输入getche()函数
    #include"string.h"//字符串处理
    #include"stdlib.h"//exit函数头文件 
    //#define N 3  //3个学生 
    #define IDlen 12 //学好
    #define NameLen 10//姓名
    #define SexLen  4   //性别 
    //结构体 定义
    typedef struct Sco
    {
      int cp;//c语言
      int en;//英语
      int math;//数学 
    } Score;
    typedef struct Stu
    {
     char id[IDlen+1];//学号
     char name[NameLen+1];//姓名
     char sex[SexLen+1];
     int age;
     Score score;
     double avg;//平均成绩
    }Student;
    //函数声明 
    void line();//画线
    void IuputStudent();//输入学生信息
    void DisPlayMenu();//主菜单   
    void GetOrderDir();//排序菜单
    void SortStudent();//排序操作(冒泡)
    void OutputStudent(Student[]);//输出学生信息 
    //全局变量 
    Student stu[100];//原始输出学生信息
    Student sorted[100];//排序操作的学生信息
    char choice =0;//主菜单当中的选项
    char dir =1;//排序方向1升序0降序
    int i=0;
    int N; //登记的学生个数。
    //输入学生信息
    void IuputStudent()
    {
       printf("请输入登记信息的学生个数:\n");
       scanf("%d",&N); 
    for(i=0;i<N;i++)

       printf("\n请输入%d/%d个学生的信息:\n",i+1,N);
       line();
       printf("学号(%d个字符):\t",IDlen);
       scanf("%s",stu[i].id);
       stu[i].id[IDlen]='\0';//最后一位强制结束。
       printf("姓名(%d个字符):\t",NameLen);
       scanf("%s",stu[i].name);//字符串中不能有空格,如果有空格用gets(stud[i].name);
       printf("姓别不超出(%d个字符):\t",SexLen);
       scanf("%s",stu[i].sex);
       stu[i].sex[SexLen]='\0';//最后一位强制结束
       printf("年龄(整数):\t");
       scanf("%d",&stu[i].age);//注意整数输入要加上取地址符号。
       printf("c语言成绩(整数):\t");
       scanf("%d",&stu[i].score.cp);
       printf("英语成绩(整数):\t");
       scanf("%d",&stu[i].score.en);
       printf("高数成绩(整数):\t");
       scanf("%d",&stu[i].score.math);
       //平均分 
       stu[i].avg=(stu[i].score.cp+stu[i].score.en+stu[i].score.math)/3.0;///3.0不是三目的是得到小数,精确度高。
       line();
    }
    //复制结构体
    for(i=0;i<N;i++)
    {
        sorted[i]=stu[i];//保留现场。
    }
    }
    //主菜单
    void DisPlayMenu()
    {
    printf("\n主菜单\n");
    printf("请选择你的操作(排序字段或显示原始信息,或退出)\n");
    line();
    printf("(1)学号\t(2)姓名\t(3)性别\t(4)年龄\t");
    printf("(5)c语言\t(6)英语\t(7)高数\t(8)平均分\t");
    printf("(9)显示原始输入信息\t\t(0)退出程序\n");
    line();
    choice=getche();//getche 返回的是ascii值,不能用getchar();
    if(choice-'0'<0||choice-'0'>9)
    { printf("\n输入选项错误,请重新输入!\n");
    }
    else 
      return ;

    //排序菜单
    void GetOrderDir()
    {
    printf("\n排序菜单\n");
    printf("\n请选择你的排序方向(或返回)\n)");
    line();
    printf("(1)升序\t(2)降序\t(0)返回主菜单\n");
    line();
    dir =getche();//getche 返回的是ascii值,不能用getchar();
    if(dir-'0'<0||dir-'0'>2)
    {
         printf("\n输入选项错误,请重新输入!\n");
    }
    else 
      return ;
    }
    //排序操作(冒泡)
    void SortStudent()
    { int j=0,f=0;
       Student s;
       //从索引0到N-1升序
      for(j=0;j<N-1;j++)
      {
      for(i=0;i<N-1;i++)
      { 
            f=0;//默认不交换,f=1表示要交换。
        switch(choice)
        {case '1':if (strcmp(sorted[i].id,sorted[i+1].id)>0)
                     f=1;
                  break;//比较学号
         case '2':if (strcmp(sorted[i].id,sorted[i+1].id)>0)
                     f=1;
                  break;//比较姓名
         case '3':if (strcmp(sorted[i].sex,sorted[i+1].sex)>0)
                     f=1;
                  break;//比较姓名
         case '4':if (sorted[i].age>sorted[i+1].age)
                     f=1;
                  break;//比较年龄
         case '5':if (sorted[i].score.cp>sorted[i+1].score.cp)
                     f=1;
                  break;//比较c语言
         case '6':if (sorted[i].score.en>sorted[i+1].score.en)
                     f=1;
                  break;//比较英语
         case '7':if (sorted[i].score.math>sorted[i+1].score.math)
                     f=1;
                  break;//比较高数
         case '8':if (sorted[i].avg>sorted[i+1].avg)
                     f=1;
                  break;//比较高数
         default:
              printf("未知错误");
        }
       if(f==1)//要交换 
       {
          s=sorted[i];
          sorted[i] =sorted[i+1];
          sorted[i+1]=s;
       }
    }


      }
    }
    //输出学生信息 
    void OutputStudent(Student s[])
    {
    printf("\n按排序字段排序后的学生信息如下\n");
    line();
    printf("%-15s\t%-14s\t%-7s\t%-7s\t%-7s\t%-7s\t%-7s\t%-7s\n","学号","姓名","性别","年龄","c语言","英语","高数","平均分");//%-15s%
    //15个字符对齐方式。
    if(dir=='1')//升序
    {
    for(i=0;i<N;i++)
    {
     printf("%-15s\t%-14s\t%-7s\t%-7d\t",s[i].id,s[i].name,s[i].sex,s[i].age);
     printf("%-7d%-7d%-7d%.1f",s[i].score.cp,s[i].score.en,s[i].score.math,s[i].avg);
     printf("\n");
    }
    }
    else //降序
    {
    for(i=N-1;i>=0;i--)//降序,0的时候也得输出等号不能丢。
    {
     printf("%-15s\t%-14s\t%-7s\t%-7d\t",s[i].id,s[i].name,s[i].sex,s[i].age);
     printf("%-7d%-7d%-7d%.1f\n",s[i].score.cp,s[i].score.en,s[i].score.math,s[i].avg);
     printf("\n");
    }
    }
    line();
    }
    //画线
    void line()
    {
    printf("----------------------------------------------------------------------\n");
    }
    int  main()
    {
       IuputStudent();
     while(1)
     {
        DisPlayMenu();//显示菜单 
      if(choice=='0') 
       {
           printf("\n谢谢使用,再见\n");
           exit(0); 
      }
       else if(choice=='9')
       {       dir=1;
           OutputStudent(stu);//传结构体数组名
       }
       else 
       {
            GetOrderDir();//排序菜单
        if (dir=='0')
           {
                continue;//返回上一级菜单,进行下一次循环;
        }
            SortStudent();
            OutputStudent(sorted);
       }
     }
      return 0;
    }
     

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值