老师要求:能查询每个学生的总成绩、显示前三名成绩、单科成绩最高分和不及格的学生名单、全班平均成绩、各科成绩在不同分数段的学生人数百分比。
第一次用C#,写的比较糙,但总的来说还是学到不少的:
1.学会了Windows窗体的建立,基本组件的添加,组件属性的获取(如果在当前窗体下就是this.组件名字.组件属性:this.Grades.Text)、点击按钮事件的编写;
2.C#基本语句,面向对象的编程的思想;
3.老师要求不用数据库,直接把成绩写到类里,这个地方纠结了好久,我的实现方法是新建一个Student类,一个Class类,班级类里包含一个student类的数组,和其他实现上述结果的方法。
界面1:第一个窗体应该是主窗体,我发现主窗体里的类成员、方法,在后面新建的窗体里是可以直接访问的,所以我把学生类和班级类创建在这个CS文件里。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Text1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button5_Click(object sender, EventArgs e)
{
}
private void button6_Click(object sender, EventArgs e)
{
Form2 myForm = new Form2();//弹出新窗体
myForm.ShowDialog();
}
}
}
public class FormStudent//创建学生类
{
public string studentsName;//学生姓名
public int Number;//学号
public int Chinese;//语文成绩
public int English;//英语成绩
public int Math;//数学成绩
public int SCORE;//总分
}
public class Class//班级类
{
public FormStudent[] students { get; set; }//一个名字为students的由FormStudent类型组成的数组
public float EnglishYouxiu = 0;//这里是一系列记录分数分布的变量,初始值为0
public float EnglishJige = 0;
public float EnglishBujige = 0;
public int EnopassNumber = 999;//这个用来经过排序后记录第一个没有通过的学生序号
public float MathYouxiu = 0;
public float MathJige = 0;
public float MathBujige = 0;
public int MnopassNumber = 999;
public float ChineseYouxiu = 0;
public float ChineseJige = 0;
public float ChineseBujige = 0;
public int CnopassNumber = 999;
public void three(FormStudent[] studentscore)//冒泡排序获得前三名成绩
{
int length = 3;
if(studentscore.Length>2)
{
length = studentscore.Length;
}
for (int i = 0; i < 3; i++)
{
for (int j = (length - 3); j >= 0; j--)
{
if (studentscore[j].SCORE < studentscore[j + 1].SCORE)
{
FormStudent st = studentscore[j];
studentscore[j] = studentscore[j + 1];
studentscore[j + 1] = st;
}
}
}
}
public float Average(FormStudent[] studentscore, int m)//求均分
{
int Fullscore = 0;
for (int q = 0; q < m; q++)
{
Fullscore = Fullscore + studentscore[q].SCORE;
}
float ave = Fullscore / m;
return ave;
}
public int EnglishBest(FormStudent[] studentscore)//英语最高成绩
{
int k = 0;
int score = studentscore[0].English;
for (int i = 0; i < studentscore.Length - 1; i++)
{
if (studentscore[k].English < studentscore[i].English)
{
k = i;
score = studentscore[i].English;
}
}
return score;
}
public int ChineseBest(FormStudent[] studentscore)//语文最高成绩
{
int k = 0;
int score = studentscore[0].Chinese;
for (int i = 0; i < studentscore.Length - 1; i++)
{
if (studentscore[k].Chinese < studentscore[i].Chinese)
{
k = i;
score = studentscore[i].Chinese;
}
}
return score;
}
public int MathBest(FormStudent[] studentscore)//数学最高成绩
{
int k = 0;
int score = studentscore[0].Math;
for (int i = 0; i < studentscore.Length - 1; i++)
{
if (studentscore[k].Math < studentscore[i].Math)
{
k = i;
score = studentscore[i].Math;
}
}
return score;
}
public FormStudent[] EnglishGrades(FormStudent[] score)//英语成绩分布
{
for (int i = 0; i < score.Length; i++)
{
for (int j = (score.Length - 3); j >= 0; j--)
{
if (score[j].English < score[j + 1].English)
{
FormStudent st = score[j];
score[j] = score[j + 1];
score[j + 1] = st;
}
}
}
float Youxiu = 0;
float Jige = 0;
float Bujige = 0;
bool x = true;//设置M的标志符,意义在于判断是不是已经记录过第一个不及格的人序号,只用记录第一个序号就可以。
int m = score.Length;//记录不及格第一个人的角标,设初始值为数组长度,如果全部及格,比如4个人长度为4 A[4]一定不存在。
for (int i = 0; i < (score.Length - 1) && score[i].Number != 0; i++)
{
if (score[i].English >= 90)
Youxiu++;
else if (score[i].English < 90 && score[i].English >= 60)
Jige++;
else
{
if (x == true)
{
m = i;
x = false;
}
Bujige++;
}
}
EnopassNumber = m;
EnglishYouxiu = Youxiu / (score.Length - 1);
EnglishJige = Jige / (score.Length - 1);
EnglishBujige = Bujige / (score.Length - 1);
return score;//返回已经排序好的数组
}
public FormStudent[] Mathgrades(FormStudent[] score)//数学成绩分布
{
for (int i = 0; i < score.Length; i++)
{
for (int j = (score.Length - 3); j >= 0; j--)
{
if (score[j].Math < score[j + 1].Math)
{
FormStudent st = score[j];
score[j] = score[j + 1];
score[j + 1] = st;
}
}
}
float Youxiu = 0;
float Jige = 0;
float Bujige = 0;
bool x = true;//设置M的标志符
int m = score.Length;//记录不及格第一个人的角标,设初始值为数组长度,比如4个人长度为4 A[4]一定不存在。
for (int i = 0; i < (score.Length - 1) && score[i].Number != 0; i++)
{
if (score[i].Math >= 90)
Youxiu++;
else if (score[i].Math < 90 && score[i].Math >= 60)
Jige++;
else
{
if (x == true)
{
m = i;
x = false;
}
Bujige++;
}
MnopassNumber = m;
}
MathYouxiu = Youxiu / (score.Length - 1);
MathJige = Jige / (score.Length - 1);
MathBujige = Bujige / (score.Length - 1);
return score;
}
public FormStudent[] Chinesegrades(FormStudent[] score)//语文成绩分布
{
for (int i = 0; i < score.Length; i++)
{
for (int j = (score.Length - 3); j >= 0; j--)
{
if (score[j].Chinese < score[j + 1].Chinese)
{
FormStudent st = score[j];
score[j] = score[j + 1];
score[j + 1] = st;
}
}
}
float Youxiu = 0;
float Jige = 0;
float Bujige = 0;
bool x = true;//设置M的标志符
int m = score.Length;//记录不及格第一个人的角标,设初始值为数组长度,比如4个人长度为4 A[4]一定不存在。
for (int i = 0; i < (score.Length - 1)&&score[i].Number!=0; i++)
{
if (score[i].Chinese >= 90)
Youxiu++;
else if (score[i].Chinese < 90 && score[i].Chinese >= 60)
Jige++;
else
{
if (x == true)
{
m = i;
x = false;
}
Bujige++;
}
CnopassNumber = m;
}
ChineseYouxiu = Youxiu / (score.Length - 1);
ChineseJige = Jige / (score.Length - 1);
ChineseBujige = Bujige / (score.Length - 1);
return score;
}
public int Find(FormStudent[] students, string name)//查询按钮
{
for (int i = 0; i < students.Length; i++)
{
if (students[i].studentsName == name)//如果名字匹配,则返回该学生总成绩
return students[i].SCORE;
}
FormStudent Nostudent = new FormStudent();//如果没有该学生,则创建一个空学生,把成绩赋值99999,输出时如果成绩等于99999则说明不存在。
Nostudent.SCORE = 99999;
return Nostudent.SCORE;
}
}
界面2:添加成功反馈
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Text1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
}
public static int txtConvertToInt(string txt) //string转int,这个很重要!!因为输入框里提取出来的是string型的,而我们的成绩记录是int型,百度出来的这个方法,可以把输入框的string转成Int。
{
int result = 0;
bool f = int.TryParse(txt, out result);//百度到这个tryparse()是这样的:int.Parse()是一种类容转换;表示将数字内容的字符串转为int类型
return result;
}
Class A1 = new Class();//新建一个班级类
FormStudent[] S1 = new FormStudent[50];//新建一个长度为的50的班级数组(后来想想好像没必要创建这个,但是已经最后要交作业了要改太麻烦,)
int k = 0;//记录存放了多少人
private void button1_Click(object sender, EventArgs e)//添加按钮事件
{
int ChineseScore = txtConvertToInt(this.Chinese.Text);
int MathScore = txtConvertToInt(this.Math.Text);
int EnglishScore = txtConvertToInt(this.English.Text);//把用户输入的数据全都变成int型
if (ChineseScore>100||MathScore>100||EnglishScore>100)//保证输入的数字在100以内
{
MessageBox.Show("请输入100以内分数", "失败", MessageBoxButtons.OK);//一个简单的弹出框,不用新建,一个函数搞定,参数是这样的(“要显示的内容”,“标题”,OK按钮)
}
else
{
FormStudent KS = new FormStudent();//先新建一个新的学生,并初始化
KS.studentsName = "没有学生信息";
KS.Number = 0;
KS.SCORE = 0;
KS.Math = 0;
KS.Chinese = 0;
KS.English = 0;
for (int tt = k; tt < 50; tt++)//学生数组初始化
{
S1[tt] = KS;
}
FormStudent a;
a = new FormStudent();
a.studentsName = this.StudentsName.Text;
a.Number = txtConvertToInt(this.Number.Text);
a.Chinese = txtConvertToInt(this.Chinese.Text);
a.Math = txtConvertToInt(this.Math.Text);
a.English = txtConvertToInt(this.English.Text);
a.SCORE = a.Chinese + a.Math + a.English;//获取输入框的值
// A1.students[0] = a;//问题应该出在这里 不应该只赋一个值,应该可以循环赋值的!!应该先创建一个学生类型数组,把学生都放进去,然后再创建一个float数组,把每个学生的成绩放进去。然后再用这个float数组调用three函数!
S1[k] = a;
k++;
A1.students = S1;
MessageBox.Show("添加成功", "成功", MessageBoxButtons.OK);
}
StudentsName.Clear();//清空文本,这个应该比较常用
Number.Clear();
Chinese.Clear();
Math.Clear();
English.Clear();
}
private void button2_Click(object sender, EventArgs e)//完成按钮,显示各种需要统计的信息
{
int c = k;//下面这一大串操作都是在处理当记录人数小于3的情况下。因为输出前三名需要前三名的数组里都有对象,如果学生记录少于3的话,会出现空对象,出现BUG,
if (k < 3)
{
k = 2;
}
FormStudent[] Y = new FormStudent[k+1];//保证数组长度就是有效成绩个数,最后一个数据角标是K,数组初始化时应该长度是k+1//这里写错了 应该是K的 ,不过后面代码都按照k+1写的,浪费了一个数组的空间 ,罪过罪过
//FormStudent i= A1.three(Y);
if (c < 3)//这个操作就是记录的人数小于3的话,把空数组全都初始化为0,并且只要人数小于3,就把数组长度定义成3,这样就不影响后面的函数调用了。
{
int i = 0;
FormStudent[] B = new FormStudent[3];
FormStudent Kongstudent = new FormStudent();
Kongstudent.studentsName = "没有学生信息";
Kongstudent.Number = 0;
Kongstudent.SCORE = 0;
Kongstudent.Math = 0;
Kongstudent.Chinese = 0;
Kongstudent.English = 0;
for (; i < 3; i++)
{
if (i < c)
{
B[i] = A1.students[i];
}
else
{
B[i] = Kongstudent;
}
}
Y = B;
}
else //人数大于三,就直接赋给Y数组就好了,所以综上所述,Y数组里要么是存储了小于三个人,里面有空对象,要么是存满了人,数组长度就是人数+1
{
for (int q = 0; q <= c; q++)
{
Y[q] = A1.students[q];
}
}
A1.three(Y);//前三名成绩显示
string strResult;
strResult = "第一名:姓名:" + Y[0].studentsName + ",学号:" + Y[0].Number + ",总分" + Y[0].SCORE;
label29.Text = strResult;
label30.Text= "第二名:姓名:" + Y[1].studentsName + ",学号:" + Y[1].Number + ",总分:" + Y[1].SCORE;
label31.Text = "第三名:姓名:" + Y[2].studentsName + ",学号:" + Y[2].Number + ",总分:" + Y[2].SCORE;
float ave1= A1.Average(Y, k);//均分显示
label32.Text = ave1 + "分";
int Escore = A1.EnglishBest(Y);//英语最高分
label20.Text = Escore + "分";
int CHscore = A1.ChineseBest(Y);//语文最高分
label28.Text = CHscore + "分";
int Mscore = A1.MathBest(Y);//数学最高分
label25.Text = Mscore + "分";
FormStudent[] EPscore = new FormStudent[Y.Length];//英语分布显示和不及格人名显示
EPscore=A1.EnglishGrades(Y);
float EY = A1.EnglishYouxiu*100;
float EJ = A1.EnglishJige * 100;
float EB = A1.EnglishBujige * 100;
label21.Text = "90分以上占" + EY+"%,60-90分占"+EJ+"%,60分以下占"+EB+"%。";
int m = A1.EnopassNumber;
int n = m;
if (m == Y.Length)
{
label22.Text = ": 没有人不及格~";
}
else
{
//FormStudent[] ENG = new FormStudent[Y.Length-m-1];
for (int l = 1; l < Y.Length - m; l++)
{
label22.Text = label22.Text + EPscore[n].studentsName + ",";
n++;
}
}
FormStudent[] MPscore = new FormStudent[Y.Length];//数学分布显示和不及格人名显示
MPscore = A1.Mathgrades(Y);
float MY = A1.MathYouxiu * 100;
float MJ = A1.MathJige * 100;
float MB = A1.MathBujige * 100;
label24.Text = "90分以上占" + MY + "%,60-90分占" + MJ + "%,60分以下占" + MB + "%。";
int f = A1.MnopassNumber;
int p = f;
if (f == Y.Length)
{
label23.Text = ":没有人不及格~";
}
else
{
for (int l = 1; l < Y.Length - f; l++)
{
label23.Text = label23.Text + MPscore[p].studentsName + ",";
p++;
}
}
FormStudent[] CPscore = new FormStudent[Y.Length];//数学分布显示和不及格人名显示
CPscore = A1.Chinesegrades(Y);
float CY = A1.ChineseYouxiu * 100;
float CJ = A1.ChineseJige * 100;
float CB = A1.ChineseBujige * 100;
label27.Text = "90分以上占" + CY + "%,60-90分占" + CJ + "%,60分以下占" + CB + "%。";
int b = A1.CnopassNumber;
int x = b;
if (b == Y.Length)
{
label26.Text = ":没有人不及格~";
}
else
{
for (int l = 1; l < Y.Length - b; l++)
{
label26.Text = label26.Text + CPscore[x].studentsName + ",";
x++;
}
}
}
private void button3_Click(object sender, EventArgs e)//查询按钮
{
if (S1[0] == null)
{
label33.Text = "系统无记录!";
return;
}
else
{
int sc = A1.Find(S1, textBox1.Text);
if (sc == 99999)
{
label33.Text = "无记录!";
}
else
label33.Text = sc + "分";
}
}
}
}
结果界面
给人的锻炼还是很大的,也算初步了解了C#吧,这门课选的真的值了,上面的程序还有很多缺点,比如框架有点乱,计算均分和分数分布应该是可以用一个函数解决的,还有变量设的太多了,为了解决现有的问题不断的设新的变量,整个键盘小字母都快用完了,还有就是成绩、学号等定义应该设计成Private的,再有以后要养成把变量写成英文名的习惯,就这样吧~