学生信息管理系统C++
设计目的
- 使学生进一步理解和掌握课堂上所学的面向对象C++编程知识,巩固和加深学生对C++面向对象课程的基本知识的理解和掌握。
- 掌握C++面向对象编程和程序调试的基本技能,学会利用C++语言进行基本的软件设计,着重提高运用C++面向对象语言解决实际问题的能力。
- 掌握书写程序设计说明文档的能力,使学生学会使用各种计算机资料和查阅有关参考资料解决问题的方法。
具体要求
运用C++语言描述学生类,每一个类应包含数据成员和成员函数。学生的信息包括学号、姓名、性别、班级、高数成绩和英语成绩。注重面向对象程序设计理论知识的理解与实际的动手编程能力,要求学生设计具有继承与派生以及多态性的类,理解面向对象程序设计的核心的概念。
本题目要实现的主要功能如下:
- 建立基类—学生类,数据成员包括学号、姓名、性别;
- 派生类—电信类,新增数据成员有:班级、高数成绩、英语成绩;
- 能够实现对电信类学生信息的录入、修改、查找、排序、删除等功能;
- 能够输出总成绩,即高数和英语两门课的成绩之和;
- 能够对学生信息按高数成绩从高到低进行排序,若高数成绩一样,则按英语成绩排序,若成绩都一样,则按学号进行排序;
- 查找功能支持姓名查找或学号查找
- 若通过动态分配内存的链表或哈希表实现
设计思路
首先数据都是放在类中的,在创建一个结构体进行类与链表的结合使用完成学生信息管理系统。
分别在类与链表结构体中封装对象指针,方便之后形成链表结点对其进行控制。每个功能函数都被封装在链表结构体中,因为需要使用内部的指针,这样比较方便。
我采用的是带头双向链表来实现,这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单了。链表为空时,也会有一个哨兵位的头结点(head),这样我们每次去实现功能的时候,不需要遍历。直接让当前结点指向头结点就可以从头开始依次下去,这也是我比较喜欢的一点。
主函数(main)中是实现这些功能的,但需要先创建一个头结点(空的),然后录入的时候进行结点之间的链接即可。
通过程序主界面写一个菜单,然后通过分支函数switch进行选择。
我认为类和链表的最大难点只需要想通它们之间的指针关系即可,只要理解了指针指向,就可以通过指针实现所有功能。
1. 录入信息
通过for循环可以控制输入的人数,这样想要插入多个学生数据时不用每次都调用Input()函数;在for循环中每次插入数据之前要记得开辟空间,更新指针的指向,录入信息是以后所有功能的基础,如果这步出错,接下来的所有功能实现都会有问题,特别是打印,录入成功但是什么都没打印出来。所以需要尤为注意!
我这里使用的是头插,所以每次扩容之后,都会present->pre=NULL;
插入信息之后,此时就顺势将英语成绩与高数成绩相加算出总分,之后打印直接打印总分会方便很多。
每次输入都会new一个新的类出来,不插入就不用开辟空间,之前也没有定了空间大小,我觉得这也是一种动态开辟的方法,而且简单易懂还很方便。
2.浏览信息
浏览所有信息,就是将所有信息打印出来。因为格式与录入的不一样,我使用了setw函数可以让表格对齐观感更好(注意使用要包头文件iomanip)。将表头信息封装成了display函数,在以后需要打印的时候直接调用,代码会更加整洁。因为链表中不是只有一组数据(一个结点),所以想要打印全部的数据需要使用while循环,然后更新指针指向即可。
3.查找信息
可以通过学生姓名与学生学号进行查找,只需要从头开始present=head;然后当想要查找的姓名或学号等于present-》Name与present->num即可
我将查找的函数封装成了bool类型的(其余都是void),方便接下来的删除和修改模块。因为想要删除和修改也需要在链表中找到相关的数据才可以进行相关操作,需要的时候直接调用就行,很方便。
因为通过姓名和学号是两种不同的方式(但是底层实现都一样),所以我又另外写了一个选择查找通过switch进行不同的选择。
4.删除信息
这个功能模块,说实话不是很难,但是我卡了一天,原因是我的录入模块一开始没有写好,导致它只能删除最后插入的数据,也就是头结点。浪费了我很多时间。所以说录入是基础!!!
当删除的是头结点和不是头结点的有两种处理方式
5.修改信息
通过Check函数查找想要修改的学生学号,找到重新输入即可。
6.排序
通过简单的冒泡排序实现。当当前结点比下一个结点大就交换。
因为按实训要求,需要对学生信息按高数成绩从高到低进行排序,若高数成绩一样,则按英语成绩排序,若成绩都一样,则按学号进行排序。所以直接嵌套就行。
之前我觉得代码太过凌乱了,想着封装成三个函数,然后达到条件之后依次调用,但是真正实现的时候,可以排序成功,但是一旦进入在排序中调用另一个函数,代码就不接着往下跑了,终止main函数中的循环了。我觉得是因为代码嵌套程度太高程序奔溃了,所以我就按一个函数的方式写了。虽然看着有些复杂,但是不会出错。
完整代码
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <string>
#include <iomanip>using namespace std;class Student
{
public:int num;string name;string sex;};//电信类中存放学生数据
class DX :public Student
{
public:int classroom;int hmath;int eng;int sum;//总分DX *next;//电信类指针,指向下一结点DX* pre;//指向前一个结点};//双向链表
struct Linklist
{DX* head;//头指针DX *present;//当前指针void Input();//录入void Creat();//扩容bool Check();//查找学号bool Check1();//查找姓名void SelectCheck();//选择查找 void Output();//浏览void Delete();//删除void Modify();//修改void Sort();//排序,高数,英语,学号
}X;//开辟新空间,new一个类出来
void Linklist::Creat()
{//头插present = new DX;//当前指针为新开辟的这个电信类head = present;present->next = NULL;present->pre = NULL;//此时只有一个结点
}void Linklist::Input()
{int size;//想要输入的学生个数cout << "请输入学生的人数:";cin >> size;//有几个人循环几次 for (int i = 0; i < size; i++){//在插入的时候就进行链表的链接 present = new DX;head->pre = present;present->next = head;head = present;//相当于头插present->pre = NULL;cout << "请输入第" << i + 1 << "个学生的学号:";cin >> present->num;cout << "请输入第" << i + 1 << "个学生的姓名:";cin >> present->name;cout << "请输入第" << i + 1 << "个学生的性别:";cin >> present->sex;cout << "请输入第" << i + 1 << "个学生的班级:";cin >> present->classroom;cout << "请输入第" << i + 1 << "个学生的高数成绩:";cin >> present->hmath;cout << "请输入第" << i + 1 << "个学生的英语成绩:";cin >> present->eng;present->sum = present->hmath + present->eng;cout << "-----------------------------" << endl;}cout << "录入成功!!!!" << endl;
}//打印表头信息
void display()
{cout << setw(30) << "学生成绩信息" << endl; // setw函数设置字段宽度,需要引用头文件iomanip cout << " --------------------------------------------------------------------------" << endl;cout << setw(6) << "学号" << setw(12) << "姓名" << setw(8) << "性别" << setw(8)<< "班级" << setw(8) << "高数" << setw(8) << "英语" << setw(12) << "总分" << endl;cout << " --------------------------------------------------------------------------" << endl;
}void Linklist::Output()
{//从头开始 present = head;display();//打印出所有信息,直到末尾while (present->next != NULL){//setw函数是用来设置行间距的cout << setw(6) << present->num << setw(12) << present->name << setw(8) << present->sex<< setw(8) << present->classroom << setw(8) << present->hmath << setw(8) << present->eng<< setw(12) << present->sum << endl;cout << " --------------------------------------------------------------------------" << endl;present = present->next;//更新}}//精确查找
//要想用学生姓名查找将num改为name即可 int变为string 类型要匹配
bool Linklist::Check()
{present = head;int id;cin >> id;display();while (present->next != NULL){if (id == present->num){//找到打印出信息cout << setw(6) << present->num << setw(12) << present->name << setw(8) << present->sex<< setw(8) << present->classroom << setw(8) << present->hmath << setw(8) << present->eng<< setw(12) << present->sum << endl;cout << " --------------------------------------------------------------------------" << endl;return true;}else{//不同就接着找present = present->next;}}cout << "查无此人!!!!" << endl;return false;
}bool Linklist::Check1()
{present = head;//cout << "请输入需要查找的学生学号:";string nam;cin >> nam;display();while (present->next != NULL){if (nam == present->name){//找到打印出信息cout << setw(6) << present->num << setw(12) << present->name << setw(8) << present->sex<< setw(8) << present->classroom << setw(8) << present->hmath << setw(8) << present->eng<< setw(12) << present->sum << endl;cout << " --------------------------------------------------------------------------" << endl;return true;}else{//不同就接着找present = present->next;}}cout << "查无此人!!!!" << endl;return false;
}//选择查找
void Linklist::SelectCheck()
{cout << "1.按学号查询" << endl;cout << "2.按姓名查询" << endl;//cout << "3.按姓名进行模糊查询" << endl;cout << "请选择:";int a;cin >> a;switch (a){case 1:cout << "请输入需要查找的学生学号:";Check();break;case 2:cout << "请输入需要查找的学生姓名:";Check1();break;/*case 3:cout << "请输入需要模糊查找的学生姓名:";*/default:cout << "选择错误" << endl;break;}
}void Linklist::Modify()
{cout << "请输入你须要修改的学生的学号:";//输入学号在check函数中输入即可,不用另外写了 //先查看需要修改的信息是否存在if (Check()){//找到,重新录入即可 cout << "请输入修改后学生的学号:";cin >> present->num;cout << "请输入修改后学生的姓名:";cin >> present->name;cout << "请输入修改后学生的性别:";cin >> present->sex;cout << "请输入修改后学生的班级:";cin >> present->classroom;cout << "请输入修改后学生的高数成绩:";cin >> present->hmath;cout << "请输入修改后学生的英语成绩:";cin >> present->eng;present->sum = present->hmath + present->eng;cout << "修改成功!!!" << endl;}//找不到Check函数会自动return false else cout << "修改失败!" << endl;
}void Linklist::Delete()
{//删除学生信息cout << "请输入要删除的学生学号: ";if (Check()){if (present->pre == NULL){//头指针与当前指针指向同一个,将头指针给下一个 head = present->next;delete present;}else if (present->pre != NULL){//改变指针指向,前一个越过present 指向后一个//不改变之前两个等号右边都是present present->pre->next = present->next;present->next->pre = present->pre;delete present;}cout << "删除数据成功!" << endl;}else cout << "删除失败!" << endl;
}void Linklist::Sort()
{int a = 1, b = 1; present = head;
start:while (present->next->next != NULL){a = b;//排序,小的放前面 //高数if (present->hmath == present->next->hmath){if (present->eng == present->next->eng){//学号if (present->num < present->next->num){//无需互换 present = present->next;}else if (present->num > present->next->num&&present->pre == NULL){b++;DX* p = present;DX* q = p->next;p->next = q->next;q->next = p;p->pre = q;q->next = p;q->pre = NULL;}//中间结点,尾结点不作考虑 else if (present->num > present->next->num && present->pre != NULL){if (present->next->next != NULL){b++;DX* p = present;DX* q = p->next;p->pre->next = q;q->pre = p->pre;p->next = q->next;q->next->pre = p;p->pre = q;q->next = p;}}}//英语else if (present->eng < present->next->eng){//无需互换 present = present->next;}else if (present->eng > present->next->eng&&present->pre == NULL){b++;DX* p = present;DX* q = p->next;p->next = q->next;q->next = p;p->pre = q;q->next = p;q->pre = NULL;}//中间结点,尾结点不作考虑 else if (present->eng > present->next->eng && present->pre != NULL){if (present->next->next != NULL){b++;DX* p = present;DX* q = p->next;p->pre->next = q;q->pre = p->pre;p->next = q->next;q->next->pre = p;p->pre = q;q->next = p;}}}else if (present->hmath < present->next->hmath){//无需互换 present = present->next;}//头结点 else if (present->hmath > present->next->hmath&&present->pre == NULL){b++;DX* p = present;DX* q = p->next;p->next = q->next;q->next = p;p->pre = q;q->next = p;q->pre = NULL;}//中间结点,尾结点不作考虑 else if (present->hmath > present->next->hmath && present->pre != NULL){if (present->next->next != NULL){b++;DX* p = present;DX* q = p->next;p->pre->next = q;q->pre = p->pre;p->next = q->next;q->next->pre = p;p->pre = q;q->next = p;}}while (a != b){//若一次完整循环下来没有顺序变化,退出while (present->pre != NULL) {present = present->pre;} goto start;}}//没有此次向前遍历,排序过后链表中只会留下最后一次插入的数据 while (present->pre != NULL) { present = present->pre; }head = present;//因为头结点不为空,修改完后可能会被改变,此处从新定位头结点//打印出排序好的链表 display();do{cout << setw(6) << present->num << setw(12) << present->name << setw(8) << present->sex<< setw(8) << present->classroom << setw(8) << present->hmath << setw(8) << present->eng<< setw(12) << present->sum << endl;cout << " --------------------------------------------------------------------------" << endl;present = present->next;//更新} while (present->next != NULL);
}//菜单
void menu()
{cout << "-----------------------------------------------" << endl;cout << "学生信息管理系统" << endl;cout << "0.退出系统" << endl;cout << "1.录入信息" << endl;cout << "2.删除信息" << endl;cout << "3.修改信息" << endl;cout << "4.查找信息" << endl;cout << "5.浏览信息" << endl;cout << "6.排序" << endl;cout << "-----------------------------------------------" << endl;cout << "请输入(0-6):";
}int main()
{X.Creat();//没有while循环switch语句只走一遍就结束了 while (1){menu();int input;cin >> input;switch (input){case 0:break;case 1:X.Input();break;case 2:X.Delete();break;case 3:X.Modify();break;case 4:X.SelectCheck();break;case 5:X.Output();break;case 6:X.Sort();break;default:cout << "输入错误!!!" << endl;break;}//退出循环if (input == 0){break;//终止while }}return 0;}
结果展现
相关文章:

学生信息管理系统C++
设计目的 使学生进一步理解和掌握课堂上所学的面向对象C编程知识,巩固和加深学生对C面向对象课程的基本知识的理解和掌握。掌握C面向对象编程和程序调试的基本技能,学会利用C语言进行基本的软件设计,着重提高运用C面向对象语言解决实际问题的…...
前端开发三大主流框架解析
Web前端三大主流框架分别是Angular、React和Vue.js。以下是《优联前端》关于这三个框架解析介绍: Angular: 来源与开发者:Angular是由Google开发的前端框架。功能特点:Angular是一个完整的框架,包括了数据绑定、组件化…...

【2.文件和目录相关(下)】
一、查看文件内容命令 1、cat 文件名:用于显示文件内容,比如 cat test.c。 (1)cat -b test.c 表示加行号显示文件内容。 (2)cat -s test.c 表示多个空行合并成一个空行显示。 2、nl 文件名:…...

【C语言】结构体与内存对齐
前言 在本篇博客,我将介绍结构体类型,结构体变量的创建和初始化,重点介绍结构中存在的内存对齐。 结构变量 结构是一些值的集合,这些值被称为成员变量。结构的每个成员可以是不同类型的变量。 在理解结构的时候,我们…...
【机器学习】之 kmean算法原理及实现
基本概念 K-Means 聚类算法的目标是将数据集分成 ( K ) 个簇,使得每个簇内的数据点尽可能相似,而簇与簇之间尽可能不同。这种相似度是通过计算数据点与簇中心的距离来衡量的。 算法步骤 选择簇的数量 ( K ):随机选择 ( K ) 个数据点作为初…...
国产高边驱动HD70202Q替换英飞凌BTS7040-2
高边驱动也称之为高边开关,主要用于车内负载的驱动与开关,并对负载进行保护和诊断。高边驱动以高可靠性、灵活性、低功耗以及小型轻量等特点,正逐渐替代传统的保险丝、继电器等方案。 RAMSUN提供的HD70202Q车规级双通道智能高边驱动的输入控…...

2024年06月在线IDE流行度最新排名
点击查看最新在线IDE流行度最新排名(每月更新) 2024年06月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多,人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…...
顺序表和链表基础操作的复习
顺序表 #include<iostream> using namespace std; 静态 //#define MAX_SIZE 50 //typedef int ElemType; //typedef struct //{ // int length; // ElemType nums[MAX_SIZE]; //}Sqlist; //动态: #define Init_SIZE 50 typedef int ElemType; typedef struct {int lengt…...

[C#]winform部署官方yolov10目标检测的onnx模型
【框架地址】 https://github.com/THU-MIG/yolov10 【算法介绍】 今天为大家介绍的是 YOLOv10,这是由清华大学研究团队最新提出的,同样遵循 YOLO 系列设计原则,致力于打造实时端到端的高性能目标检测器。 方法 创新 双标签分配策略 众所…...

hmcode硬件编程1
在/home/golemon/hmcode/applications/sample/wifi-iot/app内创建文件夹。 这里创建了d_6_3文件夹 . ├── BUILD.gn ├── d_6_3 │ ├── BUILD.gn │ └── lab.c ├── demolink │ ├── BUILD.gn │ └── helloworld.c ├── iothardware │ ├── B…...
[C++][CMake] set_target_properties called with incorrect number of arguments
1 简介 这篇文章将探讨了在使用CMake构建C项目时,调用set_target_properties函数时参数数量不正确所引发的问题。 2 错误案例 以下为可能发生错误的案例 include_directories (${CMAKE_SOURCE_DIR}/common) find_package(Threads)add_library (libusbmuxd SHARE…...
AdamW算法
AdamW算法是优化算法Adam的一个变体,它在深度学习中广泛应用。AdamW的主要改进在于它正则化方法的改变,即通过权重衰减(weight decay)而不是L2正则化,来控制模型参数的大小,从而提升了训练的稳定性和效果。…...

【c++进阶(二)】STL之string类的模拟实现
💓博主CSDN主页:Am心若依旧💓 ⏩专栏分类c从入门到精通⏪ 🚚代码仓库:青酒余成🚚 🌹关注我🫵带你学习更多c 🔝🔝 1.前言 本章重点 本章主要介绍一些关键接口的模拟实现ÿ…...

PHPStudy(xp 小皮)V8.1.1 通过cmd进入MySQL命令行模式
PHPStudy是一个PHP开发环境集成包,可用在本地电脑或者服务器上,该程序包集成最新的PHP/MySql/Apache/Nginx/Redis/FTP/Composer,一次性安装,无须配置即可使用。MySQL MySQL是一个关系型数据库管理系统,由瑞典 MySQL A…...

php反序列化初步了解
一、定义 序列化(串行化):将变量转换为可保存或传输的字符串的过程(通常是字节流、JSON、XML格式) 反序列比(反串行化):把这个字符串再转化成原始数据结构或对象(原来的…...

Windows系统电脑本地部署AI音乐创作工具并实现无公网IP远程使用
文章目录 前言1. 本地部署2. 使用方法介绍3. 内网穿透工具下载安装4. 配置公网地址5. 配置固定公网地址 前言 本文主要介绍如何在Windows系统电脑上快速本地部署一个文字生成音乐的AI创作工具MusicGPT,并结合cpolar内网穿透工具实现随时随地远程访问使用。 MusicG…...

玩转Linux进度条
准备工作: 一.关于缓冲区 首先,咱们先来一段有意思的代码: #include<stdio.h> #include<unistd.h> int main() {printf("you can see me");sleep(5);} 你可以在你的本地运行一下,这里我告诉大家运行结果…...

真国色码上赞,科技流量双剑合璧,商家获客新纪元开启
在数字化浪潮汹涌的今天,真国色研发团队依托红玉房网络科技公司的雄厚实力,凭借科技领先的核心竞争力,推出了创新性的商家曝光引流工具——码上赞。这款工具借助微信支付与视频号已有功能,为实体商家提供了一种全新的引流获客方式,实现了科技与商业的完美融合。 科技领先,流量黑…...

C++:特殊类设计和四种类型转换
一、特殊类设计 1.1 不能被拷贝的类 拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。 C98: 1、将拷贝构造函数与赋值运算符重载只…...

(南京观海微电子)——屏幕材质及优缺点对比
LED/LCD LCD(Liquid Crystal Ddisplay)即“液晶显示器”,由两块偏光镜、两块薄膜晶体管以及彩色滤光片、光源(荧光灯)、显示面板组成的成像元器件。 LED(Light Emitting Diode)即“发光二极管…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...