《程序設計基礎》課程設計報告
設計題目 | 學生成績管理系統 |
學生姓名 | |
學生班級 | |
學生學號 | |
指導教師 |
完成時間 :12 月 25日
目錄
1.設計目的與要求
2.系統需求分析
3.總體設計
4、詳細設計
5、調試與測試
6、總結與體會
設計目的:學生成績管理系統是為了在這個信息時代高速發展的今天,通過計算機取代傳統的紙張記錄人力處理的方法,提高處理學生信息的速度,提高工作效率,并且通過保證軟件的正常運行即保證了工作的正常運行,減少人力工作中可能出現的失誤,不僅保證了工作的執行力度而且還提高了工作的準確度、效率。
設計要求:熟練掌握運用這個學期學的C語言知識用VISAL C++軟件編寫程序,通過設計這個程序充分考察這個學期的知識是否已經落到實處,進行實踐。在學生成績管理系統中加入足夠數量的功能,保證這個系統的多功能性以保證學生成績管理系統的完善。通過不斷的調整測試,找出系統中的bug,各種語法錯誤和邏輯錯誤,確保這個系統在處理信息的過程中系統不會出現崩潰或信息處理錯誤,導致學生成績導入、處理發生錯誤,或導致信息處理工作無法正常進行。還有重要的是,選擇盡量高效,高利用率的方法來編寫程序,避免使用低級的編程手法來編寫系統,導致不必要的信息處理的繁雜或者較長的程序執行時間。
對于學校來說,每個學期都有大量的考試,有大量的學生,有大量的成績信息進行處理,如若使用人工處理的方法,這龐大的信息量和信息處理難度是非常可怕的。因此,我們應該借用計算機來實現學生成績管理,實現工作準確度的提高和效率的提升。在學生管理系統中,對學生成績的管理至少應該包括學生數據的輸入、輸出、查找、處理、保存等功能。為了保證程序的可讀性,在Visal C++里用C語言應該使用對各單獨的函數和單獨的文件將每個功能都分開,以滿足復雜的功能的實現。為了保證不浪費有限的空間,應該使用鏈表代替有可能浪費大量空間的數組。為了實現數據處理的簡化,應該自定義一個結構體以此來更高效的實現學生信息的輸入輸出調用。
3.總體設計
1)問題分析
學生成績管理系統首先應該實現的是用戶通過系統來輸入學生的各種數據,所以需要用戶首先輸入信息,所以需要數據輸入功能。其次是對信息的處理,應該要對信息進行備份保存,所以需要保存至文本文件功能。再者就是對信息的處理了,對總體學生的各種數據進行比較,處理,匯總,輸出,所以需要求平均分,最高分,最低分數據搜索,學生數據輸出。用戶需要的是盡量高效的處理效率,盡量完善的功能,還有適當的系統占用空間大小,所以應當使用恰當的數據儲存方法,數據調用處理方法。
2)設計思路
(1)顯示主菜單界面,包括輸入學生的數據記錄、保存數據記錄、輸出最高分和最低分、求平均分、查找指定的學生信息、輸出學生的成績等級、輸出所有學生的信息還有退出功能。
(2)每項功能之間都是獨立的,所以應該是用多文件多函數結構,通過在主函數中調用其他函數來實現功能的使用。
(3)學生的信息包括了姓名、學號、各科成績,故選擇定義結構體來簡化數據的儲存。
(4)因為大部分功能需要對每一個同學的信息進行查看并處理,故使用鏈表來實現信息的儲存、輸出、查看、處理。
(3)程序結構
(1)頭文件
(2)數據結構
(3)函數聲明
班級學生成績管理系統的詳細設計是各個功能的實現,即為每個函數每個功能的設計思路和編程過程。
(1)主函數
主函數是班級學生管理系統的入口函數程序,提供各功能模塊的操作。
首先調用菜單函數呈現給用戶菜單,菜單使用數字來標記各功能,要求用戶通過輸入數字來選擇要實現的功能,如果輸入錯誤,則提示用戶重新輸入,用default實現。用scanf()函數來接收用戶的輸入,用多分支條件語句switch()case…來實現子函數的調用,從而實現各個功能的使用。在實現其中一個函數的調用后用break;跳出分支語句后,詢問用戶是否返回主菜單,要求用戶輸入y或n,如果返回主菜單,則清空之前顯示的數據,如果不返回則要求用戶輸入像要實現的功能所代表的數字,如果輸入錯誤,則提示用戶重新輸入,這三個分支使用if……else if……else……來實現,語句跳轉用goto命令來實現。
(2)菜單函數
函數名:view 所在文件:view.c
在main函數中調用,所有功能在函數內部完成,無需返回值,定義為void類型。
菜單用在告知用戶本系統的功能,一一列出八種功能并用不同的數字代表。
(3)數據輸入函數
函數:input 所在文件:input.c
在main函數中調用,所有功能在函數內部完成,但需要返回鏈表的表頭,定義為struct stu*類型。
此函數要求用戶用鍵盤輸入,scanf語句來接收數據,用以上給出的結構體類型struct stu來儲存。創建鏈表,創建head,p,q三個結構體類型指針,head為表頭,
(4)保存至文本文件函數
函數:save 所在文件:save.c
在main函數中調用,所有功能在函數內部完成,無需返回值,定義為void類型。
以形參接收鏈表的表頭,定義一個file類型的文件指針fp,用fopen()函數以只寫方式打開文本文件,將fp指向指定的文本文件,從鏈表開始將每一個數據用fprintf()函數逐一寫入文本文件,當一個學生的所有數據全部輸入完,指針指向下一個學生的數據,直到指針指向空停止,此處使用循環結構do……while……。全部數據輸入完畢,使用fclose()函數關閉文本文件。
(5)輸出最高分最低分函數
函數:compare 所在文件:compare.c
在main函數中調用,所有功能在函數內部完成,無需返回值,定義為void類型。
此函數需要輸出所有科目和總分的最高分,故定義了mathmax,mathmin,englishmax,englishmin,computermax,computermin,totalmax,totalmin。運用if語句,將每一個數據與max和min比較,若該數據比max大則取代max,若比min小則取代min。
(6)輸出平均數函數
函數:average 所在文件:average.c
在main函數中調用,所有功能在函數內部完成,無需返回值,定義為void類型。
用do……while……語句來實現所有學生數學,英語,計算機成績還有總分的相加,運用+=符號。并在定義了count,放在其中一個科目的do……while……語句中,每運行一次就自加一次,最后得出學生總人數。然后將得到的所有學生的數學成績的總和、英語成績的總和、計算機成績的總和總分的總和在輸出的前均除以count,輸出各科平均分。
(7)查找指定學生信息函數
函數:search 所在文件:search.c
在main函數中調用,所有功能在函數內部完成,無需返回值,定義為void類型。
通過鏈表,使指針逐一指向每個學生的信息,并且取其中的學號來與用戶輸入的n作對比,用do…while…語句來控制這個比較的過程,用if語句來實現當學生的學號等于用戶需要查找的那個的時候先輸出那個學生的信息,再用return;結束search函數的調用返回主函數。
(8)輸出所有學生信息函數
函數:output 所在文件:output.c
main函數中調用,所有功能在函數內部完成,無需返回值,定義為void類型
同樣用鏈表來調用學生的數據,當一個學生的數據全部輸出完之后,指針指向下一個學生,直到指針指向空的節點結束output函數的調用。
(9)學生等級函數
函數:level 所在文件:level.c
main函數中調用,所有功能在函數內部完成,無需返回值,定義為void類型。
同樣使用鏈表,但不同的是每一塊求等級的語句前需要將 p指向表頭head,因為執行完每一塊求等級的語句之后,p會停留在指向空,這樣如果直接再去當做表頭來進行下面的語句中的數據調用,明顯屬不合理的,所以每次都要將p重新指向表頭。并運用if…else if…else if…else多分支語句來篩選學生成績并按照成績高低來決定哪個等級的人數加一。
(10)reinput函數
函數:reinput 所在文件:reinput.c
函數:level 所在文件:level.c
為了優化系統原來不能重復輸入學生數據,所以添加了一個重復輸入的函數,在第一次輸入數據,input函數執行時,先創建鏈表。在重復添加數據時,則執行reinput函數,在input函數創建的鏈表后,在最后一個結點的后面重新接入數據,輸入數據,儲存數據。
(11)自定義頭文件head.h
用于連接各文件個函數,在頭文件中定義結構體數組以便讓所有的文件、函數都能隨意調用,全局定義各種函數以便主函數調用。
(1)一開始不會使用鏈表,先使用數組來進行處理,例如主函數是這樣的:
使用數組info[]來實現數據處理
后來改成了鏈表的形式,如:
從input函數那里接收了表頭,傳遞給各函數,在各函數內部調用鏈表進行數據處理。
當所用到的知識比較復雜的時候,可以先用簡單的只是去實現系統基本功能,語句的書寫,將系統的大體結構完成的時候再使用復雜的手法來優化系統,這樣不易出錯。
(2)鏈表的創建
(3)鏈表的調用
以求數學最高分為例
從表頭開始調用表頭指向的第一個節點中的數學成績的數據進行處理,完成后將指針移向下一個節點,繼續重復,并運用do······while語句來控制循環直到指針指向空。
(4)鏈表的研究
創建了一個小的系統來研究鏈表,因為在學生成績管理系統中研究不方便,故做了一個小的系統,基于老師的代碼,研究鏈表的創建和調用
(5)寫入文本文件
第一步:
第二步:打開文件
第三步:數據寫入
第四步:關閉文件
(6)函數返回值為指針類型和指針和指向函數的指針的區別
以input函數為例:
函數返回值為指針類型:struct stu *input()
指向函數的指針:struct stu( *input)()
(7)在獲得最大最小值之前要先定義并初始化變量max和min
max應該初始化為0以保證數據能比max的初始值大以取代其初始值。
但min的初始值不應為0因為如此min的值永遠是最小的,數據不符合if里面的篩選條件p->(某數據)<min,所以應該初始化為min=101。
(8)在把數據寫入某個指定文件時,如果指定位置為E:/system/student,它不會被放在E盤的system文件夾中的student.txt文件中,而是在E盤中創建了以下的文本文件。
(9)優化數據的類型,因為計算平均分如果將平均分定義為int,會丟失部分數據,故將其保留小數點后兩位以float類型輸出。
(10)優化,要求用戶必須先輸入數據再執行其他功能。
原來:
優化后:
(11)驗證每個函數,每個功能是否能正常運行
0:退出系統
1:輸入學生的數據記錄
2:保存數據記錄
3:輸出最高分和最低分
4:輸出平均分
5:查找指定學生的信息
6:學生等級
7:輸出所有學生的信息
(12) 在查找信息時,如果輸入錯誤,在重新輸入學號后,會引起系統崩潰,其實是在判斷輸入之前,系統將所有的學號先檢查了一遍,才判斷出輸入錯誤,此時p指向了null,此時繼續從p開始查找,肯定會引起崩潰。所以將表頭保留,每次查找之前,都先將p指向表頭,避免錯誤。
原來:
改正:
(13)在輸入數據之前,進行其他功能的操作是沒有任何意義的,所以在執行其他功能之前,先判斷有無先輸入數據。
(14)為了能夠反復輸入數據,添加了一個reinput函數,在input函數,第一次輸入的數據后,進行數據的添加。
通過這次設計一個系統讓我學到了很多,程序設計的思維,學會從用戶體驗出發,設想用戶的需求,從而將系統所應該具有的功能一一設計出。通過這種方式我能更好的實現課堂知識的實踐,將課堂上的知識點進行查缺補漏。這次的設計老師還要求我們運用沒有學過的鏈表、文件流等內容,這更考驗我們的自學能力,通過老師提供的ppt和提供的系統作范例,研究出了如何創建并使用鏈表,還有如何打開、寫入、關閉文件,并且教給不會的同學,以此既幫助了對方,也幫助了我加深對知識點的理解和發現自己的不足。因為這個系統包含的內容比較多,容易出現大量的錯誤,這讓我學會了認真仔細的注意查看每一行代碼,查缺補漏,不斷的調試,發現系統的錯誤并改正。
歡迎光臨 (http://www.zg4o1577.cn/bbs/) | Powered by Discuz! X3.1 |