精华内容
下载资源
问答
  • 定义结构体struct stu,编写成绩排名函数:void sort(struct stu *ps,int n),对结构体数组按成绩排名程序功能为读入整数N(N<100),再读入N个学生学号(整型)和成绩(实数)。按样例输出排名。 ...

    题目详情

    定义结构体struct stu,编写成绩排名函数:void sort(struct stu *ps,int n),对结构体数组按成绩排名。 程序功能为读入整数N(N<100),再读入N个学生的学号(整型)和成绩(实数)。按样例输出排名。

    输出格式

    第一列是名次,注意并列情况;

    第二列是学号,第三列是成绩(2位小数)

    输入样例

    5
    101 99
    102 100
    103 50
    104 80
    105 99

    输出样例 

    1 102 100.00
    2 101 99.00
    2 105 99.00
    4 104 80.00
    5 103 50.00
     

    题目分析 

    怎么来分析这个题目呢?

    我觉得这道题难得不是排序,难顶的是这该死的并列排名还有一些细节!细节!细节!

    先说说这个并列排名吧  我是真真的在这磕了好久 提交了好多次 就是不能够通过测试点1 就是不能完全对... 那种感觉真的是太难受了。(最后是一个好朋友救了我)

    直接说说我的思路吧。

    无非就是两种情况

    所以我们可以考虑使用  if (s[i].score == s[i-1].score)  具体代码可以看下面

    第一种就是该学生的成绩与前面一个的学生不相同 这个时候我们就可以直接用 i+1 来表示排名就可以了 最关键的一步就是我们要将这个名次用一个变量存储起来 (至于为什么呢 看了第2种情况就悟了)。

    第二种就是成绩并列的情况了 这个时候的名次就和前一个的是一样的了  这个时候我们就可以直接用上边的那个存储名次的变量了。

    大致就是这样了。

    代码展示

    静态构建结构体数组

    # include <stdio.h>
    
    struct stu
    {
    	int num;//学号 
    	float score;//成绩 
    };
    
    void sort(struct stu * ps, int n)
    {
    	int i, j;
    	struct stu t;/* 定义中间变量 */
    	/* 冒泡排序法 这里就不具体解释了*/
    	for (i=0; i<n; i++)
    	{
    		for (j=0; j<n-1-i; j++)
    		{
    			if (ps[j].score < ps[j+1].score)
    			{
    				t = ps[j];
    				ps[j] = ps[j+1];
    				ps[j+1] = t;
    			}
    		}
    	}
    	
    }
    
    int main(void)
    {
    	struct stu s[100]; 
    	int N, i;
    	int k = 0; /* 记录排名 (呜呜呜 定义这个变量真的太有必要了)*/   
    	
    	scanf("%d", &N); /* 输入N个学生个数 */
    	for (i=0; i<N; i++)/* 逐个输入学生的信息 */ 
    	{
    		scanf("%d%f", &s[i].num, &s[i].score);
    	}
    	sort(s, N);/* 将学生信息排列 */
    	for (i=0; i<N; i++)/* 遍历所有学生 逐个输出 */
    	{
    		/* 与前一个学生成绩进行比较 在这里是与前一个学生的信息进行对比 具体分析可以参考题目分析里的 */
    		if (s[i].score == s[i-1].score)
    		{     
    		   printf("%d %d %.2f", k, s[i].num, s[i].score); /* 注意题目要求成绩要保留两位小数 */
    		}
    		else 
    		{   /* 如果与前面的成绩不相等的话 就直接用i+1来表示排名再好不过了 */
    			printf("%d %d %.2f", i+1, s[i].num, s[i].score);
    			k = i+1;/* 把这个排名保存在K中 如果后面的成绩与这个成绩相同 排名就相同 直接就用K来表示了 */ 
    		}
    	    if (i < N-1) /* 呜呜呜 我们这里还要满足人类的要求 输出最后一名时不能加换行符  */
            {
                printf("\n");
            }   
        }   
    	return 0;
    }

     动态构建结构体数组

    思路都一样就不注释了

    # include <stdio.h>
    # include <stdlib.h>
    # define LEN sizeof(struct stu)
    
    struct stu
    {
    	int num;
    	float score;
    };
    
    void sort(struct stu * ps, int n)
    {
    	int i, j;
    	struct stu t;
    	
    	for (i=0; i<n; i++)
    	{
    		for (j=0; j<n-1-i; j++)
    		{
    			if (ps[j].score < ps[j+1].score)
    			{
    				t = ps[j];
    				ps[j] = ps[j+1];
    				ps[j+1] = t;
    			}
    		}
    	}
    	
    }
    
    int main(void)
    {
    	struct stu * s; 
    	int N, i;
    	
    	scanf("%d", &N);
    	s = (struct stu *)malloc(N*LEN);
    	for (i=0; i<N; i++)
    	{
    		scanf("%d%f", &s[i].num, &s[i].score);
    	}
    	sort(s, N);
    	int t; 
    	for (i=0; i<N; i++)
    	{
    		if (s[i].score == s[i-1].score)
    		{
    		   printf("%d %d %.2f", t, s[i].num, s[i].score);
    		}
    		else 
    		{
    			printf("%d %d %.2f", i+1, s[i].num, s[i].score);
    			t = i+1;
    		}
    		if (i < N-1)
            {
                printf("\n");
            }      
    	}
    	
    	return 0;
    }

    运行展示

     

     

     

     

     

    展开全文
  • 不改变数据位置排序算法及动态演示宁 宁1,张 霞2(1.潍坊教育学院信息工程系,山东 青州 262500;2.潍坊教育学院数学系,山东 青州 262500)摘要:实际应用中经常遇到要求不改变原始数据顺序而按关键字大小对...

    不改变数据位置的排序算法及动态演示

    宁 宁1,张 霞2

    (1.潍坊教育学院信息工程系,山东 青州 262500;

    2.潍坊教育学院数学系,山东 青州 262500)

    摘要:实际应用中经常遇到要求不改变原始数据的顺序而按关键字的大小对数据进行排序的情况,原有的一些经典排序算法不能直接用于解决该类问题。经过对选择排序算法进行研究,给出了基于选择思想的不改变数据位置而对数据进行排序的算法,并利用C#语言编程对该算法的实现过程进行了动态演示。

    关键词:排序 ; 关键字 ; 选择 ; 定时器

    Sorting Algorithm Without Changing the Data Position & Dynamic Demonstration

    1.FU Ning 2.ZHANG Dong-xia

    (1.The Information Engineering Department of Weifang College of Education,Qingzhou Shandong 262500)(2.The Information Engineering Department of Weifang College of Education,Qingzhou Shandong 262500)

    Abstract:In practical application, the situation, in which it requires a listing of the data in the order of the size of the keywords without changing the order of the original data, is an often-met case. The original classic sorting algorithm cannot be used directed to solve this kind of problem. This paper, by researching into the selective sorting algorithm, puts forward an algorithm on the basis of sorting the data without changing the positions of the data. It also gives a dynamic demonstration of the realization procedure of this algorithm by applying the C language programming.

    Keywords:sorting ; key word ; select ; timer

    1. 问题的提出

    排序是计算机程序设计中一项基本的操作,在实际应用中,有很多情况下需要对数据按照某种方式进行排序后才能达到某种要求,因此,学习和研究各种排序方法是计算机工作者的重要课题之一。

    我们已经熟知的、比较成熟的排序算法有很多,比如冒泡排序、选择排序、插入排序、快速排序等,利用这些排序算法都能够使一组数据序列按照某个关键字排成需要的顺序。但这些经典的排序算法在对数据序列排序时,都要改变数据的原始顺序,也就是说,在一般情况下,排序问题的输入是n个数a1,a2,a3,……,an的一个序列,按照某个关键字对初始序列进行重新排序后产生初始输入序列的一个重新排列:a11, a21, a31, ……,an1,使得a11< a21< a31

    待排序数据:( 596 560 480 616 560 580 498 500 540 610)

    对应的名次:( 3 5 10 1 o 5 4 9 8 7 2 )

    对于实际工作中类似的排序要求,原有的一些基础排序算法就不能够直接应用,在具体的编程应用中可以在一些经典排序方法的基础上适当做一些改进,来解决具体的问题。本文基于选择排序算法的基本思想,给出了对不改变数据位置而对数据进行排序的有效算法,并利用C#语言编程给出了该算法实现的动态演示。

    2. 算法实现

    假设要处理的数据存放在A数组中,为了我们算法实

    展开全文
  • 程序C语言开发。 2.学生成绩管理系统基本要求: 假设有5名学生的成绩放在1个数组中。系统要求从键盘上输入的方法生成学生的成绩几有关数据。系统能按照要求根据不同条件对学生成绩进行管理。 3. 系统模块及操作...
  • 某专业2019-2020-2学期开设10门课程,6门必修课,4门选修课(任选2门)。 专业有2个班级,每个班级30人。现要求统计必修课、选修课平均成绩,统计每名学生的成绩,奖...编写统计每名同学奖学金评定成绩排名的函数。
  • c语言学生成绩管理系统

    热门讨论 2013-03-14 22:27:45
    4. 对所开课程的成绩分析(求其平均成绩,最高分和最低分); 5. 对学生考试成绩进行排名(单科按系别或班级进行排名,对每一个班级,同一学期学生总体成绩进行排名,并显示各科成绩信息) 五、解决方案 1. 分析...
  • C语言--排名

    2014-11-05 18:08:26
    Description 今天的上机考试虽然有实时的...考生,并将他们的成绩按降序打印。   Input 测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 名考生的准考证号(长度不超过

    排名

    Description

    今天的上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑
    每题的分值,所以并不是最后的排名。给定录取分数线,请你写程序找出最后通过分数线的
    考生,并将他们的成绩按降序打印。
     

    Input

    测试输入包含若干场考试的信息。每场考试信息的第1行给出考生人数N ( 0 < N
    < 1000 )、考题数M ( 0 < M < = 10 )、分数线(正整数)G;第2行排序给出第1题至第M题的正整数分值;以下N行,每行给出一
    名考生的准考证号(长度不超过20的字符串)、该生解决的题目总数m、以及这m道题的题号
    (题目号由1到M)。
    当读入的考生人数为0时,输入结束,该场考试不予处理。
     

    Output

    对每场考试,首先在第1行输出不低于分数线的考生人数n,随后n行按分数从高
    到低输出上线考生的考号与分数,其间用1空格分隔。若有多名考生分数相同,则按他们考
    号的升序输出。
     

    Sample Input

    4 5 25 10 10 12 13 15 CS004 3 5 1 3 CS003 5 2 4 1 3 5 CS002 2 1 2 CS001 3 2 3 5 1 2 40 10 30 CS001 1 2 2 3 20 10 10 10 CS000000000000000001 0 CS000000000000000002 2 1 2 0
     

    Sample Output

    3 CS003 60 CS001 37 CS004 37 0 1 CS000000000000000002 20

    Hint

     Huge input, scanf is recommend




    题目分析:这道题涉及到一个成员多个单元格,需要的是定义一个结构体变量,然后进行处理。
    重点及注意事项:1.结构体变量中的数据大小比较,如何做到选择,排序;
                                       2.人数较多,数据较多,最好使用快排,否者易超时;

    AC代码(个人解法,仅供参考)
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    struct score
    {
    	char num[100];
    	int sum;
    }
    d[1020];
    int cmp(score a,score b)
    {
    	if(a.sum==b.sum) 
    		return strcmp(a.num,b.num)<0;
    	else 
    		return a.sum>b.sum;//按题目要求对各变量进行排序
    }
    int main()
    {
    	int n,m,g,a[11],i,k,j,b,f;
    	while(scanf("%d",&n)!=EOF&&n!=0)
    	{
    		f=0;
    		scanf("%d%d",&m,&g);
    		for(i=0;i<m;i++)
    			scanf("%d",&a[i]);
    		for(i=0;i<n;i++)
    		{
    			scanf("%s",d[i].num);
    			scanf("%d",&k);
    			d[i].sum=0;
    			for(j=0;j<k;j++)
    			{
    				scanf("%d",&b);
    				d[i].sum+=a[b-1]; 
    			}
    			if(d[i].sum>=g)
    				f++;
    		}
    		sort(d,d+n,cmp);
    		printf("%d\n",f);
    		for(i=0;i<f;i++)
    			printf("%s %d\n",d[i].num,d[i].sum);
    	}
    	return 0;
    }
    

    附上运行截图

    心得:一定要注意到结构体变量的强大,不然多元数据难已处理。
                         
    展开全文
  • C语言学生成绩管理系统详解

    千次阅读 2020-06-07 10:53:22
    引言:最近写了C语言的大作业,感觉做得还行,记录一下,给后人一些参考,给自己留更深印象方便后续改进! 不知道发了这篇博客会不会认为我抄袭…害怕.jpg 一、系统概述 使用单向链表和文件作为基本数据结构,设计一...

    源代码请直接跳到最后

    引言:最近写了C语言的大作业,感觉做得还行,记录一下,给后人一些参考,给自己留更深印象方便后续改进!

    不知道发了这篇博客会不会认为我抄袭…害怕.jpg

    一、系统概述

    使用单向链表和文件作为基本数据结构,设计一个学生成绩管理程序,管理某学校学生成绩。
    [1]插入数据
    [2]修改对应数据项的数据
    [3]删除对应学号的信息
    [4]查找某学号的信息
    [5]查找不及格学生
    [6]对学生成绩进行排名
    [7]统计各个等级的学生人数
    [8]输出所有学生信息
    [9]分页显示学生信息

    二、数据类型

    //枚举
    enum sex{women,man}; 
    struct StuLink{
    	int  xh;                   //学号
    	char xm[20];               //姓名 
    	enum sex  xb;              //性别 
    	int  cj;                   //成绩,范围[0,100]    前四个为输入项 
    	char dj;                   //等级
    	int  mc;                   //名次
    	struct StuLink *next;      //下一项 
    };
    char sex[][3]={"女","男"};     //用于输出“男女”中文字符 
    int size=sizeof(struct StuLink);  //节点字节大小 
    
    1. 注意姓名是xm[20],是字符串;而等级是cj,单个字符;这会影响到赋值问题
    2. 其中姓名、性别、成绩是输入项,名字、等级、名次由程序计算得出

    三、自定义函数说明

    1. main 函数

    函数首部:void main

    参数列表:
    [1] menu1:用于接收一级菜单选择
    [2] menu2:用于接收一级菜单选择
    [3] i:用于 for 循环迭代变量
    [4]n:用于接收“插入数据”功能的学生个数
    [5] dj_add[5]:用于储存各等级人数
    [6] head:用于储存头节点的地址
    [7]pw:用于储存尾节点的地址

    返回值:无

    实现功能:选择对应功能并实现

    算法描述:

    void main(){
    //	声明变量
    	int menu1,menu2;        //menu1:一级菜单 menu2:二级菜单  
    	int i=0,n,dj_add[5]={0,0,0,0,0};
    	struct StuLink *head=NULL,*pw;   //*head:学生信息链表头指针 pw:尾节点 
    	
    //  声明函数
    // 从数据文件中逐行读取学生信息生成学生链表,返回头指针 
    	struct StuLink *ReadFromFile();
    //	先将学生链表按学号升序排序,再将学生链表中的数据逐行保存到数据文件
    	void SaveToFile(struct StuLink *head);
    //	SortLink函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】对学生链表进行排序 
    	struct StuLink *SortLink(struct StuLink *head,int i); 
    //	InsertNode函数:在链表尾插入一个新结点。新结点的学号是链表中最大学号加1,姓名和成绩从键盘输入
    //	(注意:成绩必须在[0,100]区间的整数),根据成绩计算等级。
    //	注意:插入结点会导致链表中各结点名次的变化。
    	struct StuLink *InsertNode(struct StuLink *pw);
    //	EditNode函数:修改链表中指定学号的结点(学号不能修改,成绩必须在[0,100]区间的整数)
    //	注意:当修改成绩时会导致等级和名次的变化
    	void EditNode(struct StuLink *head); 
    //DeleteNode函数:删除链表中指定学号的结点。注意:删除结点会导致链表中各结点名次的变化
    	struct StuLink *DeleteNode(struct StuLink *head);
    //	QueryNode函数:查询链表中指定学号的结点,并显示查询结果。
    void QueryNode(struct StuLink *head);
    //	QueryLink函数:查询链表中不及格的所有结点,并显示查询结果。
    void QueryLink(struct StuLink *head);
    //RankLink函数:计算链表中每个结点的名次。名次规则:按成绩降序排名,从第1名开始依次排名,
    //若出现并列名次,则名次需要叠加。例如,若出现5个并列第1名,则没有第2名,下一个名次是第6名,依此类推。
    void RankLink(struct StuLink *head);
    //AnalysisLink函数:统计并返回各等级人数。等级标准:
    //A:90及以上		B:80及以上		C:70及以上		D:60及以上		E:60以下
    void AnalysisLink(struct StuLink *head,int *dj_add);
    //OutputLink_1函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表、各等级人数。
    //学生成绩表每行输出一个学生信息(依次为学号、姓名、性别、成绩、等级和名次,各项间以1个空格隔开),
    //各等级人数分行输出。
    void  OutputLink_1(struct StuLink *head,int i);
    //OutputLink_2函数:分页显示全部学生的信息。
    //分页功能:每页显示10个学生信息,有上一页、下一页、首页和最后一页的翻页功能。
    void  OutputLink_2(struct StuLink *head,int i);
    	
    //	执行语句
    	head=ReadFromFile();     //读取文件到链表,获取头指针 
    	
    	
    //	菜单
    	while(1){
    		system("cls");                  //清控制台,Windows 
    		printf("========================================\n");//40个=
    		printf("=                                      =\n");
    		printf("=           学生成绩管理程序           =\n");
    		printf("=                              by:xxx =\n"); 
    		printf("========================================\n");
    		printf("=                                      =\n");
    		printf("=        1-数据维护  2-数据查询        =\n");
    		printf("=        3-统计分析  4-报表输出        =\n");
    		printf("=                0-退出                =\n");
    		printf("=                                      =\n");
    		printf("========================================\n");
    //		printf("\n");
    		printf("请选择:");
    		scanf("%d",&menu1); 
    		switch(menu1){                 //一级菜单 
    			case 1:
    				while(1){                      //循环输出二级菜单 
    					system("cls");
    					printf("\n");
    					printf("========================================\n");
    					printf("=                                      =\n");
    					printf("=        1-数据插入  2-数据修改        =\n");
    					printf("=        3-数据删除  0-返回上级        =\n");
    					printf("=                                      =\n");
    					printf("========================================\n");
    					printf("请选择:");
    					scanf("%d",&menu2); 
    					switch(menu2){      //二级菜单 
    						case 1:
    							printf("请输入要插入的学生个数(n>0): "); 
    							scanf("%d",&n);
    							while(n<=0){
    								printf("!!!请输入正确的学生个数!!!: ");
    								scanf("%d",&n);
    							}
    							pw=head;
    							if(pw){
    								while(pw->next)   //获取尾部节点 
    									pw=pw->next;
    							}
    							
    							for(i=0;i<n;i++){
    								pw=InsertNode(pw);
    								if(head==NULL) head=pw;
    							}
    							//	计算名次
    							RankLink(head);
    //							SaveToFile(head);		
    							break;
    						case 2:
    							EditNode(head);
    							//	计算名次
    							RankLink(head);
    //							SaveToFile(head);
    							break;
    						case 3:
    							head=DeleteNode(head);
    							//	计算名次
    							RankLink(head);
    //							SaveToFile(head);	
    							break;
    						case 0:
    							break;
    					}
    					if(menu2==0) break;
    					}
    				break;
    			case 2:
    				while(1){                      //循环输出二级菜单 
    					system("cls");
    					printf("\n");
    					printf("========================================\n");
    					printf("=                                      =\n");
    					printf("=1-学号查询 2-不及格学生查询 0-返回上级=\n");
    					printf("=                                      =\n");
    					printf("========================================\n");
    					printf("请选择:");
    					scanf("%d",&menu2); 
    					switch(menu2){      //二级菜单 
    						case 1:
    							QueryNode(head);
    							printf("\n"); system("pause");
    							break;
    						case 2:
    							QueryLink(head); 
    							printf("\n"); system("pause");
    							break;
    						case 0:
    							break;
    					}
    					if(menu2==0) break;
    					}
    				break;
    			case 3:
    				while(1){                      //循环输出二级菜单 
    					system("cls");
    					printf("\n");
    					printf("========================================\n");
    					printf("=                                      =\n");
    					printf("=    1-成绩名次计算  2-成绩频次分析    =\n");
    					printf("=              0-返回上级              =\n");
    					printf("=                                      =\n");
    					printf("========================================\n");
    					printf("请选择:");
    					scanf("%d",&menu2); 
    					switch(menu2){      //二级菜单 
    						case 1:
    							RankLink(head);
    							break;
    						case 2:
    							AnalysisLink(head,dj_add);
    							printf("'A'有%d人;'B'有%d人,'C'有%d人,'D'有%d人,'E'有%d人,共有%d人\n",
    							dj_add[0],dj_add[1],dj_add[2],dj_add[3],dj_add[4],dj_add[0]+dj_add[1]+dj_add[2]+dj_add[3]+dj_add[4]); 
    							printf("\n"); system("pause"); 
    							break;
    						case 0:
    							break;
    					}
    					if(menu2==0) break;
    					}
    				break;
    			case 4:
    				while(1){                      //循环输出二级菜单 
    					system("cls");
    					printf("\n");
    					printf("========================================\n");
    					printf("=                                      =\n");
    					printf("=1-排序显示学生信息  2-分页显示学生信息=\n");
    					printf("=              0-返回上级              =\n");
    					printf("=                                      =\n");
    					printf("========================================\n");
    					printf("请选择:");
    					scanf("%d",&menu2); 
    					switch(menu2){      //二级菜单 
    						case 1:
    							printf("请选择按【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表:");
    							scanf("%d",&i);
    							while((i!=1)&&(i!=2)){
    								printf("!!!请选择正确选项!!!1 or 2 : ");
    								scanf("%d",&i);
    							}
    							OutputLink_1(head,i);
    							printf("\n"); 
    							system("pause"); 
    							break;
    						case 2:
    							printf("请选择按【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表:");
    							scanf("%d",&i);
    							while((i!=1)&&(i!=2)){
    								printf("!!!请选择正确选项!!!1 or 2 : ");
    								scanf("%d",&i);
    							}
    							OutputLink_2(head,i);
    							break;
    						case 0:
    							break;
    					}
    					if(menu2==0) break;
    					}
    				break;
    			case 0:
    				printf("========================================\n");
    				printf("=                                      =\n");
    				printf("=        你已经退出学生管理系统        =\n");
    				printf("=                                      =\n");
    				printf("========================================\n");
    				return;       //退出main函数 
    		}
    	} 
    
    } 
    

    2. ReadFromFile 函数

    函数首部:struct StuLink *ReadFromFile()

    参数列表:
    [1]fp:用于储存储存在缓冲区的文件地址
    [2]p1:用于储存开辟的新节点的地址
    [3]p2:用于储存尾节点的地址
    [4]head:用于储存首节点的地址
    [5]ch:用于接收文件第一个字符

    返回值:head 的地址

    实现功能:
    1.写打开文件
    2.2.读取文件第一个字符,若是 EOF 文件终止符,则返回 head 的指针,函数结束;否则将 fp 的地址重置为文件开头
    3.3.循环:若 fp 指针不为空,则开辟新节点,并且接入链表的尾节点(根据情况),读取 文件第一行信息并且赋值到 p1 指向的节点中
    4.4.写关闭文件,返回 head 的地址

    算法描述:

    struct StuLink *ReadFromFile(){
    	FILE *fp;                           //指向student.dat文件 
    	struct StuLink *p1,*p2,*head=NULL;  //head:头节点  p1:开辟新节点  p2:尾节点 
    	char ch;
    	
    	if((fp=fopen("student.dat","r"))==NULL){   //读开student.dat 
    		printf("打开student.dat失败\n");
    		exit(0); 
    	} 
    	ch=fgetc(fp);                               //读取文件第一个字符
    	if(ch==EOF){                                //EOF文件终止符
    		printf("文件为空\n");
    		return head;	
    	}else{
    		rewind(fp);                            // 将fp的地址重置为文件开头
    	}
    	
    	while(!feof(fp)){
    		if((p1=(struct StuLink *)malloc(size))==NULL) {
    			printf("不能成功分配储存块");
    			exit(0);
    		}
    		p1->next=NULL;
    		if(head==NULL)  head=p1;        //首节点 
    			else p2->next=p1;     //非首节点,表尾插入新节点 
    		p2=p1;                    // p2指向新的表尾结点 
    		fscanf(fp,"%d %s %d %d %s %d\n",&p1->xh,p1->xm,&p1->xb,&p1->cj,&p1->dj,&p1->mc);
    //		读取\n是防止fp以为文件未完 
    		printf("%-5d%-10s%-5d%-5d%-5c%-5d\n",p1->xh,p1->xm,p1->xb,p1->cj,p1->dj,p1->mc);
    	}
    	fclose(fp);                                 //关闭student.dat
    	return head;
    } 
    

    3. SortLink 函数

    函数首部:struct StuLink *SortLink(struct StuLink *head,int i)

    参数列表:
    [1]head:储存首节点的地址
    [2]i:用于储存排序方式的选项
    [3]xh:用于储存学号
    [4]xb:用于储存性别
    [5]cj:用于储存成绩
    [6]mc:用于储存名次
    [7]xm:用于储存姓名
    [8]dj:用于储存等级
    [9]p1:用于表示被比较节点的地址
    [10]p2:用于表示比较节点的地址
    [11]p3:用于表示中间节点的地址

    返回值:head 的地址

    实现功能:

    1. 判断 head 是否为空,为空则返回 head 并且结束函数
    2. 进行排序,快速排序,交换连个节点的数据项,而不是改变链表的节点信息
    3. 返回 head,结束函数

    算法描述:

    struct StuLink *SortLink(struct StuLink *head,int i){
    		if(head==NULL)return head;
    //		使用交换数据的形式交换两个节点 
    		int xh,xb,cj,mc;
    		char xm[20],dj;
    //		p1:被比较节点  p2:比较节点  p3:快速排序储存节点 
    		struct StuLink *p1=head,*p2=head->next,*p3=p1;
    		switch(i){
    			case 1:
    //				快速排序
    				while(p1->next){
    					p2=p1->next;
    					p3=p1;
    					while(p2){
    						if(p3->xh>p2->xh) 
    							p3=p2;
    						p2=p2->next;
    					}
    					if(p3->xh<p1->xh){
    						xh=p3->xh;  xb=p3->xb;
    						cj=p3->cj;  mc=p3->mc;
    						strcpy(xm,p3->xm);  dj=p3->dj;
    						p3->xh=p1->xh;  p3->xb=p1->xb;
    						p3->cj=p1->cj;  p3->mc=p1->mc;
    						strcpy(p3->xm,p1->xm);  p3->dj=p1->dj;
    						p1->xh=xh;  p1->xb=xb;
    						p1->cj=cj;  p1->mc=mc;
    						strcpy(p1->xm,xm);  p1->dj=dj;
    					} 
    					p1=p1->next;
    				} 
    				break;
    			case 2:
    //				快速排序
    				while(p1->next){
    					p2=p1->next;
    					p3=p1;
    					while(p2){
    						if(p3->cj<p2->cj) 
    							p3=p2;
    						p2=p2->next;
    					}
    					if(p3->cj>p1->cj){
    						xh=p3->xh;  xb=p3->xb;
    						cj=p3->cj;  mc=p3->mc;
    						strcpy(xm,p3->xm);  dj=p3->dj;
    						p3->xh=p1->xh;  p3->xb=p1->xb;
    						p3->cj=p1->cj;  p3->mc=p1->mc;
    						strcpy(p3->xm,p1->xm);  p3->dj=p1->dj;
    						p1->xh=xh;  p1->xb=xb;
    						p1->cj=cj;  p1->mc=mc;
    						strcpy(p1->xm,xm);  p1->dj=dj;
    					} 
    					p1=p1->next;
    				} 
    				break;
    		} 
    		return head;
    	}
    

    4. SaveToFile 函数

    函数首部:void SaveToFile(struct StuLink *head)

    参数列表:
    [1]head:用于表示首节点的地址
    [2]fp:用于表示缓冲区文件的地址
    [3]i:用于储存排序方式

    返回值:无

    实现功能:写开文件,循环将链表中的信息储存到文件中

    算法描述:

    	void SaveToFile(struct StuLink *head){
    		FILE *fp;
    		int i=1;
    		head=SortLink(head,i);
    		struct StuLink *p=head;
    		if((fp=fopen("student.dat","w"))==NULL){
    			printf("写开文件失败!");
    			exit(0);
    		}
    		while(p){
    //			写入文件 
    			fprintf(fp,"%d %s %d %d %c %d\n",p->xh,p->xm,p->xb,p->cj,p->dj,p->mc);
    			p=p->next;
    		}
    		fclose(fp); 
    	}
    

    5. InsertNode 函数

    函数首部:struct StuLink *InsertNode

    参数列表:
    [1]pw:用于表示链表尾节点的地址
    [2]p1:用于表示新节点的地址
    [3]xm:用于表示姓名字符串的地址

    返回值:pw 的地址

    实现功能:开辟一个新节点,用 p1 指向新节点,并向其赋值,同时检查性别和成绩的正确性, 根据成绩计算等级,再将 p1 接在 pw 后面

    算法描述

    struct StuLink *InsertNode(struct StuLink *pw){
    	struct StuLink *p1;    //pw:原链表尾节点	 p1:开辟新节点 
    	if((p1=(struct StuLink *)malloc(size))==NULL) {
    			printf("不能成功分配储存块\n");
    			exit(0);
    	}
    	p1->next=NULL;
    	if(pw)
    		p1->xh=pw->xh+1;
    	else 
    		p1->xh=1;
    	char xm[20];
    	printf("请依次输入姓名、性别(男1女0)、成绩[0,100]:  ");
    	scanf("%s%d%d",xm,&p1->xb,&p1->cj);
    	while(p1->xb!=0&&p1->xb!=1){
    		printf("! ! ! 性别只能是1或0,请重新输入性别1:男    0:女   ");
    		scanf("%d",&p1->xb); 
    	}
    	while(p1->cj<0 || p1->cj>100){
    		printf("! ! ! 成绩范围是0~100,请重新输入成绩   ");
    		scanf("%d",&p1->cj); 
    	}
    	strcpy(p1->xm,xm);
    	
    //	p1->mc=1;  // 名次暂时命名为1 
    	if(p1->cj>=90) p1->dj='A';
    	else if(p1->cj>=80)  p1->dj='B';
    	else if(p1->cj>=70)  p1->dj='C';
    	else if(p1->cj>=60)  p1->dj='D';
    	else p1->dj='E';
    	if(pw==NULL)	pw=p1;
    	else{
    		pw->next=p1;	
    		pw=pw->next;
    	}
    	return pw;
    }
    

    6. EditNode函数

    函数首部:void EditNode(struct StuLink *head)

    参数列表:
    [1]head:用于表示首节点的地址
    [2]p1:用于表示循环寻找对应学号地址
    [3]xm:用于表示姓名字符串
    [4]n:用于表示要修改的学号
    [5]re:用于表示要修改的数据项

    返回值:无 实现功能:先判断链表是否为空,为空则退出函数。输入一个学号,判断是否存在,不存在则退 出函数;存在则输出对应学生信息,选择要修改的数据项进行修改

    返回值:无

    算法描述:

    void EditNode(struct StuLink *head){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	 
    	struct StuLink *p1=head;
    	char xm[20];
    	
    	int n,re;
    	printf("请输入你要修改的学生信息的学号:");
    	scanf("%d",&n) ;
    	while(p1){
    		if(p1->xh==n){
    			break;
    		}else{
    			p1=p1->next;
    		}
    	}
    	if(p1){
    		printf("你要修改的学生信息为:\n");
    		printf("学号  姓名      性别  成绩  等级  名次   ##男1女0##\n");
    		printf("%-6d%-10s%-6d%-6d%-6c%-6d\n",p1->xh,p1->xm,p1->xb,p1->cj,p1->dj,p1->mc);
    	} else{
    		printf("你输入的学号有误!\n");
    		printf("\n"); system("pause");	
    		return;
    	} 
    	printf("请选择要修改的数据项:0-不修改 1-姓名 2-性别 3-成绩  "); 
    	scanf("%d",&re);
    	while(re<0||re>3){
    		printf("输入有误!重新输入: ");
    		scanf("%d",&re);
    	}
    	switch(re){
    		case 0:break;
    		case 1:
    			printf("请输出新的姓名:");
    			scanf("%s",xm);
    			strcpy(p1->xm,xm);
    			break;
    		case 2:
    			printf("请输入新的性别:");
    			scanf("%d",&p1->xb);
    			while(p1->xb!=0&&p1->xb!=1){
    				printf("! ! ! 性别只能是1或0,请重新输入性别1:男    0:女   ");
    				scanf("%d",&p1->xb); 
    			}
    			break;
    		case 3:
    			printf("请输入新的成绩:");
    			scanf("%d",&p1->cj);
    			while(p1->cj<0 || p1->cj>100){
    				printf("! ! ! 成绩范围是0~100,请重新输入成绩   ");
    				scanf("%d",&p1->cj); 
    			}
    			if(p1->cj>=90) p1->dj='A';
    				else if(p1->cj>=80)  p1->dj='B';
    				else if(p1->cj>=70)  p1->dj='C';
    				else if(p1->cj>=60)  p1->dj='D';
    				else p1->dj='E';
    			break;	
    	}
    }
    

    **7. DeleteNode 函数 **

    函数首部:struct StuLink *DeleteNode(struct StuLink *head)

    参数列表:
    [1]head:用于表示首节点的地址
    [2]p1:用于表示循环查找对应节点的地址
    [3]p2:用于表示 p1 指向的节点的前驱节点的地址
    [4]del_xh:用于表示被删除学生的学号

    返回值:head 的地址

    算法描述:

    struct StuLink *DeleteNode(struct StuLink *head){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return head;
    	}
    	struct StuLink *p1=head,*p2;
    	int del_xh;
    	printf("请输入要删除的学号:");
    	scanf("%d",&del_xh); 
    	while((p1->xh!=del_xh)&&(p1->next!=NULL)){
    		p2=p1;p1=p1->next;
    	} 
    	if(p1->xh==del_xh){   //找到 
    		if(head==p1) head=head->next;   //首节点 
    		else p2->next=p1->next;         //非首节点 
    		free(p1); 
    		printf("删除成功!\n");
    	}else printf("未找到此学号对应节点!\n");
    	printf("\n"); system("pause"); 
    	return head;
    }
    

    8. QueryNode 函数

    函数首部:void QueryNode(struct StuLink *head)

    参数列表:
    [1]head:用于表示首节点的地址
    [2]query_xh:用于表示查询的学号
    [3]p1:用于表示循环查找对应节点的地址
    [4]p2:用于表示 p1 指向的节点的前驱节点的地址

    返回值:无

    实现功能:先判断链表是否为空,为空则退出函数。接收要查询的学号,循环寻找,找到则输出学学 生信息;否则输出未找到

    算法描述:

    void QueryNode(struct StuLink *head){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	int query_xh;
    	struct StuLink *p1=head,*p2;
    	printf("请输入要查询的学生学号:");
    	scanf("%d",&query_xh); 
    	while((p1->xh!=query_xh)&&(p1->next!=NULL)){
    		p2=p1;p1=p1->next;
    	} 
    	if(p1->xh==query_xh){           //找到 
    		printf("查找结果为:\n"); 
    		printf("学号:%-5d姓名:%-10s成绩:%-5d等级:%-5c名次:%-5d",p1->xh,p1->xm,p1->cj,p1->dj,p1->mc);
    		if(p1->xb==1) printf("性别:男\n");
    		else printf("性别:女\n"); 
    	}else printf("未找到该学号对应学生!\n");
    }
    

    9. QueryLink 函数

    函数首部:void QueryLink(struct StuLink *head)

    参数列表:
    [1]head:用于表示首节点的地址
    [2]p1:用于表示循环链表各节点的地址
    [3]n:用于表示循环次数

    返回值:无

    实现功能:先判断链表是否为空,为空则退出函数。循环查找不及格学习,符合则输出,不符合则下 一个。若一个不及格的都没有,则输出没有不及格学生

    算法描述:

    void QueryLink(struct StuLink *head){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	struct StuLink *p1=head;
    	int n=0;
    	while(p1){
    		if(p1->cj<60){
    			n++; if(n==1) printf("未及格学生信息为:\n"); 
    			printf("学号:%-5d姓名:%-10s成绩:%-5d等级:%-5c名次:%-5d",p1->xh,p1->xm,p1->cj,p1->dj,p1->mc);
    			if(p1->xb==1) printf("性别:男\n");
    				else printf("性别:女\n"); 
    		}
    		p1=p1->next;
    	}
    	if(n==0) printf("没有不及格学生!\n");
    }
    

    10. RankLink 函数

    函数首部:void RankLink(struct StuLink *head)

    参数列表:
    [1]head:用于表示首节点的地址
    [2]i:用于表示排序的升降序
    [3]p1:用于表示循环链表中节点的地址
    [4]p2:用于表示 p1 指向的节点的前驱节点的地址
    [5]n:用于表示循环次数

    返回值:无

    实现功能:先判断链表是否为空,为空则退出函数。学生按成绩降序排序,再计算链表中每个结 点的名次,最后保存(学号升序)到文件中。

    算法描述:

    void RankLink(struct StuLink *head){
    	int i=2;
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	head=SortLink(head,i);
    	struct StuLink *p1=head,*p2;
    	
    	int n=1;
    	while(p1){
    		p1->mc=n;
    		n++;
    		if((p1!=head)&&((p1->cj)==(p2->cj))) p1->mc=p2->mc;
    		p2=p1;
    		p1=p1->next;
    	}
    	SaveToFile(head);
    }
    

    11. AnalysisLink 函数

    函数首部:void AnalysisLink(struct StuLink *head,int *dj_add)

    参数列表:
    [1]head:用于表示首节点的地址
    [2]dj_add:用于表示各个等级的人数数组
    [3]p1:用于表示循环链表中的节点

    返回值:无

    实现功能:先判断链表是否为空,为空则退出函数。循环各节点,判断成绩且对应等级统计数递增

    算法描述:

    void AnalysisLink(struct StuLink *head,int *dj_add){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	struct StuLink *p1=head;
    	while(p1){
    		if(p1->cj>=90) dj_add[0]++;
    		else if(p1->cj>=80) dj_add[1]++;
    		else if(p1->cj>=70) dj_add[2]++;
    		else if(p1->cj>=60) dj_add[3]++;
    		else  dj_add[5]++;
    		p1=p1->next;
    	}	
    }
    

    12. OutputLink_1 函数

    函数首部:void OutputLink_1(struct StuLink *head,int i)

    参数列表:
    [1]head:用于表示首节点的地址
    [2]p1:用于表示循环链表节点的地址

    返回值:无

    实现功能:先判断链表是否为空,为空则退出函数。循环各节点,输出信息

    算法描述:

    void  OutputLink_1(struct StuLink *head,int i){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	head=SortLink(head,i);
    	struct StuLink *p1=head;
    	printf("所有学生信息为:\n");
    	printf("学号  姓名      性别 成绩  等级  名次\n");
    	while(p1){
    		
    		printf("%-6d%-10s",p1->xh,p1->xm);
    		if(p1->xb==1) printf("男    ");
    			else printf("女    "); 
    		printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    		p1=p1->next;
    	}
    }
    

    13. OutputLink_2 函数

    函数首部:void OutputLink_2(struct StuLink *head,int i)

    参数列表:
    [1]head:用于表示首节点的地址
    [2]i:用于表示排序的升降序
    [3]sum:用于表示学生总数
    [4]n:用于表示当前输出个数
    [5]num1:用于表示菜单选择
    [6]page_sum:用于表示总页数
    [7]page_now:用于表示当前页数
    [8]pf_num:用于表示当前输出的个数,控制不超过 10 个

    返回值:无

    实现功能:先判断链表是否为空,为空则退出函数。先输出第一页,判断总人数,是否有下一页, 无则退出函数,有则继续。接收输入选择功能数字,判断数字时候合理,不合理重新输入。使用 switch 跳到对应功能。1:用上次输出的当前页数*10-20 就等于“上一页”的第一个的学生个数,再用 n 控制 p1 循环到此处进行输出。2:跟着 p1 继续输出。3:输出第一页。4:用(sum/10)*10 就等于最后一页的第一 个学生个数,用 p1 循环到此处,输出即可。

    算法描述:

    void  OutputLink_2(struct StuLink *head,int i){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	head=SortLink(head,i);
    //	sum:学生总数 n:当前输出个数  
    	int n=1,num1,sum=0,page_sum,page_now=1,pf_num=0;
    	struct StuLink *p1=head;
    	while(p1){
    		sum++;
    		p1=p1->next;
    	}
    	p1=head;
    	page_sum=sum/10+1;
    	system("cls");
    	printf("学号  姓名      性别 成绩  等级  名次\n");
    	pf_num=1;
    	while(p1&&pf_num<=10){
    		printf("%-6d%-10s",p1->xh,p1->xm);
    		if(p1->xb==1) printf("男    ");
    			else printf("女    "); 
    		printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    		pf_num++;
    		p1=p1->next;
    	}
    	if(sum<=10){
    		printf("\n只有一页,暂无上下页功能\n"); 
    		system("pause"); return ;
    	}else{
    		printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");
    		printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    		scanf("%d",&num1);
    		while(num1<2||num1>5){
    			printf("请输入正确的数字: ");
    			scanf("%d",&num1);
    		}
    	}
    	while(1) {
    		switch(num1){
    			case 1:
    				system("cls");
    				p1=head;
    				n=1;
    				while(n<=page_now*10-20){
    					p1=p1->next;
    					n++;
    				}
    				printf("学号  姓名      性别 成绩  等级  名次\n");
    				pf_num=1;
    				while(p1&&pf_num<=10){
    					printf("%-6d%-10s",p1->xh,p1->xm);
    					if(p1->xb==1) printf("男    ");
    						else printf("女    "); 
    					printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    					pf_num++;
    					p1=p1->next;
    				}
    				page_now--;                                          //当前页数-1
    				if(page_now==1){
    					printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");
    					printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    					scanf("%d",&num1);
    					while(num1<2||num1>5){
    						printf("请输入正确的数字: ");
    						scanf("%d",&num1);
    					}
    				}else{
    					printf("\n1-上一页  2-下一页  3-首页  4-尾页  5-返回上级\n");
    					printf("            当前第%-2d页,共%-2d页\n"); 
    					scanf("%d",&num1);
    					while(num1<1||num1>4){
    						printf("请输入正确的数字: ");
    						scanf("%d",&num1);
    					}
    				}
    				break;
    			case 2:
    				system("cls");
    				printf("学号  姓名      性别 成绩  等级  名次\n");
    				pf_num=1;
    				while(p1&&pf_num<=10){
    					printf("%-6d%-10s",p1->xh,p1->xm);
    					if(p1->xb==1) printf("男    ");
    						else printf("女    "); 
    					printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    					pf_num++;
    					p1=p1->next;
    				}
    				page_now++;                                          //当前页数+1 
    				if(page_now==page_sum){
    					printf("\n1-上一页            3-首页  4-尾页  5-返回上级\n");
    					printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    					scanf("%d",&num1);
    					while(num1<1||num1>5||num1==2){
    						printf("请输入正确的数字: ");
    						scanf("%d",&num1);
    					}
    				}else{
    					printf("\n1-上一页  2-下一页  3-首页  4-尾页  5-返回上级\n");
    					printf("            当前第%-2d页,共%-2d页\n"); 
    					scanf("%d",&num1);
    					while(num1<1||num1>5){
    						printf("请输入正确的数字: ");
    						scanf("%d",&num1);
    					}
    				}
    				break;
    			case 3:
    				system("cls");
    				p1=head;
    				page_now=1;
    				printf("学号  姓名      性别 成绩  等级  名次\n");
    				pf_num=1;
    				while(p1&&pf_num<=10){
    					printf("%-6d%-10s",p1->xh,p1->xm);
    					if(p1->xb==1) printf("男    ");
    						else printf("女    "); 
    					printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    					pf_num++;
    					p1=p1->next;
    				}
    				printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");
    				printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    				scanf("%d",&num1);
    				while(num1<2||num1>5){
    					printf("请输入正确的数字: ");
    					scanf("%d",&num1);
    				}
    				break;
    			case 4:
    				system("cls");
    				p1=head;
    				page_now=page_sum;
    				n=1;
    				while(n<=(sum/10)*10){
    					p1=p1->next;
    					n++;
    				}
    				printf("学号  姓名      性别 成绩  等级  名次\n");
    				pf_num=1;
    				while(p1&&pf_num<=10){
    					printf("%-6d%-10s",p1->xh,p1->xm);
    					if(p1->xb==1) printf("男    ");
    						else printf("女    "); 
    					printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    					pf_num++;
    					p1=p1->next;
    				}
    				printf("\n1-上一页            3-首页  4-尾页  5-返回上级\n");
    				printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    				scanf("%d",&num1);
    				while(num1<1||num1>5||num1==2){
    					printf("请输入正确的数字: ");
    					scanf("%d",&num1);
    				}
    				break;
    			case 5:
    				break;
    		}
    		if(num1==5) break;
    	}
    }
    

    四、运行界面

    一:主菜单

    二:二级菜单——数据维护

    1. 数据插入

    2. 数据修改

    3. 数据删除

    三:二级菜单——数据查询

    1. 学号查询

    1. 不及格学生查询

    四:二级菜单——统计分析

    1. 成绩名次计算:无输出
    2. 成绩频次分析

    五:二级菜单——报表输出

    1. 排序显示学生信息

    ​ 学号升序:

    ​ 成绩降序:

    1. 分页显示学生信息

    六、退出

    五、源代码

    注意要在同个目录新建一个student.dat文件

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    //枚举
    enum sex{women,man}; 
    struct StuLink{
    	int  xh;                   //学号
    	char xm[20];               //姓名 
    	enum sex  xb;              //性别 
    	int  cj;                   //成绩,范围[0,100]    前四个为输入项 
    	char dj;                   //等级
    	int  mc;                   //名次
    	struct StuLink *next;      //下一项 
    };
    char sex[][3]={"女","男"};     //用于输出“男女”中文字符 
    int size=sizeof(struct StuLink);  //节点字节大小 
    
    void main(){
    //	声明变量
    	int menu1,menu2;        //menu1:一级菜单 menu2:二级菜单  
    	int i=0,n,dj_add[5]={0,0,0,0,0};
    	struct StuLink *head=NULL,*pw;   //*head:学生信息链表头指针 pw:尾节点 
    	
    //  声明函数
    // 从数据文件中逐行读取学生信息生成学生链表,返回头指针 
    	struct StuLink *ReadFromFile();
    //	先将学生链表按学号升序排序,再将学生链表中的数据逐行保存到数据文件
    	void SaveToFile(struct StuLink *head);
    //	SortLink函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】对学生链表进行排序 
    	struct StuLink *SortLink(struct StuLink *head,int i); 
    //	InsertNode函数:在链表尾插入一个新结点。新结点的学号是链表中最大学号加1,姓名和成绩从键盘输入
    //	(注意:成绩必须在[0,100]区间的整数),根据成绩计算等级。
    //	注意:插入结点会导致链表中各结点名次的变化。
    	struct StuLink *InsertNode(struct StuLink *pw);
    //	EditNode函数:修改链表中指定学号的结点(学号不能修改,成绩必须在[0,100]区间的整数)
    //	注意:当修改成绩时会导致等级和名次的变化
    	void EditNode(struct StuLink *head); 
    //DeleteNode函数:删除链表中指定学号的结点。注意:删除结点会导致链表中各结点名次的变化
    	struct StuLink *DeleteNode(struct StuLink *head);
    //	QueryNode函数:查询链表中指定学号的结点,并显示查询结果。
    void QueryNode(struct StuLink *head);
    //	QueryLink函数:查询链表中不及格的所有结点,并显示查询结果。
    void QueryLink(struct StuLink *head);
    //RankLink函数:计算链表中每个结点的名次。名次规则:按成绩降序排名,从第1名开始依次排名,
    //若出现并列名次,则名次需要叠加。例如,若出现5个并列第1名,则没有第2名,下一个名次是第6名,依此类推。
    void RankLink(struct StuLink *head);
    //AnalysisLink函数:统计并返回各等级人数。等级标准:
    //A:90及以上		B:80及以上		C:70及以上		D:60及以上		E:60以下
    void AnalysisLink(struct StuLink *head,int *dj_add);
    //OutputLink_1函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表、各等级人数。
    //学生成绩表每行输出一个学生信息(依次为学号、姓名、性别、成绩、等级和名次,各项间以1个空格隔开),
    //各等级人数分行输出。
    void  OutputLink_1(struct StuLink *head,int i);
    //OutputLink_2函数:分页显示全部学生的信息。
    //分页功能:每页显示10个学生信息,有上一页、下一页、首页和最后一页的翻页功能。
    void  OutputLink_2(struct StuLink *head,int i);
    	
    //	执行语句
    	head=ReadFromFile();     //读取文件到链表,获取头指针 
    	
    	
    //	菜单
    	while(1){
    		system("cls");                  //清控制台,Windows 
    		printf("========================================\n");//40个=
    		printf("=                                      =\n");
    		printf("=           学生成绩管理程序           =\n");
    		printf("=                              by:xxx =\n"); 
    		printf("========================================\n");
    		printf("=                                      =\n");
    		printf("=        1-数据维护  2-数据查询        =\n");
    		printf("=        3-统计分析  4-报表输出        =\n");
    		printf("=                0-退出                =\n");
    		printf("=                                      =\n");
    		printf("========================================\n");
    //		printf("\n");
    		printf("请选择:");
    		scanf("%d",&menu1); 
    		switch(menu1){                 //一级菜单 
    			case 1:
    				while(1){                      //循环输出二级菜单 
    					system("cls");
    					printf("\n");
    					printf("========================================\n");
    					printf("=                                      =\n");
    					printf("=        1-数据插入  2-数据修改        =\n");
    					printf("=        3-数据删除  0-返回上级        =\n");
    					printf("=                                      =\n");
    					printf("========================================\n");
    					printf("请选择:");
    					scanf("%d",&menu2); 
    					switch(menu2){      //二级菜单 
    						case 1:
    							printf("请输入要插入的学生个数(n>0): "); 
    							scanf("%d",&n);
    							while(n<=0){
    								printf("!!!请输入正确的学生个数!!!: ");
    								scanf("%d",&n);
    							}
    							pw=head;
    							if(pw){
    								while(pw->next)   //获取尾部节点 
    									pw=pw->next;
    							}
    							
    							for(i=0;i<n;i++){
    								pw=InsertNode(pw);
    								if(head==NULL) head=pw;
    							}
    							//	计算名次
    							RankLink(head);
    //							SaveToFile(head);		
    							break;
    						case 2:
    							EditNode(head);
    							//	计算名次
    							RankLink(head);
    //							SaveToFile(head);
    							break;
    						case 3:
    							head=DeleteNode(head);
    							//	计算名次
    							RankLink(head);
    //							SaveToFile(head);	
    							break;
    						case 0:
    							break;
    					}
    					if(menu2==0) break;
    					}
    				break;
    			case 2:
    				while(1){                      //循环输出二级菜单 
    					system("cls");
    					printf("\n");
    					printf("========================================\n");
    					printf("=                                      =\n");
    					printf("=1-学号查询 2-不及格学生查询 0-返回上级=\n");
    					printf("=                                      =\n");
    					printf("========================================\n");
    					printf("请选择:");
    					scanf("%d",&menu2); 
    					switch(menu2){      //二级菜单 
    						case 1:
    							QueryNode(head);
    							printf("\n"); system("pause");
    							break;
    						case 2:
    							QueryLink(head); 
    							printf("\n"); system("pause");
    							break;
    						case 0:
    							break;
    					}
    					if(menu2==0) break;
    					}
    				break;
    			case 3:
    				while(1){                      //循环输出二级菜单 
    					system("cls");
    					printf("\n");
    					printf("========================================\n");
    					printf("=                                      =\n");
    					printf("=    1-成绩名次计算  2-成绩频次分析    =\n");
    					printf("=              0-返回上级              =\n");
    					printf("=                                      =\n");
    					printf("========================================\n");
    					printf("请选择:");
    					scanf("%d",&menu2); 
    					switch(menu2){      //二级菜单 
    						case 1:
    							RankLink(head);
    							break;
    						case 2:
    							AnalysisLink(head,dj_add);
    							printf("'A'有%d人;'B'有%d人,'C'有%d人,'D'有%d人,'E'有%d人,共有%d人\n",
    							dj_add[0],dj_add[1],dj_add[2],dj_add[3],dj_add[4],dj_add[0]+dj_add[1]+dj_add[2]+dj_add[3]+dj_add[4]); 
    							printf("\n"); system("pause"); 
    							break;
    						case 0:
    							break;
    					}
    					if(menu2==0) break;
    					}
    				break;
    			case 4:
    				while(1){                      //循环输出二级菜单 
    					system("cls");
    					printf("\n");
    					printf("========================================\n");
    					printf("=                                      =\n");
    					printf("=1-排序显示学生信息  2-分页显示学生信息=\n");
    					printf("=              0-返回上级              =\n");
    					printf("=                                      =\n");
    					printf("========================================\n");
    					printf("请选择:");
    					scanf("%d",&menu2); 
    					switch(menu2){      //二级菜单 
    						case 1:
    							printf("请选择按【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表:");
    							scanf("%d",&i);
    							while((i!=1)&&(i!=2)){
    								printf("!!!请选择正确选项!!!1 or 2 : ");
    								scanf("%d",&i);
    							}
    							OutputLink_1(head,i);
    							printf("\n"); 
    							system("pause"); 
    							break;
    						case 2:
    							printf("请选择按【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表:");
    							scanf("%d",&i);
    							while((i!=1)&&(i!=2)){
    								printf("!!!请选择正确选项!!!1 or 2 : ");
    								scanf("%d",&i);
    							}
    							OutputLink_2(head,i);
    							break;
    						case 0:
    							break;
    					}
    					if(menu2==0) break;
    					}
    				break;
    			case 0:
    				printf("========================================\n");
    				printf("=                                      =\n");
    				printf("=        你已经退出学生管理系统        =\n");
    				printf("=                                      =\n");
    				printf("========================================\n");
    				return;       //退出main函数 
    		}
    	} 
    
    } 
    
    //  自 定 义 函 数 
    // 从数据文件中逐行读取学生信息生成学生链表,返回头指针 
    struct StuLink *ReadFromFile(){
    	FILE *fp;                           //指向student.dat文件 
    	struct StuLink *p1,*p2,*head=NULL;  //head:头节点  p1:开辟新节点  p2:尾节点 
    	char ch;
    	
    	if((fp=fopen("student.dat","r"))==NULL){   //读开student.dat 
    		printf("打开student.dat失败\n");
    		exit(0); 
    	} 
    	ch=fgetc(fp);                               //读取文件第一个字符
    	if(ch==EOF){                                //EOF文件终止符
    		printf("文件为空\n");
    		return head;	
    	}else{
    		rewind(fp);                            // 将fp的地址重置为文件开头
    	}
    	
    	while(!feof(fp)){
    		if((p1=(struct StuLink *)malloc(size))==NULL) {
    			printf("不能成功分配储存块");
    			exit(0);
    		}
    		p1->next=NULL;
    		if(head==NULL)  head=p1;        //首节点 
    			else p2->next=p1;     //非首节点,表尾插入新节点 
    		p2=p1;                    // p2指向新的表尾结点 
    		fscanf(fp,"%d %s %d %d %s %d\n",&p1->xh,p1->xm,&p1->xb,&p1->cj,&p1->dj,&p1->mc);
    //		读取\n是防止fp以为文件未完 
    		printf("%-5d%-10s%-5d%-5d%-5c%-5d\n",p1->xh,p1->xm,p1->xb,p1->cj,p1->dj,p1->mc);
    	}
    	fclose(fp);                                 //关闭student.dat
    	return head;
    } 
    
    //	SortLink函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】对学生链表进行排序
    	struct StuLink *SortLink(struct StuLink *head,int i){
    		if(head==NULL)return head;
    //		使用交换数据的形式交换两个节点 
    		int xh,xb,cj,mc;
    		char xm[20],dj;
    //		p1:被比较节点  p2:比较节点  p3:快速排序储存节点 
    		struct StuLink *p1=head,*p2=head->next,*p3=p1;
    		switch(i){
    			case 1:
    //				快速排序
    				while(p1->next){
    					p2=p1->next;
    					p3=p1;
    					while(p2){
    						if(p3->xh>p2->xh) 
    							p3=p2;
    						p2=p2->next;
    					}
    					if(p3->xh<p1->xh){
    						xh=p3->xh;  xb=p3->xb;
    						cj=p3->cj;  mc=p3->mc;
    						strcpy(xm,p3->xm);  dj=p3->dj;
    						p3->xh=p1->xh;  p3->xb=p1->xb;
    						p3->cj=p1->cj;  p3->mc=p1->mc;
    						strcpy(p3->xm,p1->xm);  p3->dj=p1->dj;
    						p1->xh=xh;  p1->xb=xb;
    						p1->cj=cj;  p1->mc=mc;
    						strcpy(p1->xm,xm);  p1->dj=dj;
    					} 
    					p1=p1->next;
    				} 
    				break;
    			case 2:
    //				快速排序
    				while(p1->next){
    					p2=p1->next;
    					p3=p1;
    					while(p2){
    						if(p3->cj<p2->cj) 
    							p3=p2;
    						p2=p2->next;
    					}
    					if(p3->cj>p1->cj){
    						xh=p3->xh;  xb=p3->xb;
    						cj=p3->cj;  mc=p3->mc;
    						strcpy(xm,p3->xm);  dj=p3->dj;
    						p3->xh=p1->xh;  p3->xb=p1->xb;
    						p3->cj=p1->cj;  p3->mc=p1->mc;
    						strcpy(p3->xm,p1->xm);  p3->dj=p1->dj;
    						p1->xh=xh;  p1->xb=xb;
    						p1->cj=cj;  p1->mc=mc;
    						strcpy(p1->xm,xm);  p1->dj=dj;
    					} 
    					p1=p1->next;
    				} 
    				break;
    		} 
    		return head;
    	}
    
    //	先将学生链表按学号升序排序,再将学生链表中的数据逐行保存到数据文件
    	void SaveToFile(struct StuLink *head){
    		FILE *fp;
    		int i=1;
    		head=SortLink(head,i);
    		struct StuLink *p=head;
    		if((fp=fopen("student.dat","w"))==NULL){
    			printf("写开文件失败!");
    			exit(0);
    		}
    		while(p){
    //			写入文件 
    			fprintf(fp,"%d %s %d %d %c %d\n",p->xh,p->xm,p->xb,p->cj,p->dj,p->mc);
    			p=p->next;
    		}
    		fclose(fp); 
    	}
    	
    //	InsertNode函数:在链表尾插入一个新结点。新结点的学号是链表中最大学号加1,姓名和成绩从键盘输入
    //	(注意:成绩必须在[0,100]区间的整数),根据成绩计算等级。
    //	注意:插入结点会导致链表中各结点名次的变化。
    struct StuLink *InsertNode(struct StuLink *pw){
    	struct StuLink *p1;    //pw:原链表尾节点	 p1:开辟新节点 
    	if((p1=(struct StuLink *)malloc(size))==NULL) {
    			printf("不能成功分配储存块\n");
    			exit(0);
    	}
    	p1->next=NULL;
    	if(pw)
    		p1->xh=pw->xh+1;
    	else 
    		p1->xh=1;
    	char xm[20];
    	printf("请依次输入姓名、性别(男1女0)、成绩[0,100]:  ");
    	scanf("%s%d%d",xm,&p1->xb,&p1->cj);
    	while(p1->xb!=0&&p1->xb!=1){
    		printf("! ! ! 性别只能是1或0,请重新输入性别1:男    0:女   ");
    		scanf("%d",&p1->xb); 
    	}
    	while(p1->cj<0 || p1->cj>100){
    		printf("! ! ! 成绩范围是0~100,请重新输入成绩   ");
    		scanf("%d",&p1->cj); 
    	}
    	strcpy(p1->xm,xm);
    	
    //	p1->mc=1;  // 名次暂时命名为1 
    	if(p1->cj>=90) p1->dj='A';
    	else if(p1->cj>=80)  p1->dj='B';
    	else if(p1->cj>=70)  p1->dj='C';
    	else if(p1->cj>=60)  p1->dj='D';
    	else p1->dj='E';
    	if(pw==NULL)	pw=p1;
    	else{
    		pw->next=p1;	
    		pw=pw->next;
    	}
    	return pw;
    }
    
    //	EditNode函数:修改链表中指定学号的结点(学号不能修改,成绩必须在[0,100]区间的整数)
    //	注意:当修改成绩时会导致等级和名次的变化
    void EditNode(struct StuLink *head){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	 
    	struct StuLink *p1=head;
    	char xm[20];
    	
    	int n,re;
    	printf("请输入你要修改的学生信息的学号:");
    	scanf("%d",&n) ;
    	while(p1){
    		if(p1->xh==n){
    			break;
    		}else{
    			p1=p1->next;
    		}
    	}
    	if(p1){
    		printf("你要修改的学生信息为:\n");
    		printf("学号  姓名      性别  成绩  等级  名次   ##男1女0##\n");
    		printf("%-6d%-10s%-6d%-6d%-6c%-6d\n",p1->xh,p1->xm,p1->xb,p1->cj,p1->dj,p1->mc);
    	} else{
    		printf("你输入的学号有误!\n");
    		printf("\n"); system("pause");	
    		return;
    	} 
    	printf("请选择要修改的数据项:0-不修改 1-姓名 2-性别 3-成绩  "); 
    	scanf("%d",&re);
    	while(re<0||re>3){
    		printf("输入有误!重新输入: ");
    		scanf("%d",&re);
    	}
    	switch(re){
    		case 0:break;
    		case 1:
    			printf("请输出新的姓名:");
    			scanf("%s",xm);
    			strcpy(p1->xm,xm);
    			break;
    		case 2:
    			printf("请输入新的性别:");
    			scanf("%d",&p1->xb);
    			while(p1->xb!=0&&p1->xb!=1){
    				printf("! ! ! 性别只能是1或0,请重新输入性别1:男    0:女   ");
    				scanf("%d",&p1->xb); 
    			}
    			break;
    		case 3:
    			printf("请输入新的成绩:");
    			scanf("%d",&p1->cj);
    			while(p1->cj<0 || p1->cj>100){
    				printf("! ! ! 成绩范围是0~100,请重新输入成绩   ");
    				scanf("%d",&p1->cj); 
    			}
    			if(p1->cj>=90) p1->dj='A';
    				else if(p1->cj>=80)  p1->dj='B';
    				else if(p1->cj>=70)  p1->dj='C';
    				else if(p1->cj>=60)  p1->dj='D';
    				else p1->dj='E';
    			break;	
    	}
    }
    
    //DeleteNode函数:删除链表中指定学号的结点。注意:删除结点会导致链表中各结点名次的变化
    struct StuLink *DeleteNode(struct StuLink *head){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return head;
    	}
    	struct StuLink *p1=head,*p2;
    	int del_xh;
    	printf("请输入要删除的学号:");
    	scanf("%d",&del_xh); 
    	while((p1->xh!=del_xh)&&(p1->next!=NULL)){
    		p2=p1;p1=p1->next;
    	} 
    	if(p1->xh==del_xh){   //找到 
    		if(head==p1) head=head->next;   //首节点 
    		else p2->next=p1->next;         //非首节点 
    		free(p1); 
    		printf("删除成功!\n");
    	}else printf("未找到此学号对应节点!\n");
    	printf("\n"); system("pause"); 
    	return head;
    }
    
    //	QueryNode函数:查询链表中指定学号的结点,并显示查询结果。
    void QueryNode(struct StuLink *head){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	int query_xh;
    	struct StuLink *p1=head,*p2;
    	printf("请输入要查询的学生学号:");
    	scanf("%d",&query_xh); 
    	while((p1->xh!=query_xh)&&(p1->next!=NULL)){
    		p2=p1;p1=p1->next;
    	} 
    	if(p1->xh==query_xh){           //找到 
    		printf("查找结果为:\n"); 
    		printf("学号:%-5d姓名:%-10s成绩:%-5d等级:%-5c名次:%-5d",p1->xh,p1->xm,p1->cj,p1->dj,p1->mc);
    		if(p1->xb==1) printf("性别:男\n");
    		else printf("性别:女\n"); 
    	}else printf("未找到该学号对应学生!\n");
    }
    
    //	QueryLink函数:查询链表中不及格的所有结点,并显示查询结果。
    void QueryLink(struct StuLink *head){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	struct StuLink *p1=head;
    	int n=0;
    	while(p1){
    		if(p1->cj<60){
    			n++; if(n==1) printf("未及格学生信息为:\n"); 
    			printf("学号:%-5d姓名:%-10s成绩:%-5d等级:%-5c名次:%-5d",p1->xh,p1->xm,p1->cj,p1->dj,p1->mc);
    			if(p1->xb==1) printf("性别:男\n");
    				else printf("性别:女\n"); 
    		}
    		p1=p1->next;
    	}
    	if(n==0) printf("没有不及格学生!\n");
    }
    
    //RankLink函数:计算链表中每个结点的名次。名次规则:按成绩降序排名,从第1名开始依次排名,
    //若出现并列名次,则名次需要叠加。例如,若出现5个并列第1名,则没有第2名,下一个名次是第6名,依此类推。
    void RankLink(struct StuLink *head){
    	int i=2;
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	head=SortLink(head,i);
    	struct StuLink *p1=head,*p2;
    	
    	int n=1;
    	while(p1){
    		p1->mc=n;
    		n++;
    		if((p1!=head)&&((p1->cj)==(p2->cj))) p1->mc=p2->mc;
    		p2=p1;
    		p1=p1->next;
    	}
    	SaveToFile(head);
    }
    
    //AnalysisLink函数:统计并返回各等级人数。等级标准:
    //A:90及以上		B:80及以上		C:70及以上		D:60及以上		E:60以下
    void AnalysisLink(struct StuLink *head,int *dj_add){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	struct StuLink *p1=head;
    	while(p1){
    		if(p1->cj>=90) dj_add[0]++;
    		else if(p1->cj>=80) dj_add[1]++;
    		else if(p1->cj>=70) dj_add[2]++;
    		else if(p1->cj>=60) dj_add[3]++;
    		else  dj_add[5]++;
    		p1=p1->next;
    	}	
    }
    
    //OutputLink_1函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表、各等级人数。
    //学生成绩表每行输出一个学生信息(依次为学号、姓名、性别、成绩、等级和名次,各项间以1个空格隔开),
    //各等级人数分行输出。
    void  OutputLink_1(struct StuLink *head,int i){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	head=SortLink(head,i);
    	struct StuLink *p1=head;
    	printf("所有学生信息为:\n");
    	printf("学号  姓名      性别 成绩  等级  名次\n");
    	while(p1){
    		
    		printf("%-6d%-10s",p1->xh,p1->xm);
    		if(p1->xb==1) printf("男    ");
    			else printf("女    "); 
    		printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    		p1=p1->next;
    	}
    }
    
    //OutputLink_2函数:分页显示全部学生的信息。
    //分页功能:每页显示10个学生信息,有上一页、下一页、首页和最后一页的翻页功能。
    void  OutputLink_2(struct StuLink *head,int i){
    	if(head==NULL){
    		printf("学生数据为空!\n");
    		printf("\n"); system("pause");	
    		return;
    	}
    	head=SortLink(head,i);
    //	sum:学生总数 n:当前输出个数  
    	int n=1,num1,sum=0,page_sum,page_now=1,pf_num=0;
    	struct StuLink *p1=head;
    	while(p1){
    		sum++;
    		p1=p1->next;
    	}
    	p1=head;
    	page_sum=sum/10+1;
    	system("cls");
    	printf("学号  姓名      性别 成绩  等级  名次\n");
    	pf_num=1;
    	while(p1&&pf_num<=10){
    		printf("%-6d%-10s",p1->xh,p1->xm);
    		if(p1->xb==1) printf("男    ");
    			else printf("女    "); 
    		printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    		pf_num++;
    		p1=p1->next;
    	}
    	if(sum<=10){
    		printf("\n只有一页,暂无上下页功能\n"); 
    		system("pause"); return ;
    	}else{
    		printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");
    		printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    		scanf("%d",&num1);
    		while(num1<2||num1>5){
    			printf("请输入正确的数字: ");
    			scanf("%d",&num1);
    		}
    	}
    	while(1) {
    		switch(num1){
    			case 1:
    				system("cls");
    				p1=head;
    				n=1;
    				while(n<=page_now*10-20){
    					p1=p1->next;
    					n++;
    				}
    				printf("学号  姓名      性别 成绩  等级  名次\n");
    				pf_num=1;
    				while(p1&&pf_num<=10){
    					printf("%-6d%-10s",p1->xh,p1->xm);
    					if(p1->xb==1) printf("男    ");
    						else printf("女    "); 
    					printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    					pf_num++;
    					p1=p1->next;
    				}
    				page_now--;                                          //当前页数-1
    				if(page_now==1){
    					printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");
    					printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    					scanf("%d",&num1);
    					while(num1<2||num1>5){
    						printf("请输入正确的数字: ");
    						scanf("%d",&num1);
    					}
    				}else{
    					printf("\n1-上一页  2-下一页  3-首页  4-尾页  5-返回上级\n");
    					printf("            当前第%-2d页,共%-2d页\n"); 
    					scanf("%d",&num1);
    					while(num1<1||num1>4){
    						printf("请输入正确的数字: ");
    						scanf("%d",&num1);
    					}
    				}
    				break;
    			case 2:
    				system("cls");
    				printf("学号  姓名      性别 成绩  等级  名次\n");
    				pf_num=1;
    				while(p1&&pf_num<=10){
    					printf("%-6d%-10s",p1->xh,p1->xm);
    					if(p1->xb==1) printf("男    ");
    						else printf("女    "); 
    					printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    					pf_num++;
    					p1=p1->next;
    				}
    				page_now++;                                          //当前页数+1 
    				if(page_now==page_sum){
    					printf("\n1-上一页            3-首页  4-尾页  5-返回上级\n");
    					printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    					scanf("%d",&num1);
    					while(num1<1||num1>5||num1==2){
    						printf("请输入正确的数字: ");
    						scanf("%d",&num1);
    					}
    				}else{
    					printf("\n1-上一页  2-下一页  3-首页  4-尾页  5-返回上级\n");
    					printf("            当前第%-2d页,共%-2d页\n"); 
    					scanf("%d",&num1);
    					while(num1<1||num1>5){
    						printf("请输入正确的数字: ");
    						scanf("%d",&num1);
    					}
    				}
    				break;
    			case 3:
    				system("cls");
    				p1=head;
    				page_now=1;
    				printf("学号  姓名      性别 成绩  等级  名次\n");
    				pf_num=1;
    				while(p1&&pf_num<=10){
    					printf("%-6d%-10s",p1->xh,p1->xm);
    					if(p1->xb==1) printf("男    ");
    						else printf("女    "); 
    					printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    					pf_num++;
    					p1=p1->next;
    				}
    				printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");
    				printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    				scanf("%d",&num1);
    				while(num1<2||num1>5){
    					printf("请输入正确的数字: ");
    					scanf("%d",&num1);
    				}
    				break;
    			case 4:
    				system("cls");
    				p1=head;
    				page_now=page_sum;
    				n=1;
    				while(n<=(sum/10)*10){
    					p1=p1->next;
    					n++;
    				}
    				printf("学号  姓名      性别 成绩  等级  名次\n");
    				pf_num=1;
    				while(p1&&pf_num<=10){
    					printf("%-6d%-10s",p1->xh,p1->xm);
    					if(p1->xb==1) printf("男    ");
    						else printf("女    "); 
    					printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);
    					pf_num++;
    					p1=p1->next;
    				}
    				printf("\n1-上一页            3-首页  4-尾页  5-返回上级\n");
    				printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); 
    				scanf("%d",&num1);
    				while(num1<1||num1>5||num1==2){
    					printf("请输入正确的数字: ");
    					scanf("%d",&num1);
    				}
    				break;
    			case 5:
    				break;
    		}
    		if(num1==5) break;
    	}
    }
    
    展开全文
  • 用C++实现课程成绩统计程序,以条为单位存储学生成绩信息,可以以二进制存到文件中,可以输入,查看,修改,统计学分绩和单科排名,学分绩排名
  • 请编写一个程序,根据输入个人数学成绩获得本次考试的排名C语言代码清单 1:根据输入个人成绩获得考试排名(顺序查找)#include #include int main( ){int i,S;int a[100];printf("从高到低输入成绩(空格分隔),...
  • 程序主要实现功能有:学生信息录入(动态链表创建),输出所有学生信息(链表遍历),输出排名(单向链表排序),以及一系列基于链表操作查询,修改,添加学生成绩和求平均分,统计分数区域人数等功能。 总体思路:...
  • 包括学号、姓名、3门课程的成绩、总分、平均分和排名。(2)能通过键盘录入学生信息,包括学号、姓名和3门课程的成绩。(3)能计算每名学生的总分和平均分。(4)能按...
  • 有n个(n≤10)选手参加比赛,m个(m≤8)评委进行评分,每个选手去掉最高...提供每个选手姓名和各评委评分,依录入次序给每个选手编号,要求按名次顺序给出各选手名次、编号、姓名和最终成绩(保留一位小数)。
  • 某专业2019-2020-2学期开设10门课程,6门必修课,4门选修课(任选2门)。 专业有2个班级,每个班级30人。现要求统计必修课、选修课平均成绩,统计每名学生的成绩,奖...编写统计每名同学奖学金评定成绩排名的函数。
  • 算法大作业,也差不多算是一个C语言课设。这也是自己第一次认真一点点写出代码,可能问题不少,但题目要求也都达到了。 大作业要求:1、自动生成10个班,每个班50人学生语数外成绩; 2、将学生成绩保存到磁盘...
  • 两款C语言编写的学生信息成绩管理系统,以前上C语言实习课编写源程序,时间记不得了现提供给初学者使用。要求:学生信息或者成绩进行管理...使用链表作为主要的数据结构使用,可以求出学生的总分跟个人的成绩排名,要求
  • 输出学生人数,并将成绩排序,并将成绩打印在屏幕上选择法将成绩排序学号,成绩排名斐波那契数列(fibonacci)打印乘法表成绩排序,输出最大值,以及学生人数删掉一个字符串中空格矩阵相乘阶公式判断是否是闰年二...
  • 1004. 成绩排名 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 读入n名学生姓名、学号、成绩...
  • 程序主要实现功能有:学生信息录入(动态链表创建),输出所有学生信息(链表遍历),输出排名(单向链表排序),以及一系列基于链表操作查询,修改,添加学生成绩和求平均分,统计分数区域人数等功能。
  • 学生记录由学号、3门课程成绩和平均分组成,根据班级人数,将学生记录存放在结构体数组中。请编写函数,...并找出排名第一学生。要求:班级人数、学生记录均由键盘输入。</p>
  • 题目来源:大工慕课 链接 作者:Caleb Sung 题目要求 ...成员名形式,按照原始输入顺序输出原始学生信息表(学号、姓名、3门成绩、总成绩、平均成绩及按总成绩排名次);经过计算总成绩、平均成绩和排...
  • 请分析如下题目要求,完成设计任务。...现要求统计必修课、选修课平均成绩,统计每名学生的成绩,奖学金成绩排名程序要求包括以下4个函数。可以以10名同学为例进行设计。设计统计每名同学成绩的函数
  • C语言课设程序和报告

    2012-06-23 14:45:01
    这是C语言的课程设计的程序源码和报告 1、先用记事本编辑文件stu.txt存储一个班学习成绩。然后在C环境下,建立一个学生信息的结构体,用r方式打开上述文件,再用fscanf读入、用printf在屏幕上显示文件内容。 2、利用...
  • 学生成绩管理系统V1.0(4分) 题目内容: 某班有最多不超过30人(具体人数由键盘输入)参加某门课程考试,用一...(5)按学号查询学生排名及其考试成绩; (6)按优秀(90100)、良好(8089)、中等(7079)、...
  • 录入每个学生学号,姓名和各科考试成绩 2.计算每门课程总分和平均分 3.计算每个学生总分和平均分 4.按每个学生总分由高到低排出名次表 5.按每个学生总分由低到高排出名次表 6.按学号由小到大排出成绩表 7....
  • 某班有不超过30人(具体人数由键盘输入)参加某门]课程考试,...按学号查询学生排名及其考试成绩(若找到函数返回对应元素下标,否则返回-1) <p>4) output函数:输出所有人学号和成绩。</p>
  • 通过对系统的分析和设计,进一步巩固C语言的学习,以提高对开发环境的进一步认识和综合编程能力。会用结构体数组或结构体指针,进行学生姓名,学号,成绩的管理,其中包括: ( 0) 退出成绩管理系统 ( 1) 输入学生...
  • 可以输入学生的C语言成绩,数学成绩,英语成绩,修改成绩 按照各科进行排名,查询,统计,存储为文件到电脑上 下面是程序部分截图 主界面: 统计 查询 程序代码: #include <stdio.h> #include <stdlib....
  • (11)输出每个学生学号、姓名、学院、各科考试成绩,以及所有课程总分、平均分、排名; (12)将每个学生记录信息写入文件; (13)从文件中读出每个学生记录信息并显示; (14)结束程序
  • C语言课程设计

    2011-12-11 13:35:11
    程序为一个学生C语言成绩管理系统,对学生的C语言成绩进行管理,学生信息包括学号,姓名,C语言成绩,,输入这些信息,本程序可以自动计算总成绩,可以按高分到低分进行排名,并对输入信息人数进行汇总.
  • } void paixu(struct man a[],int n){ //成绩排序 int i = 0,j = 0; //struct man temp; for(j=0;j for(i=0;i { if(a[i].pj>a[i+1].pj)//数组元素大小按升序排列 { //swap(&temp,a+i); swap(a+i,a+i+1); //swap(a+i...

空空如也

空空如也

1 2 3 4 5
收藏数 94
精华内容 37
关键字:

c语言的成绩排名的程序

c语言 订阅