1. 程式人生 > >學生成績管理系統【C語言程式設計】

學生成績管理系統【C語言程式設計】

一、功能實現:

0、瀏覽學生資訊
1、輸入學生資訊
2、增加學生資訊
3、修改學生資訊
4、刪除學生資訊
5、按學號查詢
6、按班級查詢
7、按姓名查詢
8、按課堂名稱查詢
9、按總分高低排序
10、單科成績排名
11、查詢班級優秀率
12、清屏
13、退出系統

二、運用到的核心知識:

0、動態連結串列的建立、輸出、查詢、增加、修改、刪除等

1、連結串列的氣泡排序

三、程式碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lis struct stu
#define setup (lis *)malloc(sizeof(lis))

struct score
{
    float ord_scor;
    //expe_scor,exam_scor;//可增加學生單科各類成績,為簡便,在此忽略
};

struct stu
{
    int num;
    char name[10];
    struct score Chinese, Math, English, Physics, Chem, Bio;
    float fina_scor;
    lis *next;
};

lis *p;

lis *input()//輸入學生資訊
{
    lis *head, *tail;
    int cnt = 0;
    p = setup;
    printf( "學號  姓名  語文  數學  英語  物理  化學  生物\n" );
    scanf( "%d", &p->num );
    while( 1 )
    {
        if( p->num == 0 )
            break;
        cnt++;
        scanf( "%s%f%f%f%f%f%f", p->name, &( p->Chinese ).ord_scor, &( p->Math ).ord_scor, &( p->English ).ord_scor, &( p->Physics ).ord_scor, &( p->Chem ).ord_scor, &( p->Bio ).ord_scor );
        if( cnt == 1 )
        {
            head = tail = p;
        }
        else
        {
            tail->next = p;
            tail = p;
        }
        p = setup;
        scanf( "%d", &p->num );
    }
    tail->next = NULL;
    return ( head );
}

lis *alter( lis *head ) //修改學生資訊
{
    float alt_num, alt_scor;
    int course;
    printf( "請輸入要修改的學生學號(0代表結束): " );
    scanf( "%f", &alt_num );
    while( alt_num != 0 )
    {
        p = head;
        while( p != NULL )
        {
            if( p->num != alt_num )
                p = p->next;
            else
                break;
        }
        if( p == NULL )
        {
            printf( "輸入學號有錯!請重新輸入(0代表結束): " );
        }
        else
        {
            printf( "請輸入要修改的課程代表的編號(1-語文,2-數學,3-英語,4-物理,5-化學,6-生物,0-修改結束): " );
            scanf( "%d", &course );
            while( course > 6 || course < 0 )
            {
                printf( "輸入編號有錯!請重新輸入編號(0代表結束): " );
                scanf( "%d", &course );
            }
            while( course != 0 )
            {
                if( course > 6 || course < 0 )
                    printf( "輸入編號有錯!請重新輸入編號(0代表結束): " );
                else
                {
                    p = head;
                    while( p != NULL )
                    {
                        if( p->num == alt_num )
                        {
                            printf( "請輸入新成績:\n" );
                            scanf( "%f", &alt_scor );
                            switch( course )
                            {
                            case 1:
                                ( p->Chinese ).ord_scor = alt_scor;
                                break;
                            case 2:
                                ( p->Math ).ord_scor = alt_scor;
                                break;
                            case 3:
                                ( p->English ).ord_scor = alt_scor;
                                break;
                            case 4:
                                ( p->Physics ).ord_scor = alt_scor;
                                break;
                            case 5:
                                ( p->Chem ).ord_scor = alt_scor;
                                break;
                            case 6:
                                ( p->Bio ).ord_scor = alt_scor;
                                break;
                            }
                        }
                        p = p->next;
                    }
                    printf( "若繼續修改該學生成績,請輸入編號(0代表結束): " );
                }
                scanf( "%d", &course );
            }
            printf( "請輸入學號(0代表結束): " );
        }
        scanf( "%f", &alt_num );
    }
    return ( head );
}

lis *add( lis *head ) //增加學生資訊
{
    lis *tail, *z, *q;
    q = tail = head;
    while( q != NULL )
    {
        z = tail; //z指向倒數第二個結點
        tail = q;
        q = q->next;
    }           //tail->next==NULL
    p = setup;
    printf( "請增加學生資訊(學號為0無效,且結束增加):\n學號  姓名  語文  數學  英語  物理  化學  生物\n" );
    scanf( "%d%s%f%f%f%f%f%f", &p->num, p->name, &( p->Chinese ).ord_scor, &( p->Math ).ord_scor, &( p->English ).ord_scor, &( p->Physics ).ord_scor, &( p->Chem ).ord_scor, &( p->Bio ).ord_scor );
    int flag;
    while( p->num != 0 )
    {
        flag = 0;
        while( flag == 0 || flag == 1 )
        {
            q = head;
            while( q != NULL )
            {
                if( q->num == p->num ) //學號重複
                {
                    flag = 1;
                    break;
                }
                else
                    q = q->next;
            }
            if( flag == 1 )
            {
                flag = 0;
                printf( "已存在該學生,請重新輸入:\n" );
                p = setup;
                scanf( "%d%s%f%f%f%f%f%f", &p->num, p->name, &( p->Chinese ).ord_scor, &( p->Math ).ord_scor, &( p->English ).ord_scor, &( p->Physics ).ord_scor, &( p->Chem ).ord_scor, &( p->Bio ).ord_scor );
            }
            else
                break;
        }
        z->next = p;
        p->next = tail;
        z = p;
        p = setup;
        scanf( "%d%s%f%f%f%f%f%f", &p->num, p->name, &( p->Chinese ).ord_scor, &( p->Math ).ord_scor, &( p->English ).ord_scor, &( p->Physics ).ord_scor, &( p->Chem ).ord_scor, &( p->Bio ).ord_scor );
    }
    return ( head );
}

lis *delet( lis *head ) //刪除學生資訊
{
    int del_num;
    lis *t;
    printf( "請輸入要刪除的成績對應的學號(0表示刪除結束):\n" );
    scanf( "%d", &del_num );
    while( del_num )
    {
        p = head;
        while( p != NULL )
        {
            if( head->num == del_num )
            {
                head = p->next;
                break;
            }
            else if( p->num == del_num )
            {
                t->next = p->next;
                break;
            }
            t = p;
            p = p->next;
        }
        if( p == NULL )
            printf( "輸入學號有錯!請重新輸入:\n" );
        scanf( "%d", &del_num );
    }
    return ( head );
}

void search_print( lis *p )
{
    printf( "%d%7s%8.2f%10.2f%10.2f%10.2f%10.2f%10.2f\n", p->num, p->name, ( p->Chinese ).ord_scor, ( p->Math ).ord_scor, ( p->English ).ord_scor, ( p->Physics ).ord_scor, ( p->Chem ).ord_scor, ( p->Bio ).ord_scor );
}

void search( lis *head, int key ) //各種方式查詢學生資訊
{
    lis *q = head;
    int sear_num, sear_class, sear_course, flag1 = 0, flag2 = 0;
    char sear_name[10];
    if( key == 5 )
    {
        printf( "請輸入學號:" );
        scanf( "%d", &sear_num );
    }
    else if( key == 6 )
    {
        flag1 = 1;                      //標記按班級查詢
        printf( "請輸入班級:" );
        scanf( "%d", &sear_class );
    }
    else if( key == 7 )
    {
        printf( "請請輸入姓名:" );
        scanf( "%s", sear_name );
    }
    else if( key == 8 )
    {
        flag2 = 1;                      //標記按課程查詢
        printf( "請輸入課程代表的編號(1-語文,2-數學,3-英語,4-物理,5-化學,6-生物):" );
        scanf( "%d", &sear_course );
    }
    if( flag2 )                         //按課程查詢
    {
        switch( sear_course )
        {
        case 1:
        {
            printf( "學號    姓名    語文\n" );
            while( q != NULL )
            {
                printf( "%d%7s%8.2f\n", q->num, q->name, ( q->Chinese ).ord_scor );
                q = q->next;
            }
        }
        break;
        case 2:
        {
            printf( "學號    姓名    數學\n" );
            while( q != NULL )
            {
                printf( "%d%7s%8.2f\n", q->num, q->name, ( q->Math ).ord_scor );
                q = q->next;
            }
        }
        break;
        case 3:
        {
            printf( "學號    姓名    英語\n" );
            while( q != NULL )
            {
                printf( "%d%7s%8.2f\n", q->num, q->name, ( q->English ).ord_scor );
                q = q->next;
            }
        }
        break;
        case 4:
        {
            printf( "學號    姓名    物理\n" );
            while( q != NULL )
            {
                printf( "%d%7s%8.2f\n", q->num, q->name, ( q->Physics ).ord_scor );
                q = q->next;
            }
        }
        break;
        case 5:
        {
            printf( "學號    姓名    化學\n" );
            while( q != NULL )
            {
                printf( "%d%7s%8.2f\n", q->num, q->name, ( q->Chem ).ord_scor );
                q = q->next;
            }
        }
        break;
        case 6:
        {
            printf( "學號    姓名    生物\n" );
            while( q != NULL )
            {
                printf( "%d%7s%8.2f\n", q->num, q->name, ( q->Bio ).ord_scor );
                q = q->next;
            }
        }
        break;
        default:
            printf( "輸入錯誤!\n" );
        }
    }
    else
    {
        if( flag1 )                     //按班級查詢
        {
            int flag3 = 0;              //標記是否有輸入的班級
            while( q != NULL )
            {
                if( ( q->num ) / 100 == sear_class )
                {
                    flag3 = 1;
                    break;
                }
                q = q->next;
            }
            if( flag3 )
            {
                q = head; //q要指向頭節點
                printf( "學號    姓名    語文    數學    英語    物理    化學    生物\n" );
                while( q != NULL )
                {
                    if( ( q->num ) / 100 == sear_class )
                        search_print( q );
                    q = q->next;
                }
            }
            else
                printf( "輸入錯誤!\n" );
        }
        else                            //按學號或姓名查詢
        {
            while( q != NULL )
            {
                if( q->num == sear_num )
                    break;
                if( strcmp( q->name, sear_name ) == 0 )
                    break;
                q = q->next;
            }
            if( q == NULL )
                printf( "輸入錯誤!\n" );
            else
            {
                printf( "學號    姓名    語文    數學    英語    物理    化學    生物\n" );
                search_print( q );
            }
        }
    }
}

lis *bubble_sort( lis *head, int len, int key ) //氣泡排序
{
    lis *t = setup;
    int i = len;
    if( key == 100 ) //交換總分
    {
        while( i > 1 )
        {
            p = head;
            while( p->next != NULL )
            {
                if( p->fina_scor < ( p->next )->fina_scor )
                {
                    t->num = p->num; //交換學號
                    p->num = ( p->next )->num;
                    ( p->next )->num = t->num;
                    strcpy( t->name, p->name ); //交換姓名
                    strcpy( p->name, ( p->next )->name );
                    strcpy( ( p->next )->name, t->name );
                    t->fina_scor = p->fina_scor;
                    p->fina_scor = ( p->next )->fina_scor;
                    ( p->next )->fina_scor = t->fina_scor;
                }
                p = p->next;
            }
            i--;
        }
        return ( head );
    }
    else if( key == 1 ) //交換語分
    {
        while( i > 1 )
        {
            p = head;
            while( p->next != NULL )
            {
                if( ( p->Chinese ).ord_scor < ( ( p->next )->Chinese ).ord_scor )
                {
                    t->num = p->num; //交換學號
                    p->num = ( p->next )->num;
                    ( p->next )->num = t->num;
                    strcpy( t->name, p->name ); //交換姓名
                    strcpy( p->name, ( p->next )->name );
                    strcpy( ( p->next )->name, t->name );
                    ( t->Chinese ).ord_scor = ( p->Chinese ).ord_scor;
                    ( p->Chinese ).ord_scor = ( ( p->next )->Chinese ).ord_scor;
                    ( ( p->next )->Chinese ).ord_scor = ( t->Chinese ).ord_scor;
                }
                p = p->next;
            }
            i--;
        }
        return ( head );
    }
    else if( key == 2 ) //交換數分
    {
        while( i > 1 )
        {
            p = head;
            while( p->next != NULL )
            {
                if( ( p->Math ).ord_scor < ( ( p->next )->Math ).ord_scor )
                {
                    t->num = p->num; //交換學號
                    p->num = ( p->next )->num;
                    ( p->next )->num = t->num;
                    strcpy( t->name, p->name ); //交換姓名
                    strcpy( p->name, ( p->next )->name );
                    strcpy( ( p->next )->name, t->name );
                    ( t->Math ).ord_scor = ( p->Math ).ord_scor;
                    ( p->Math ).ord_scor = ( ( p->next )->Math ).ord_scor;
                    ( ( p->next )->Math ).ord_scor = ( t->Math ).ord_scor;
                }
                p = p->next;
            }
            i--;
        }
        return ( head );
    }
    else if( key == 3 ) //交換英分
    {
        while( i > 1 )
        {
            p = head;
            while( p->next != NULL )
            {
                if( ( p->English ).ord_scor < ( ( p->next )->English ).ord_scor )
                {
                    t->num = p->num; //交換學號
                    p->num = ( p->next )->num;
                    ( p->next )->num = t->num;
                    strcpy( t->name, p->name ); //交換姓名
                    strcpy( p->name, ( p->next )->name );
                    strcpy( ( p->next )->name, t->name );
                    ( t->English ).ord_scor = ( p->English ).ord_scor;
                    ( p->English ).ord_scor = ( ( p->next )->English ).ord_scor;
                    ( ( p->next )->English ).ord_scor = ( t->English ).ord_scor;
                }
                p = p->next;
            }
            i--;
        }
        return ( head );
    }
    else if( key == 4 ) //交換物分
    {
        while( i > 1 )
        {
            p = head;
            while( p->next != NULL )
            {
                if( ( p->Physics ).ord_scor < ( ( p->next )->Physics ).ord_scor )
                {
                    t->num = p->num; //交換學號
                    p->num = ( p->next )->num;
                    ( p->next )->num = t->num;
                    strcpy( t->name, p->name ); //交換姓名
                    strcpy( p->name, ( p->next )->name );
                    strcpy( ( p->next )->name, t->name );
                    ( t->Physics ).ord_scor = ( p->Physics ).ord_scor;
                    ( p->Physics ).ord_scor = ( ( p->next )->Physics ).ord_scor;
                    ( ( p->next )->Physics ).ord_scor = ( t->Physics ).ord_scor;
                }
                p = p->next;
            }
            i--;
        }
        return ( head );
    }
    else if( key == 5 ) //交換化分
    {
        while( i > 1 )
        {
            p = head;
            while( p->next != NULL )
            {
                if( ( p->Chem ).ord_scor < ( ( p->next )->Chem ).ord_scor )
                {
                    t->num = p->num; //交換學號
                    p->num = ( p->next )->num;
                    ( p->next )->num = t->num;
                    strcpy( t->name, p->name ); //交換姓名
                    strcpy( p->name, ( p->next )->name );
                    strcpy( ( p->next )->name, t->name );
                    ( t->Chem ).ord_scor = ( p->Chem ).ord_scor;
                    ( p->Chem ).ord_scor = ( ( p->next )->Chem ).ord_scor;
                    ( ( p->next )->Chem ).ord_scor = ( t->Chem ).ord_scor;
                }
                p = p->next;
            }
            i--;
        }
        return ( head );
    }
    else if( key == 6 ) //交換生分
    {
        while( i > 1 )
        {
            p = head;
            while( p->next != NULL )
            {
                if( ( p->Bio ).ord_scor < ( ( p->next )->Bio ).ord_scor )
                {
                    t->num = p->num; //交換學號
                    p->num = ( p->next )->num;
                    ( p->next )->num = t->num;
                    strcpy( t->name, p->name ); //交換姓名
                    strcpy( p->name, ( p->next )->name );
                    strcpy( ( p->next )->name, t->name );
                    ( t->Bio ).ord_scor = ( p->Bio ).ord_scor;
                    ( p->Bio ).ord_scor = ( ( p->next )->Bio ).ord_scor;
                    ( ( p->next )->Bio ).ord_scor = ( t->Bio ).ord_scor;
                }
                p = p->next;
            }
            i--;
        }
        return ( head );
    }
}

void final_score_sort( lis *head ) //按總分高低排序
{
    int cnt = 0, z = 100;
    p = head;
    while( p != NULL )
    {
        cnt++;
        p->fina_scor = ( p->Chinese ).ord_scor + ( p->Math ).ord_scor + ( p->English ).ord_scor + ( p->Physics ).ord_scor + ( p->Chem ).ord_scor + ( p->Bio ).ord_scor;
        p = p->next;
    }
    head = bubble_sort( head, cnt, z );
    printf( "名次    學號\t    姓名    總分\n" );
    cnt = 1;
    p = head;
    while( p != NULL )
    {
        printf( "%d\t%d\t%7s%8.2f\n", cnt++, p->num, p->name, p->fina_scor );
        p = p->next;
    }
}

void  single_course_sort( lis *head ) //單科成績排名
{
    int select, cnt = 0;
    p = head;
    while( p != NULL )
    {
        cnt++;
        p = p->next;
    }
    printf( "請輸入課程代表的編號(1-語文,2-數學,3-英語,4-物理,5-化學,6-生物):" );
    scanf( "%d", &select );
    switch( select )
    {
    case 1:
    {
        head = bubble_sort( head, cnt, select );
        printf( "名次    學號\t    姓名    語文分數\n" );
        cnt = 1;
        p = head;
        while( p != NULL )
        {
            printf( "%d\t%d\t%7s%8.2f\n", cnt++, p->num, p->name, ( p->Chinese ).ord_scor );
            p = p->next;
        }
    }
    break;
    case 2:
    {
        head = bubble_sort( head, cnt, select );
        printf( "名次    學號\t    姓名    數學分數\n" );
        cnt = 1;
        p = head;
        while( p != NULL )
        {
            printf( "%d\t%d\t%7s%8.2f\n", cnt++, p->num, p->name, ( p->Math ).ord_scor );
            p = p->next;
        }
    }
    break;
    case 3:
    {
        head = bubble_sort( head, cnt, select );
        printf( "名次    學號\t    姓名    英語分數\n" );
        cnt = 1;
        p = head;
        while( p != NULL )
        {
            printf( "%d\t%d\t%7s%8.2f\n", cnt++, p->num, p->name, ( p->English ).ord_scor );
            p = p->next;
        }
    }
    break;
    case 4:
    {
        head = bubble_sort( head, cnt, select );
        printf( "名次    學號\t    姓名    物理分數\n" );
        cnt = 1;
        p = head;
        while( p != NULL )
        {
            printf( "%d\t%d\t%7s%8.2f\n", cnt++, p->num, p->name, ( p->Physics ).ord_scor );
            p = p->next;
        }
    }
    break;
    case 5:
    {
        head = bubble_sort( head, cnt, select );
        printf( "名次    學號\t    姓名    化學分數\n" );
        cnt = 1;
        p = head;
        while( p != NULL )
        {
            printf( "%d\t%d\t%7s%8.2f\n", cnt++, p->num, p->name, ( p->Chem ).ord_scor );
            p = p->next;
        }
    }
    break;
    case 6:
    {
        head = bubble_sort( head, cnt, select );
        printf( "名次    學號\t    姓名    生物分數\n" );
        cnt = 1;
        p = head;
        while( p != NULL )
        {
            printf( "%d\t%d\t%7s%8.2f\n", cnt++, p->num, p->name, ( p->Bio ).ord_scor );
            p = p->next;
        }
    }
    break;
    default:
        printf( "輸入錯誤!\n" );
    }
}

struct class_excel_rate
{
    int class_num, all_stu, excel_stu;
    struct class_excel_rate *next;
};

void bubble_sort_print( struct class_excel_rate *head, int lenth ) //氣泡排序並輸出班級優秀率
{
    struct class_excel_rate *t = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
    int len = 0;
    float s;
    t = head;
    while( t != NULL )
    {
        len++;
        t = t->next;
    }
    while( len > 1 )
    {
        t = head;
        while( t->next != NULL )
        {
            if( ( t->next )->excel_stu / ( ( t->next )->all_stu * 0.1 ) > t->excel_stu / ( t->all_stu * 0.1 ) )
            {
                s = t->excel_stu;
                t->excel_stu = ( t->next )->excel_stu;
                ( t->next )->excel_stu = s;
                s = t->all_stu;
                t->all_stu = ( t->next )->all_stu;
                ( t->next )->all_stu = s;
            }
            t = t->next;
        }
        len--;
    }
    printf( "名次\t班級\t     總人數    優秀人數    優秀率\n" );
    int i = 1;
    t = head;
    while( t != NULL )
    {
        printf( "%d\t%d\t\t%d\t  %d\t   %.2f%%\n", i++, t->class_num, t->all_stu, t->excel_stu, t->excel_stu / ( t->all_stu * 0.1 ) * 10 );
        t = t->next;
    }
}

void select_class_find( lis *head, int len, int key ) //查詢班級優秀率
{
    struct class_excel_rate *head1, *q, *r, *k; //建立新連結串列
    switch( key )
    {
    case 1://查詢語文
    {
        p = head;
        head1 = q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
        head1->class_num = p->num / 100; //初始化頭節點
        head1->all_stu = 1;
        if( ( p->Chinese ).ord_scor >= 90.0 )
            head1->excel_stu = 1;
        else
            head1->excel_stu = 0;
        p = p->next;
        while( p->next != NULL ) //先建立兩個兩個首、尾結點,以便其它班級的插入
        {
            if( p->num / 100 == head1->class_num ) //相同班級
            {
                head1->all_stu++;
                if( ( p->Chinese ).ord_scor >= 90.0 )
                    head1->excel_stu++;
            }
            else
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Chinese ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                head1->next = q;
                q->next = NULL;
                break;//建立鏈尾結點
            }
            p = p->next;
        }
        p = p->next;
        while( p != NULL ) //檢索所有剩餘的班級
        {
            r = k = head1; //問題:最後一個班級檢索沒有被處理
            while( r != NULL ) //檢索班級是否相同
            {
                if( p->num / 100 == r->class_num )
                {
                    r->all_stu++;
                    if( ( p->Chinese ).ord_scor >= 90.0 )
                        r->excel_stu++;
                    break;
                }
                else
                {
                    k = r;
                    r = r->next;
                }
            }
            if( r == NULL ) //沒有相同的班級,插入新結點
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Chinese ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                k->next = q;
                q->next = r;
            }
            p = p->next; //檢索下一個處理的班級
        }
        bubble_sort_print( head1, len );
    }
    break;
    case 2://查詢數學
    {
        p = head;
        head1 = q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
        head1->class_num = p->num / 100; //初始化頭節點
        head1->all_stu = 1;
        if( ( p->Math ).ord_scor >= 90.0 )
            head1->excel_stu = 1;
        else
            head1->excel_stu = 0;
        p = p->next;
        while( p->next != NULL ) //先建立兩個兩個首、尾結點,以便其它班級的插入
        {
            if( p->num / 100 == head1->class_num ) //相同班級
            {
                head1->all_stu++;
                if( ( p->Math ).ord_scor >= 90.0 )
                    head1->excel_stu++;
            }
            else
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Math ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                head1->next = q;
                q->next = NULL;
                break;//建立鏈尾結點
            }
            p = p->next;
        }
        p = p->next;
        while( p != NULL ) //檢索所有剩餘的班級
        {
            r = k = head1; //問題:最後一個班級檢索沒有被處理
            while( r != NULL ) //檢索班級是否相同
            {
                if( p->num / 100 == r->class_num )
                {
                    r->all_stu++;
                    if( ( p->Math ).ord_scor >= 90.0 )
                        r->excel_stu++;
                    break;
                }
                else
                {
                    k = r;
                    r = r->next;
                }
            }
            if( r == NULL ) //沒有相同的班級,插入新結點
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Math ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                k->next = q;
                q->next = r;
            }
            p = p->next; //檢索下一個處理的班級
        }
        bubble_sort_print( head1, len );
    }
    break;
    case 3://查詢英語
    {
        p = head;
        head1 = q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
        head1->class_num = p->num / 100; //初始化頭節點
        head1->all_stu = 1;
        if( ( p->English ).ord_scor >= 90.0 )
            head1->excel_stu = 1;
        else
            head1->excel_stu = 0;
        p = p->next;
        while( p->next != NULL ) //先建立兩個兩個首、尾結點,以便其它班級的插入
        {
            if( p->num / 100 == head1->class_num ) //相同班級
            {
                head1->all_stu++;
                if( ( p->English ).ord_scor >= 90.0 )
                    head1->excel_stu++;
            }
            else
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->English ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                head1->next = q;
                q->next = NULL;
                break;//建立鏈尾結點
            }
            p = p->next;
        }
        p = p->next;
        while( p != NULL ) //檢索所有剩餘的班級
        {
            r = k = head1; //問題:最後一個班級檢索沒有被處理
            while( r != NULL ) //檢索班級是否相同
            {
                if( p->num / 100 == r->class_num )
                {
                    r->all_stu++;
                    if( ( p->English ).ord_scor >= 90.0 )
                        r->excel_stu++;
                    break;
                }
                else
                {
                    k = r;
                    r = r->next;
                }
            }
            if( r == NULL ) //沒有相同的班級,插入新結點
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->English ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                k->next = q;
                q->next = r;
            }
            p = p->next; //檢索下一個處理的班級
        }
        bubble_sort_print( head1, len );
    }
    break;
    case 4://查詢物理
    {
        p = head;
        head1 = q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
        head1->class_num = p->num / 100; //初始化頭節點
        head1->all_stu = 1;
        if( ( p->Physics ).ord_scor >= 90.0 )
            head1->excel_stu = 1;
        else
            head1->excel_stu = 0;
        p = p->next;
        while( p->next != NULL ) //先建立兩個兩個首、尾結點,以便其它班級的插入
        {
            if( p->num / 100 == head1->class_num ) //相同班級
            {
                head1->all_stu++;
                if( ( p->Physics ).ord_scor >= 90.0 )
                    head1->excel_stu++;
            }
            else
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Physics ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                head1->next = q;
                q->next = NULL;
                break;//建立鏈尾結點
            }
            p = p->next;
        }
        p = p->next;
        while( p != NULL ) //檢索所有剩餘的班級
        {
            r = k = head1; //問題:最後一個班級檢索沒有被處理
            while( r != NULL ) //檢索班級是否相同
            {
                if( p->num / 100 == r->class_num )
                {
                    r->all_stu++;
                    if( ( p->Physics ).ord_scor >= 90.0 )
                        r->excel_stu++;
                    break;
                }
                else
                {
                    k = r;
                    r = r->next;
                }
            }
            if( r == NULL ) //沒有相同的班級,插入新結點
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Physics ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                k->next = q;
                q->next = r;
            }
            p = p->next; //檢索下一個處理的班級
        }
        bubble_sort_print( head1, len );
    }
    break;
    case 5://查詢化學
    {
        p = head;
        head1 = q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
        head1->class_num = p->num / 100; //初始化頭節點
        head1->all_stu = 1;
        if( ( p->Chem ).ord_scor >= 90.0 )
            head1->excel_stu = 1;
        else
            head1->excel_stu = 0;
        p = p->next;
        while( p->next != NULL ) //先建立兩個兩個首、尾結點,以便其它班級的插入
        {
            if( p->num / 100 == head1->class_num ) //相同班級
            {
                head1->all_stu++;
                if( ( p->Chem ).ord_scor >= 90.0 )
                    head1->excel_stu++;
            }
            else
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Chem ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                head1->next = q;
                q->next = NULL;
                break;//建立鏈尾結點
            }
            p = p->next;
        }
        p = p->next;
        while( p != NULL ) //檢索所有剩餘的班級
        {
            r = k = head1; //問題:最後一個班級檢索沒有被處理
            while( r != NULL ) //檢索班級是否相同
            {
                if( p->num / 100 == r->class_num )
                {
                    r->all_stu++;
                    if( ( p->Chem ).ord_scor >= 90.0 )
                        r->excel_stu++;
                    break;
                }
                else
                {
                    k = r;
                    r = r->next;
                }
            }
            if( r == NULL ) //沒有相同的班級,插入新結點
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Chem ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                k->next = q;
                q->next = r;
            }
            p = p->next; //檢索下一個處理的班級
        }
        bubble_sort_print( head1, len );
    }
    break;
    case 6://查詢生物
    {
        p = head;
        head1 = q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
        head1->class_num = p->num / 100; //初始化頭節點
        head1->all_stu = 1;
        if( ( p->Bio ).ord_scor >= 90.0 )
            head1->excel_stu = 1;
        else
            head1->excel_stu = 0;
        p = p->next;
        while( p->next != NULL ) //先建立兩個兩個首、尾結點,以便其它班級的插入
        {
            if( p->num / 100 == head1->class_num ) //相同班級
            {
                head1->all_stu++;
                if( ( p->Bio ).ord_scor >= 90.0 )
                    head1->excel_stu++;
            }
            else
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Bio ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                head1->next = q;
                q->next = NULL;
                break;//建立鏈尾結點
            }
            p = p->next;
        }
        p = p->next;
        while( p != NULL ) //檢索所有剩餘的班級
        {
            r = k = head1; //問題:最後一個班級檢索沒有被處理
            while( r != NULL ) //檢索班級是否相同
            {
                if( p->num / 100 == r->class_num )
                {
                    r->all_stu++;
                    if( ( p->Bio ).ord_scor >= 90.0 )
                        r->excel_stu++;
                    break;
                }
                else
                {
                    k = r;
                    r = r->next;
                }
            }
            if( r == NULL ) //沒有相同的班級,插入新結點
            {
                q = ( struct class_excel_rate * )malloc( sizeof( struct class_excel_rate ) );
                q->class_num = p->num / 100;
                q->all_stu = 1;
                if( ( p->Bio ).ord_scor >= 90.0 )
                    q->excel_stu = 1;
                else
                    q->excel_stu = 0;
                k->next = q;
                q->next = r;
            }
            p = p->next; //檢索下一個處理的班級
        }
        bubble_sort_print( head1, len );
    }
    break;
    }
}

void select_course_find( lis *head ) //選擇查詢課程優秀率
{
    int select, cnt = 0;
    p = head;
    while( p != NULL )
    {
        cnt++;
        p = p->next;
    }
    printf( "請輸入課程代表的編號(1-語文,2-數學,3-英語,4-物理,5-化學,6-生物):" );
    scanf( "%d", &select );
    switch( select )
    {
    case 1:
        select_class_find( head, cnt, select );
        break;
    case 2:
        select_class_find( head, cnt, select );
        break;
    case 3:
        select_class_find( head, cnt, select );
        break;
    case 4:
        select_class_find( head, cnt, select );
        break;
    case 5:
        select_class_find( head, cnt, select );
        break;
    case 6:
        select_class_find( head, cnt, select );
        break;
    default:
        printf( "輸入錯誤!\n" );
    }
}

void output( lis *head ) //輸出學生資訊
{
    p = setup;
    p = head;
    printf( "學號    姓名    語文      數學      英語      物理      化學      生物\n" );
    while( p != NULL )
    {
        printf( "%d%7s%8.2f%10.2f%10.2f%10.2f%10.2f%10.2f\n", p->num, p->name, ( p->Chinese ).ord_scor, ( p->Math ).ord_scor, ( p->English ).ord_scor, ( p->Physics ).ord_scor, ( p->Chem ).ord_scor, ( p->Bio ).ord_scor );
        p = p->next;
    }
}

void print()
{
    printf( "\t\t-------學生成績管理系統-------\n" );
    printf( "\t\t\t0、瀏覽學生資訊\n\t\t\t1、輸入學生資訊\n\t\t\t2、增加學生資訊\n\t\t\t3、修改學生資訊\n\t\t\t4、刪除學生資訊\n\t\t\t5、按學號查詢\n" );
    printf( "\t\t\t6、按班級查詢\n\t\t\t7、按姓名查詢\n\t\t\t8、按課堂名稱查詢\n\t\t\t9、按總分高低排序\n\t\t\t10、單科成績排名\n\t\t\t11、查詢班級優秀率\n\t\t\t12、清屏\n\t\t\t13、退出系統\n" );
    printf( "\t\t------------------------------\n" );
    printf( "\n>>請輸入要實現功能前的序號:  " );
}

int main()
{
    int fun;
    lis *student;
    print();
    while( 1 )
    {
        scanf( "%d", &fun );
        switch( fun )
        {
        case 0:
            output( student );
            break;
        case 1:
            student = input();
            break;
        case 2:
            student = add( student );
            break;
        case 3:
            student = alter( student );
            break;
        case 4:
            student = delet( student );
            break;
        case 5:
        case 6:
        case 7:
        case 8:
            search( student, fun );
            break;
        case 9:
            final_score_sort( student );
            break;
        case 10:
            single_course_sort( student );
            break;
        case 11:
            select_course_find( student );
            break;
        case 12: {
            system( "cls" );
            print();
        }
        }
        if( fun == 1 )
        {
            system( "cls" );
            print();
        }
        else if( fun == 13 )
            break;
        else if( fun > 13 )
            printf( "\n\t**輸入錯誤!\n>>請輸入要實現功能前的序號: " );
        else if( fun != 12 )
            printf( "\n>>請輸入要實現功能前的序號: " );
    }
    return 0;
}

/*測試資料
150901 james  100  99    94   89.9    93    95
130118 bryant 93   98    75   78.9    99.2  97.1
161226 lu     85   99    78   79      66    66.9
130821 jordon 99   100   98.1 90.6    91    89.9
150928 antony 98   97.4  91.9 89      78    79.4
161127 durant 100  98    93   82      97    80
161222 love   90   89    90   91.2    93    82.7
130156 duncan 99   98    91   82.5    89    78
160703 paul   90   91.5  98   89      87.9  80
150433 wade   93   93.4  95   91      89    80.9
161316 irving 96   89    91.8 95      91    98.8
161205 harden 89   88    93   95      96.7  99
161305 curry  89.9 92    89   46.9    39    100
160739 bosh   91.5 78    98   69.9    89    85
0
*/