1. 程式人生 > >課程設計————學生資訊管理系統(包含歷代思路和程式碼)

課程設計————學生資訊管理系統(包含歷代思路和程式碼)

課程設計————學生管理系統(包含歷代思路和程式碼)

一.前言

學生資訊管理系統是我第一個獨立完成的比較長的程式碼,也算是花費了一些心血,這個系統是我一點點把它從幾百行的程式碼逐漸優化到上千行,功能從簡單到複雜。在這裡我把我的思路分享給大家,希望能給大家帶來一些幫助。

相比較上一篇部落格(學生管理系統)而言,這一篇,主要講的是我逐步優化的思路和過程。以及在那篇部落格後,繼續進行的優化。

二.學生管理系統1.0版

1. 實現功能

  • 簡單的密碼驗證
  • 學生資訊的錄入(連結串列的建立)
  • 學生資訊的增.刪.改.查
  • 按照平均分排序輸出

2. 函式框架

int main(void)
{
    int a;
    struct student *pHead;
    show1(); 
    while
(1) { system("cls");//清屏 show2();//介面 fflush(stdin); scanf("%d",&a); switch(a) { case 1:pHead=input();break;//輸入 case 2:output(pHead);break;//輸出 case 3:increase(pHead);break;//增加 case 4:strike_out(pHead);break
;//刪除 case 5:chang(pHead);break;//修改 case 6:inquiry(pHead);break;//查詢 case 7:sore(pHead);break;//排序 case 0:exit(0);break; default :printf("輸入有誤請重新輸入\n");break; } printf("按任意鍵進行下一步操作\n"); getch(); } }

3. 函式呼叫關係圖

這裡寫圖片描述

4. 部分功能函式

  1. 連結串列的建立輸出和增刪改查
    這一部分大家可以參考我之前的部落格(連結串列及其簡單應用),裡面有較詳細的說明
  2. 連結串列的排序
    這一部分在我之前的部落格(連結串列及其簡單應用)中也有寫到,裡面介紹了兩種排序,連結串列的氣泡排序和插入排序。相比較而言,其實插入排序更加簡單一點,可能是因為氣泡排序是我接觸的第一個排序吧,所以我的程式碼中幾乎都是用冒泡來進行排序的
  3. 密碼的輸入顯示 *
void show1()
{
    char cipher[20]={"123456"},a[20],t;//cioher 表示密碼
    int i,j;
    printf("歡迎進入學生資訊管理系統\n");
    for(i=0;i<3;i++)
    {
        printf("請輸入管理員密碼:");    
        for(j=0;a[j-1]!=13;j++)//輸入時回車時,停止錄入密碼
        {
            a[j]=getch();//getch接受鍵盤輸入字元,不顯示到螢幕上
            if(a[j]==8&&j>0)//如果輸入的是刪除鍵
            {
                printf("\b \b");//用\b和空格覆蓋前面的*
                j-=2;//刪除陣列中的字元
            }       
            else if(j>=0)
                printf("*");
            else //防止刪除提示語句
                printf(" ");
        }
        printf("\n");
        a[j-1]='\0';    
        if(strcmp(cipher,a)==0)
            return;
    }
    printf("三次輸入錯誤!!!退出系統\n");
    Sleep(150);
    exit(1);
}

5. 原始碼

程式碼地址

學生資訊管理2.0版

這個版中,剛剛學習了檔案的相關操作,所以將檔案的操作加入到其中。

1. 新增功能

  1. 從檔案中錄入資料
  2. 可以選擇多種順序輸出
  3. 將學生資訊儲存到檔案中
  4. 使用多檔案儲存不同功能的函式

2. 函式框架

int main(void)
{
    struct student *pHead;
    int flag;
    show1();//登入介面 
    pHead=startup();//資訊的錄入 
    save_3(pHead);//儲存到快取檔案中 
    while(1)
    {
        system("cls");
        show3();
        fflush(stdin);
        scanf("%d",&flag);
        switch(flag)
        {
            case 1:increase(pHead);break;//增加  
            case 2:strike_out(pHead);break;//刪除 
            case 3:chang(pHead);break;//修改 
            case 4:inquiry(pHead);break;//查詢
            case 5:save_3(pHead);
                   output(pHead);
                   pHead=finput(1);break;//輸出
            case 6:
                   save_3(pHead);
                   save(pHead);
                   pHead=finput(1);break;//儲存 
            case 0:exit(0);break;
            default :printf("輸入有誤請重新輸入\n");break; 
        }
        printf("按任意鍵進行下一步操作\n");
        getch();
    }   
}

3. 函式呼叫關係圖

這裡寫圖片描述

4. 部分功能函式

  1. 檔案的讀
struct student *finput(int a)//檔案錄入 a控制是否需要輸入檔名 
{

    FILE *fp;
    struct student *pHead=NULL,*pEnd,*pNew;
    int sum=0,i,j,num;
    char filename[100]=N; 
    if(a==2)
    {
        printf("請輸入檔案路徑及檔名:"); 
        fflush(stdin); 
        gets(filename);
    }
    iCound=0;
    pEnd=pHead=(struct student *)malloc(sizeof(struct student));
    fp=fopen(filename,"rt+");
    if(fp==NULL)
    {
        printf("不能開啟檔案");
        exit(1); 
    }
    while(1)
    {
        sum=0;
        pNew=(struct student *)malloc(sizeof(struct student));
        fscanf(fp,"%s %s %s",pNew->name,pNew->num,pNew->classes);
        fscanf(fp,"%s %s %s",pNew->score[0],pNew->score[1],pNew->score[2]); 
        for(i=0;i<3;i++)//字串轉換為整數 
        {   
            num=0;
            for(j=0;pNew->score[i][j];j++)
                num=num*10+pNew->score[i][j]-'0';   
            sum=sum+num;    
        }   
        pNew->aver=sum*1.0/3;
        if(feof(fp))
            break;
        pEnd->next=pNew;
        pEnd=pNew;
        iCound++;
    }
    pEnd->next=NULL;
    fclose(fp);
    return pHead;
}
  1. 檔案的寫
void save_3(struct student *pHead)
{
    FILE *fp;
    char filename[100]= N;  
    fp=fopen(filename,"wt");
    if(fp==NULL)
    {
        printf("不能開啟檔案");
        exit(1); 
    }
    pHead=pHead->next;
    while(pHead)
    {
        fprintf(fp,"%s %s %s ",pHead->name,pHead->num,pHead->classes);
        fprintf(fp,"%s %s %s\n",pHead->score[0],pHead->score[1],pHead->score[2]);
        pHead=pHead->next;
    }
    fclose(fp);
}
  1. 使用引數多次呼叫排序函式
void output_2(struct student *pHead,int a)//a控制排序依據 //方式2輸出 
{
    int i,j,flag;
    struct student *pj_1,*pj,*pj_h;
    for(i=0;i<iCound-1;i++)
        for(j=0,pj=pHead,flag=0;j<iCound-i-1;j++) 
        {
            if(flag==0)
            {
                pj_1=pj;
                pj=pj->next;
                pj_h=pj->next;
            }
            if(flag==1)
            {
                pj_1=pj_1->next;
                pj_h=pj->next;
            }   
            flag=0;
            if(a==2&&(pj->aver)<(pj_h->aver))
            {
                exchange(pj,pj_h,pj_1);
                flag=1; 
            }
            else if(a==3&&strcmp(pj->num,pj_h->num)==1) 
            {
                exchange(pj,pj_h,pj_1);
                flag=1; 
            }
            else if(a==4&&strcmp(pj->classes,pj_h->classes)==1)
            {
                exchange(pj,pj_h,pj_1);
                flag=1;
            }
            else if(a==5&&strcmp(pj->name,pj_h->name)==1)
            {
                exchange(pj,pj_h,pj_1);
                flag=1;
            }
        }
    output_t(pHead);        
} 

5. 原始碼

這個程式碼中我使用的是cfree建立工程檔案的方法
其他編譯器不知道是否可以正常執行。
如果要執行檢視結果,推薦使用c free
程式碼地址

學生資訊管理3.0版

這個版本具體可以看我的上一篇部落格。

1. 新增功能

  1. 位運算對密碼的加密
  2. 分為三個登入端,學生,教師,管理員

2.原始碼

這個程式碼中我使用的是cfree建立工程檔案的方法
其他編譯器不知道是否可以正常執行。
如果要執行檢視結果,推薦使用c free
程式碼地址

學生資訊管理4.0版

1. 新增功能

  1. 從管理一個班變為管理五個班
  2. 對學生資訊的資料結構進行改進,將儲存成績從二維陣列改為連結串列,即十字連結串列。(老師加的要求)

2. 函式框架

這裡寫圖片描述

3. 函式呼叫關係圖

這裡寫圖片描述

4. 部分功能函式

  1. 學生資訊結構節點的定義
struct score//分數 
{
    char date[20];
    int No;
    struct score *next;
};
struct student
{
    int No; //排名 
    char name[20];//姓名 
    char num[20];//學號 
    char classes[20];//班級 
    struct score *ScorepHead;//分數 
    double aver;//平均分
    struct student *next;//指標域 
}; 
struct student *StupHead[6]; //5個班的頭節點 
int iCound[6];//5個班的節點數量
  1. 學生資訊連結串列的建立(檔案讀入)
struct student *Finput(char filename[]) 
{

    FILE *fp;
    struct student *pHead=NULL,*pEnd,*pNew;
    int sum=0,i,j,num;
    iCound[filename[5]-'0'-1]=0;
    pEnd=pHead=(struct student *)malloc(sizeof(struct student));
    fp=fopen(filename,"rt");
    if(fp==NULL)
    {
        printf("不能開啟檔案");
        exit(1); 
    }
    char a[20];//暫存資訊 
    fscanf(fp,"%s",a);

    int temp[Classnum]={0};//暫存科目數量 
    while(!feof(fp))
    {
        sum=0;
        pNew=(struct student *)malloc(sizeof(struct student));
        strcpy(pNew->name,a);
        fscanf(fp,"%s %s",pNew->num,pNew->classes);


        struct score *spEnd,*spNew,*spt; //錄入科目成績 
        pNew->ScorepHead=spEnd=(struct score *)malloc(sizeof(struct score));
        while(1)
        {
            spNew=(struct score *)malloc(sizeof(struct score));
            fscanf(fp,"%s",a);
            if(a[0]<'0'||a[0]>'9'||feof(fp))
                break;
            strcpy(spNew->date,a);
            spEnd->next=spNew;
            spEnd=spNew;    
        }
        spEnd->next=NULL;
        int k;
        for(k=0,spt=pNew->ScorepHead->next;spt!=NULL;spt=spt->next,k++)//字串轉整數 
        {   
            for(j=0,num=0;spt->date[j];j++)
                num=num*10+spt->date[j]-'0';    
            sum=sum+num;
            temp[k]++;  
        } 
        pNew->aver=sum/k;   

        iCound[filename[5]-'0'-1]++;
        pEnd->next=pNew;
        pEnd=pNew;
    }
    for(i=0;i<Classnum;i++)
            subject[filename[5]-'0'-1][i]=temp[i]; 
    pEnd->next=NULL;
    fclose(fp);
    return pHead;
}

5. 原始碼

這個程式碼中我使用的是cfree建立工程檔案的方法
其他編譯器不知道是否可以正常執行。
如果要執行檢視結果,推薦使用c free
程式碼地址

後續可以進行的優化

1.梳理函式呼叫關係,讓程式碼更加清晰簡潔

2.使用MFc或者Esay_x製作圖形化介面。