第一次在CSDN上发文章,本人BNUZ大学生萌新,水平不足,还请各位多多指教!
环境Windows 10 20H2 + .NET Framework 4.7.2 + Visual Studio 2019
项目:基于C#的Windows窗体应用(.NET Framework)
- 理解面向对象的概念,掌握c#定义类和创建对象的方法
- 区分类的不同数据成员,常量、字段和属性的定义,控制其访问性
- 掌握类的方法的声明和调用,理解各种参数传值方式
- 熟悉Window系统的基本操作
- 认真阅读本章相关内容,尤其是案例
- 实验前进行程序设计,完成源程序的编写任务
- 反复操作,直到不需要参考资料、能熟练操作为止。
设计一个Windows应用程序,在该程序中定义一个学生类和班级类,以处理每个学生的学号,姓名,语文,英语,数学三科的期末考试成绩。要求:
- 能查询每个学生的总成绩
- 能显示全班前三名的名单
- 能显示的单科成绩最高分和不及格的学生名单。
- 能统计全班学生的评价成绩
- 能显示各科的成绩在不同分数段的学生人数百分比
- 设计一个Student类,包含字段(学号,姓名,语文成绩,数学成绩,英语成绩)和属性(总成绩)
- 定义一个StudentList 班级类,包含一个Student类型的数组(用于保存全部学生的信息)以及若干个实现以上要求的方法。
- 设计一个界面,实现用户能输入一个学生的信息,当单击”添加”按钮时把这些信息添加到班级对象的学生数组中。当单击“完成”按钮时调用班级类的方法来显示所要求的统计结果。当学生在输入框中输入学生的学号后,单击“查询”按钮时显示该学生的总成绩。
界面组件详情:
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 WindowsFormsApp2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//实例化一个StudentList类
StudentList studentList = new StudentList();
private void btnAdd_Click(object sender, EventArgs e)
{
//checkData表示检查数据是否符合要求
bool checkData = true;
if (txtSname.Text.Length == 0 || txtSname.Text.Length > 5)
{
MessageBox.Show("名字长度必须在五个字以内!");
checkData = false;
}
if (txtSno.Text.Length != 5)
{
MessageBox.Show("学号必须为五位数!");
checkData = false;
}
int chinese = Convert.ToInt32(txtChinese.Text);
int math = Convert.ToInt32(txtMath.Text);
int english = Convert.ToInt32(txtEnglish.Text);
if (chinese > 100 || chinese < 0 || math > 100
|| math < 0 || english > 100 || english < 0)
{
MessageBox.Show("分数的范围为0-100!");
checkData = false;
}
if (checkData)
{
//若符合要求,添加学生
studentList.Add(txtSname.Text, txtSno.Text, chinese, math, english);
lblisAdded.Text = "(添加成功)";
}
else
lblisAdded.Text = "(添加失败)";
}
private void btnSearch_Click(object sender, EventArgs e)
{
bool checkData = true;
if (txtSearchbySno.Text.Length != 5)
{
MessageBox.Show("学号必须为五位数!");
checkData = false;
}
if (checkData)
{
//调用StudentList类里的Search()方法,查找学生,返回Student类型
Student result = studentList.Search(txtSearchbySno.Text);
if (result == null)
lblSearchResult.Text = "未找到该学生!";
else
{
lblSearchResult.Text = "该学生为:" + result.Sname
+ "n总成绩为:" + result.GetTotalMark();
}
}
}
private void btnAnalyze_Click(object sender, EventArgs e)
{
//调用StudentList类里的相关方法,完成成绩分析
if (studentList.Count >= 3)
{
lblAnalysis.Text = studentList.ShowTopThreeStu() + studentList.ShowTopSubjectStu()
+ studentList.ShowFailedStu() + studentList.ShowAverage() + studentList.ShowPercentage();
}
else
MessageBox.Show("学生人数>=3才可使用此功能!");
}
}
//定义学生类
public class Student
{
private string sname; //学生姓名
private string sno; //学号
private int chinese; //语文成绩
private int math; //数学成绩
private int english; //英语成绩
//有参构造方法
public Student(string sname, string sno, int chinese, int math, int english)
{
this.sname = sname;
this.sno = sno;
this.chinese = chinese;
this.math = math;
this.english = english;
}
//对应数据域get和set方法
public string Sname { get => sname; set => sname = value; }
public string Sno { get => sno; set => sno = value; }
public int Chinese { get => chinese; set => chinese = value; }
public int Math { get => math; set => math = value; }
public int English { get => english; set => english = value; }
//计算总成绩的方法
public int GetTotalMark()
{
return chinese + math + english;
}
}
//定义学生列表类,用于实现对学生对象的操作
public class StudentList
{
//定义学生类数组students,一个班级上限为50人
private Student[] students = new Student[50];
private int count = 0; //计数器,统计学生个数
//计数器count的get和set方法
public int Count { get => count; set => count = value; }
//添加学生
public void Add(string sname, string sno, int chinese, int math, int english)
{
students[Count] = new Student(sname, sno, chinese, math, english);
Count++;
}
//查找学生
public Student Search(string sno)
{
for (int i = 0; i < Count; i++)
if (students[i].Sno == sno)
return students[i];
return null;
}
//统计班级总成绩排名前三的学生
public string ShowTopThreeStu()
{
Student temp;
//冒泡排序
for (int i = 0; i < Count - 1; i++)
for (int j = 0; j < Count - 1 - i; j++)
if (students[j].GetTotalMark() < students[j + 1].GetTotalMark())
{
temp = students[j];
students[j] = students[j + 1];
students[j + 1] = temp;
}
return "总成绩前三名:" + students[0].Sname + " "
+ students[1].Sname + " " + students[2].Sname + "n";
}
//统计单科最高分的获得者
public string ShowTopSubjectStu()
{
int maxchinese = 0, maxmath = 0, maxenglish = 0;
string maxchinesestu = "", maxmathstu = "", maxenglishstu = "";
for (int i = 0; i < Count; i++)
{
if (maxchinese < students[i].Chinese)
{
maxchinese = students[i].Chinese;
maxchinesestu = students[i].Sname;
}
if (maxmath < students[i].Math)
{
maxmath = students[i].Math;
maxmathstu = students[i].Sname;
}
if (maxenglish < students[i].English)
{
maxenglish = students[i].English;
maxenglishstu = students[i].Sname;
}
}
return "单科最高分获得者:语文:" + maxchinesestu + ",数学:"
+ maxmathstu + ",英语:" + maxenglishstu + "n";
}
//统计单科不及格的学生
public string ShowFailedStu()
{
//用了StringBuilder,可变长度字符串
StringBuilder chinesefailed = new StringBuilder();
StringBuilder mathfailed = new StringBuilder();
StringBuilder englishfailed = new StringBuilder();
for (int i = 0; i < Count; i++)
{
if (students[i].Chinese < 60)
chinesefailed.Append(students[i].Sname + " ");
if (students[i].Math < 60)
mathfailed.Append(students[i].Sname + " ");
if (students[i].English < 60)
englishfailed.Append(students[i].Sname + " ");
}
return "语文不及格:" + chinesefailed.ToString()
+ "n数学不及格:" + mathfailed.ToString()
+ "n英语不及格:" + englishfailed.ToString() + "n";
}
//计算平均分
public string ShowAverage()
{
int sum = 0;
for (int i = 0; i < Count; i++)
sum += students[i].GetTotalMark();
double avg = sum / Count;
return "全班总成绩平均分为:" + avg.ToString() + "n";
}
//计算单科各个分数段的占比
//分为5个分数段,90+, 80+, 70+, 60+,不及格
//呃....写得有点阴间
public string ShowPercentage()
{
StringBuilder result = new StringBuilder();
//这些都是统计器,不同分数段的
int count90 = 0, count80 = 0, count70 = 0, count60 = 0, countfailed = 0;
for(int i = 0; i < count; i ++)
{
if (students[i].Chinese >= 90)
count90++;
else if (students[i].Chinese >= 80)
count80++;
else if (students[i].Chinese >= 70)
count70++;
else if (students[i].Chinese >= 60)
count60++;
else
countfailed++;
}
result.Append("语文分数段百分比:90+:" + (100 * count90 / count).ToString() + "%,80+:"
+ (100 * count80 / count).ToString() + "%,70+:" + (100 * count70 / count).ToString()
+ "%,60+:" + (100 * count60 / count).ToString() + "%,不及格:"
+ (100 * countfailed / count).ToString() + "%n");
count90 = 0; count80 = 0; count70 = 0; count60 = 0; countfailed = 0;
for (int i = 0; i < count; i++)
{
if (students[i].Math >= 90)
count90++;
else if (students[i].Math >= 80)
count80++;
else if (students[i].Math >= 70)
count70++;
else if (students[i].Math >= 60)
count60++;
else
countfailed++;
}
result.Append("数学分数段百分比:90+:" + (100 * count90 / count).ToString() + "%,80+:"
+ (100 * count80 / count).ToString() + "%,70+:" + (100 * count70 / count).ToString()
+ "%,60+:" + (100 * count60 / count).ToString() + "%,不及格:"
+ (100 * countfailed / count).ToString() + "%n");
count90 = 0; count80 = 0; count70 = 0; count60 = 0; countfailed = 0;
for (int i = 0; i < count; i++)
{
if (students[i].English >= 90)
count90++;
else if (students[i].English >= 80)
count80++;
else if (students[i].English >= 70)
count70++;
else if (students[i].English >= 60)
count60++;
else
countfailed++;
}
result.Append("英语分数段百分比:90+:" + (100 * count90 / count).ToString() + "%,80+:"
+ (100 * count80 / count).ToString() + "%,70+:" + (100 * count70 / count).ToString()
+ "%,60+:" + (100 * count60 / count).ToString() + "%,不及格:"
+ (100 * countfailed / count).ToString() + "%n");
return result.ToString();
}
}
}
运行结果
添加学生(btnAdd),若成功添加则显示状态(lblisAdded)
依据学号查找学生(btnSearch),并反馈结果(lblSearchResult)
一些输入约束(分数,学号,姓名)(checkData,MessageBox弹出窗口)
用Excel拟定测试数据
依次把数据输入到程序里去,运行分析(btnAnalyze),检查结果(lblAnalysis)
- 因为是新手,个人觉得这个程序有点冗长,应该是有很大优化的空间的
- 结合现实,单科最高分有可能存在多个学生同分数的情况,本程序没有把这种情况考虑进去
- 全班总成绩平均分只有整数部分,若要加上小数部分可Convert.ToDouble(),百分比那里也是



