精華區beta NTUE-CS99 關於我們 聯絡資訊
題目: 1. 設計一個學生成績資料型別,紀錄姓名、學號 2. 承上題,增加記錄英、數、C++成績、計算平均功能 3. 承上題,增加排序功能 想法參考: 1. 先建立一個類別(class) ┌────┐ │Student │ ├────┤ │姓名  │ │學號  │ │英文  │ │數學  │ │吸佳佳 │ │平均  │ ├────┤ │算平均 │ └────┘ 語法長的像下面降 class stu{ public: char name[9]; int no; float eng; float math; float cpp; float ave; void cave(){ ave=(eng+math+cpp)/3; } }; 這裡面很明顯有name,no,eng,math,cpp,ave六個屬性,cave是計算平均的方法(函數) 上面char name[9]; 代表name可以放8個英文字or4個中文字 因為字串最後面要預留\0的位子 所以是9-1=8個英文字的空間 2. 接下來我們需要一個輸入和輸出的介面 當然就是寫在main裡面(註1)啦 int main(){ stu grade; printf("請依序輸入 學號 姓名 英文 數學 C++\n"); scanf("%d %s %f %f %f", &grade.no, grade.name, &grade.eng, &grade.math, &grade.cpp); grade.cave(); printf("%4s %8s %6s %6s %6s %6s\n","座號","姓名","英文","數學","C++","平均"); printf("%4d %8s %6.2f %6.2f %6.2f %6.2f\n", grade.no, grade.name, grade.eng, grade.math, grade.cpp, grade.ave); } printf 和 scanf 用法請看上一次作業參考(8518篇)or投影片(8498篇) 註1 一般來說 程式碼的編寫順序應該像降 #include區 class 物件區 函數/副程式區 main 主程式區 當然你可以把main寫在副程式區前面 但是還是需要先宣告(請參考課本p6-7) 所以最好的順序是像上面降 以免麻煩 記得程式一定要有main這個主程式 不然系統不知道要從哪邊開始執行 3. 加上排序功能 要排序 當然資料要超過1筆啦 修改第2部分的程式碼 stu grade; 改成 int n; printf("請輸入有幾個學生:\n"); scanf("%d",&n); stu *grade=new stu[n]; 程式的最後面要加上 delete [] grade; 抱歉.. 下面的方法學校裝的visual c++板本跟課本的2005版都不能用                                             ꄊconst int s=n;                               stu grade[s];                                                                      const是啥勒                                                                      ꄊconst是從英文constant來的 代表常數的意思 也就是說這個東西的內容不會變                                           const int s=10; 就是說定義一個常數s=10 他永遠都等於10 就好像π=3.1415926一樣                                        為什麼要用const呢                                                                      上學期在寫陣列(註2)的時候 visual c++ 不能用變數來定義陣列大小                                                有一個替代的方案 另外定義一個常數s=變數n 那上面的陣列大小就不是用變數定義的啦 註2 陣列 假設現在有五筆資料 你可以設五個變數 a1 a2 a3 a4 a5 然後用程式去處理這五個變數 今天老師發現大家都考不及格 要幫大家的分數用10*開根號原始成績 那就要寫 a1=10*sqrt(a1); a2=10*sqrt(a2); a3=10*sqrt(a3); a4=10*sqrt(a4); a5=10*sqrt(a5); 那如果成績有100筆的話呢 程式裡面有一個東西叫做陣列 配合他的好幫手"迴圈" 上面的程式就可以改寫成 for(int i=1;i<=5;i++){ a[i]=10*sqrt(a[i]); } 一般變數的語法 陣列的語法 定義 int a; int a[10]; 改變數值 a=12; a[3]=12; 讀取數值 x=a; x=a[5]; 其實也可以把陣列想成數列 → a[第幾項] 回到第3部分 然後要做排序 在輸出的部分(第2部分兩個printf前面)前面加上 stu temp; for(int i=n-1;i>0;i--){ for(int j=0;j<i;j++){ if(grade[j].ave < grade[j+1].ave){ temp=grade[j]; grade[j]=grade[j+1]; grade[j+1]=temp; } } } 這裡會用到氣泡排序法(請參考課本p7-9~p7-12) 氣泡排序法也有另外一種寫法(上面是課本上的寫法 這個是我自己的寫法) stu temp; for(int i=n-1;i>0;i--){ for(int j=0;j<i;j++){ if(grade[j].ave < grade[j+1].ave){ temp=grade[j]; grade[j]=grade[j+1]; grade[j+1]=temp; } } } 氣泡排序法的精神在每一次確定一個最高/最大的 第一次迴圈兩兩交換後決定第一名 第二次決定第二名 ...以此類推 課本的方法是固定某一個 然後拿其他人跟他比 交換把大的放前面 我的方法是每次找左右比 交換把大的放前面 兩個方法都可以 不懂泡沫排序法的人可以找我 我會用撲克牌解釋給你聽 最後輸出的部份 兩個printf改成 printf("\n%4s %8s %6s %6s %6s %6s","座號","姓名","數學","英文","程設","平均"); for(int i=0;i<n;i++){ printf("%4d %8s %6.2f %6.2f %6.2f %6.2f\n",grade[i].no, grade[i].name, grade[i].math, grade[i].eng,grade[i].cpp,grade[i].ave ); } OK 完成了 感謝珈瑀大大指正 第二部份65行 printf("請依序輸入 學號 姓名 英文 數學 C++\n"); scanf("%d %s %f %f %f", &grade.no, grade.name, &grade.eng, &grade,math, &grade.cpp); 應該是 printf("請依序輸入 學號 姓名 英文 數學 C++\n"); scanf("%d %s %f %f %f", &grade.no, grade.name, &grade.eng, &grade.math, &grade.cpp); 另外排序的部份 之前我用陣列紀錄順序的方法太複雜了 物件可以直接交換 直接用新的方法吧 感謝中意大大 108行 const int s=n; stu grade[n]; 應該是 stu grade[s]; 才對 但是這個方法 Visual C++還是不能用 所以只能用記憶體的方法 宣告 stu *grade=new stu[n]; 使用 grade[i].math=59.99; 記得程式最後面要清除記憶體 delete [] grade; -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 210.240.186.34