題目:
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