首页 > 编程语言 >C++学生信息管理 1.0记录

C++学生信息管理 1.0记录

时间:2024-03-24 14:01:16浏览次数:21  
标签:current head 1.0 nullptr 信息管理 C++ next 链表 节点

C++学生信息管理 1.0记录 

该信息管理没有太多可支持的操作,仅有一些基础设置,后续优化中将添加更多功能。

一.头文件引用和命名空间声明

#include <iostream> //输入输出操作
#include <string>   //字符串操作
using namespace std;  //为方便使用,不需要在cout,string等前方加前缀std

二.学生节点的结构体定义。

用来存储学生的基本信息,其中包括学号,姓名,性别,年龄以及指向下一节点的指针。结构体中还包括了一个构造函数,用来初始化成员变量。

struct StudentNode
{
    unsigned studentNumber; //学号
    string name; //姓名
    int age; //年龄
    string sex; //性别
    StudentNode *next; //指向下一节点的指针

    //构造函数用于初始化成员变量
    StudentNode(unsigned sn, const string &na, int ag, const string &se)
                : studentNumber(sn), name(na), age(ag), sex(se), next(nullptr) {}
};

1.这里的学号用的为无符号类型,由于学号整型数太大,int类型可支持范围不够,在输入学号后会超出范围生成垃圾值。

2.因为考虑到以后会对该代码进行优化,添加一些功能,少不了插入与删除操作,所有用链表的形式用来存储信息,便于后续代码的优化。

3.构造函数接受四个参数,其中两个为常量引用类型,因为无需对传递过来的实参做更改处理,设置为常量类型更为合理与安全,且效率也更高。

4.对于unsignedint类型的参数,一般不需要将它们声明为引用类型,因为它们是基础数据类型,传递它们的值通常非常快,且不会涉及额外的内存分配。传递值意味着会创建参数的副本,但对于这些基础类型,这个副本的创建通常是非常高效的。

5.初始化列表是构造函数独有的特性,在其它成员函数中无法使用。与在函数体里面作赋值操作相比,初始化列表往往伴有更快捷的效率以及更明了的意图。

6.在这里将next指向空指针nullprt,nullprt为C++的一个关键字,可直接使用,不需要引用任何头文件和作用域。

三.链表类的定义

class StudentLinkList
{
public:
    //公开构造函数,初始化链表的头节点为nullptr
    StudentLinkList() : head(nullptr) {}
    // 析构函数声明,具体实现在类的外部定义
    ~StudentLinkList();
    // 成员函数声明,用于向链表中添加学生信息 
    void addStudent(unsigned sn, const string &na, int ag,
                    const string &se);
    // 成员函数声明,用于打印链表中的学生信息 
    void printStudent();
    
private:
    // 私有成员变量,指向链表的头节点,初始时为nullptr  
    StudentNode *head;
};

1.在这里使用C++的新特性class类来做为链表,便于对数据与操作这些数据的方法做一个封装,与struct相比,class有更多支持的操作(struct与class本质上并无什么很大的区别,最直观的就是struct结构的成员变量及成员函数均是公开的,而class如果不显式表面public,则默认全是私有的)。以后在进行代码优化的时候添加一些功能也比较方便。

2.构造函数使用初始化列表将链表中的头指针指向nullprt(空指针)。

3.析构函数StudentLinkList(); 这是StudentLinkList类的析构函数声明,用于在对象生命周期结束时执行清理操作,释放链表占用的内存。具体的析构函数实现在类的外部定义。

4.将head指针设置为私有是面向对象编程中常见的做法,它有助于实现代码的某些特性,就是面向对象编程的几大特性。

四.析构函数的定义

StudentLinkList::~StudentLinkList()
{
    // 初始化一个指针current,指向链表的头节点head
    StudentNode *current = head;
    // 当current不为空时,说明还有节点需要被删除 
    while (current != nullptr)
    {
        // 保存当前节点的下一个节点的指针
        StudentNode *next = current->next;
        // 删除当前节点,释放其占用的内存
        delete current;
        // 将current指针移动到下一个节点,继续删除操作 
        current = next;
    }
    // 将头节点指针设置为nullptr,表示链表为空
    head = nullptr;
}

1.在析构函数开始时,首先初始化一个指针current,并将其指向链表的头节点head。这是开始遍历链表并删除节点的起点。                                                                                                                     
2.使用while循环来遍历链表中的每一个节点。循环继续的条件是current不为nullptr,即还有节点未被处理。                                                                                                                                             
3.在删除当前节点之前,通过current->next保存下一个节点的指针到next变量中。这是因为一旦当前节点被删除,我们就无法通过它访问下一个节点了。                                                                      
4.使用delete操作符(这是C++中的关键字,相当于C语言中的free())释放当前节点current所占用的内存。这会将该节点从内存中移除,并且任何对该节点的引用都将变得无效。                            
5.将current指针更新为next,即我们之前保存的下一个节点的指针。这样,在下一次循环迭代时,我们就可以处理链表中的下一个节点。                                                                                                
6.循环继续,直到current变为nullptr,表示链表中的所有节点都已被删除。                                      
7.最后,将头节点指针head置为nullptr,表示链表现在为空。这是一个很重要的步骤,因为它确保了head指针不再指向任何已删除的内存区域,从而避免了很大的安全风险。

五.增添函数的定义

void StudentLinkList::addStudent(unsigned sn, const string &na,
                                 int ag, const string &se)
{
    //创建一个新的StudentNode对象,并使用传入的参数初始化它。这个新节点会被添加到链表的末尾。
    StudentNode *newNode = new StudentNode(sn, na, ag, se);
    //如果链表为空(即head为nullptr),则直接将新节点设置为链表的头节点。
    if (head == nullptr)
    {
        head = newNode;
    }
    //如果链表不为空,初始化一个指针current,使其指向链表的头节点。
    else
    {
        StudentNode *current = head;
        //使用一个循环遍历链表,直到找到链表的最后一个节点(即next指针为nullptr的节点)。
        while (current->next != nullptr)
        {
            current = current->next;
        }
        //将最后一个节点的next指针指向新创建的节点,从而将新节点添加到链表的末尾
        current->next = newNode;
    }
}

1.该函数操作为链表的基本操作,因为定义的函数体代码多,与上面的析构函数一样定义在了类外,所以要加上::作用域解析运算符,告诉编译器所属范围。 

 

六.打印函数的定义

//用于打印出学生信息
void StudentLinkList::printStudent()
{
    //将当前节点指向头节点
    StudentNode *current = head;
    //遍历整个链表,对联表内的所有内容进行打印
    while (current != nullptr)
    {
        cout << "Student Number: " << current->studentNumber
             << ", Name: " << current->name
             << ", Age: " << current->age
             << ", Sex: " << current->sex << endl;
        //打印完当前节点后将指针移动向下一节点
        current = current->next;
    }
}

 七.函数主体

int main()
{
    StudentLinkList student;

    student.addStudent(2410145903, "Zhangsan", 18, "Man");
    student.addStudent(2415343923, "Lisi", 21, "Man");
    student.addStudent(2345351878, "Wangwu", 19, "Man");
    student.printStudent();

    return 0;
}

这个管理信息没有什么较为复杂的操作,在后续还将进行优化,增添一些插入和删除学生信息的操作,该系统学生信息的获取也是比较直观,在后续的优化中会进行一些升级。

八.完整代码

#include <iostream> //输入输出操作
#include <string>   //字符串操作
using namespace std;  //为方便使用,不需要在cout,string等前方加前缀std

//结构体的声明,学生的基本信息存储
struct StudentNode
{
    unsigned studentNumber; //学号
    string name; //姓名
    int age; //年龄
    string sex; //性别
    StudentNode *next; //指向下一节点的指针

    //构造函数用于初始化成员变量
    StudentNode(unsigned sn, const string &na, int ag, const string &se)
        : studentNumber(sn), name(na), age(ag), sex(se), next(nullptr) {}
};

//链表类的声明
class StudentLinkList
{
public:
    //公开构造函数,初始化链表的头节点为nullptr
    StudentLinkList() : head(nullptr) {}
    // 析构函数声明,具体实现在类的外部定义
    ~StudentLinkList();
    // 成员函数声明,用于向链表中添加学生信息 
    void addStudent(unsigned sn, const string &na, int ag,
                    const string &se);
    // 成员函数声明,用于打印链表中的学生信息 
    void printStudent();
    
private:
    // 私有成员变量,指向链表的头节点,初始时为nullptr  
    StudentNode *head;
};

//析构函数定义
StudentLinkList::~StudentLinkList()
{
    // 初始化一个指针current,指向链表的头节点head
    StudentNode *current = head;
    // 当current不为空时,说明还有节点需要被删除 
    while (current != nullptr)
    {
        // 保存当前节点的下一个节点的指针
        StudentNode *next = current->next;
        // 删除当前节点,释放其占用的内存
        delete current;
        // 将current指针移动到下一个节点,继续删除操作 
        current = next;
    }
    // 将头节点指针设置为nullptr,表示链表为空
    head = nullptr;
}

//增添学生信息
void StudentLinkList::addStudent(unsigned sn, const string &na,
                                 int ag, const string &se)
{
    //创建一个新的StudentNode对象,并使用传入的参数初始化它。这个新节点会被添加到链表的末尾。
    StudentNode *newNode = new StudentNode(sn, na, ag, se);
    //如果链表为空(即head为nullptr),则直接将新节点设置为链表的头节点。
    if (head == nullptr)
    {
        head = newNode;
    }
    //如果链表不为空,初始化一个指针current,使其指向链表的头节点。
    else
    {
        StudentNode *current = head;
        //使用一个循环遍历链表,直到找到链表的最后一个节点(即next指针为nullptr的节点)。
        while (current->next != nullptr)
        {
            current = current->next;
        }
        //将最后一个节点的next指针指向新创建的节点,从而将新节点添加到链表的末尾
        current->next = newNode;
    }
}

//用于打印出学生信息
void StudentLinkList::printStudent()
{
    //将当前节点指向头节点
    StudentNode *current = head;
    //遍历整个链表,对联表内的所有内容进行打印
    while (current != nullptr)
    {
        cout << "Student Number: " << current->studentNumber
             << ", Name: " << current->name
             << ", Age: " << current->age
             << ", Sex: " << current->sex << endl;
        //打印完当前节点后将指针移动向下一节点
        current = current->next;
    }
}

int main()
{
    StudentLinkList student;

    student.addStudent(2410145903, "Zhangsan", 18, "Man");
    student.addStudent(2415343923, "Lisi", 21, "Man");
    student.addStudent(2345351878, "Wangwu", 19, "Man");
    student.printStudent();

    return 0;
}

九.运行示例 

标签:current,head,1.0,nullptr,信息管理,C++,next,链表,节点
From: https://blog.csdn.net/jjq20020211/article/details/136985457

相关文章

  • C++:map&set 对红黑树的封装
    C++:map&set对红黑树的封装将红黑树封装为泛型Find接口迭代器insert接口map的operator[]接口总代码展示C++的STL库中,把红黑树封装为了两个容器map与set,本博客将基于红黑树,来实现map和set的封装。如果不了解红黑树,可见博客[数据结构/C++:红黑树]将红黑树封装为泛型......
  • 【每周例题】力扣 C++ 两数之和
    两数之和题目 题目分析1.返回两个数的下标和,第一反应可以是采用双for循环2.数组数值等于整数目标值,那就采用if判断,符合直接输出,跳出循环,避免输出多个答案3.由于力扣题目采用了容器,大家可以选择点击该链接了解:容器代码#include<iostream>#include<vector>usingnamesp......
  • 【每周例题】力扣 C++ 组合
    组合题目力扣组合 题目解析1.我们可以根据题目分析可知,题目所要求我们做的是:从1到n进行遍历,找出k个数组成小组合,再将小组合拼接在一起成为大组合输出。2.所以,根据题目,我们可以采用两个数组,一个一维数组temp,负责存储k个数,组为小组合,一个二维数组res,存储小组合,变为大组合。......
  • 【webserver】 C++ 项目webserver面试八股总结(二)
    32.一次网页的访问从URL开始,说一下整个访问的过程客户端获取URL->DNS解析->TCP连接->发送HTTP请求->服务器处理请求->返回报文->浏览器解析渲染页面->TCP断开连接客户端:(应用层开始)获取URL,通过负责域名解析的域名服务获取网址的IP地址,根据HTTP协......
  • 《大厂面试模拟(免费) - C++工程方向》
        以个人的名义,提供c++工程方向的大厂面试模拟,不会以任何形式收费。此面试可为应聘者提供真实反馈。简历和面试过程不会以任何形式给第三方(包括我当前所在公司)。我的经验:多年百度,阿里知名核心项目组工作经验面试100+人多年mentor经验,辅助多位新同学项目落地《构建......
  • c++ stl 之映射—— map 详解
     map是stl的一个关联容器,名叫“映射”,何为“映射”?其实就是一个数组,但有了数组何必还需映射,这是一个高深的问题。目录一、map简介         1.空间复杂度    2.时间复杂度     3.“键”的类型二、 map用法     1.声明  ......
  • MyTlias-员工信息管理系统(一)-整体框架的搭建
    文章目录1.工作准备1.1.新建项目1.2.准备数据库表1.3.准备数据实体2完成部门信息展示2.1properties2.2DAO层2.3Service层2.4Controller层本小节主要完成项目文件准备,以及第一个功能实现:部门信息展示.并使用PostMan/Apifox测试接口数据是否正常返......
  • C++面向对象编程 - 组合:C++中的组合是一种类与类之间的关系
    C++面向对象编程-组合在C++中,面向对象编程(Object-OrientedProgramming,简称OOP)是一种强大的编程范式,它允许我们通过类(Class)和对象(Object)的概念来组织和管理代码。在面向对象编程中,类不仅可以包含数据成员(Attributes)和成员函数(Methods),还可以与其他类建立各种关系。其中一......
  • c++学习路线
    学习C++可以按照以下路线进行:基础知识:了解C++语言的基本语法和特性学习C++的数据类型、控制流和函数熟悉面向对象编程的概念和用法类和对象:学习如何定义类和对象理解类的构造函数、析构函数和成员函数掌握类的继承、多态和封装特性STL库:熟悉STL(标准模板库)的常用容器,......
  • ideaSSM 学员信息管理系统bootstrap开发mysql数据库web结构java编程计算机网页源码mav
    一、源码特点 idea开发SSM学员信息管理系统是一套完善的信息管理系统,结合SSM框架和bootstrap完成本系统,对理解JSPjava编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具有完整的源代码和数据库,系统主要采用B/S模式开发。前段主要技术bootstrap.cssjquery后端主要......