C++成绩系统管理,用链表实现的原理和链表结构

实验内容: 1)选课登记 2)动态输入学生成绩。 3)查询学生成绩。4)修改成绩
运行效果: 《学生成绩管理系统》
[0]新生注册 [1]选课登记 [2]学生成绩输入[3]成绩查询 [4]修改成绩 [5]退出

img


这个代码可以实现
但我对其中结构体、指针、链表等的技术要点不明白,能不能详细说一下这个程序的程序要点或算法描述,还有画出链表结构,非常感谢。


#include"stdafx.h"
#include <iostream>
using namespace std;//$$
#include<iomanip>//$$
#include <stdlib.h>

struct SCORE
{
    int courseId; //课程号
    int score; //分数
    SCORE *pnext;  //下个结点
};
struct STU_SCORE
{
    char name[16]; //姓名
    int stuId; //学号
    SCORE *scoreHead;//学生课程成绩链表
    struct STU_SCORE *pnext; //下个结点
};

int mainMenu();
int countRecords(STU_SCORE *pHead);//$$
int stuReg(STU_SCORE *pHead);
int selCourse(STU_SCORE *pHead);
int inputData(STU_SCORE *pHead);
int scoreSort(STU_SCORE *pHead);
int scoreQuery(STU_SCORE *pHead);
int modify(STU_SCORE *pHead);

enum MAIN_CMD{REG,SEL=1,INPUT,QUERY,MODI,EXIT};

int _tmain()
{
    STU_SCORE *head=( STU_SCORE *)malloc(sizeof(STU_SCORE));
    head->stuId=-1;
    head->pnext=head;
    while(1)
    {
        int cmd=mainMenu();
        switch(cmd)
        {
        case REG:
            stuReg(head);
            break;
        case SEL:
            selCourse(head);
            break;
        case INPUT:
            inputData(head);
            break;
        case QUERY:
            scoreQuery(head);
            break;
        case MODI:
            modify(head);
            break;
        case EXIT:
            return 0;
        }
    }

    return 0;
}

int mainMenu()
{
    system("cls");
    cout<<"\t\t《学生成绩管理系统》\n";
    cout<<" \t\t[0]新生注册\n";
    cout<<" \t\t[1]选课登记\n";
    cout<<" \t\t[2]学生成绩输入\n";
    cout<<" \t\t[3]成绩查询\n";
    cout<<" \t\t[4]修改成绩\n";
    cout<<" \t\t[5]退出\n";
    cout<<"命令? ";
    int cmd;
    cin>>cmd;
    return cmd;
}

int countRecords(STU_SCORE *pHead) {
    int count = 0;
    STU_SCORE *pStu = pHead->pnext;
    while (pStu != pHead) {
        count++;
        pStu = pStu->pnext;
    }
    return count;
}

//新生注册:建立学生信息链表,从键盘输入学生姓名学号,插入到链表中。
int stuReg(STU_SCORE *pHead)
{
start://$$start
    {
        cout << "学号 姓名"<<endl;
        while(1){
            STU_SCORE *pNewStu = new STU_SCORE;
            cin >> pNewStu->stuId;
        if (pNewStu->stuId == -1)
        {
            delete pNewStu; // 输入结束,释放结点
            break;
        }
        cin >> pNewStu->name;
        pNewStu->scoreHead = new SCORE;
        pNewStu->scoreHead->pnext = pNewStu->scoreHead; // 初始化学生课程成绩链表
        pNewStu->pnext = pHead->pnext;
        pHead->pnext = pNewStu;//头插法
        }
    }
    int count=countRecords(pHead);
    cout<<"学生数据库中共有"<<count<<"个记录"<<endl;//$$end
    cout<<"继续新的注册?";
    char c;
    cin>>c;
    if(c=='y'||c=='Y')goto start;
    return 0;
}

//学生选课
int selCourse(STU_SCORE *pHead)
{
start:
    int cid;
    cout<<"课程号:";
    cin>>cid;
    cout<<"输入选择该课程的学生学号\n";
    int stuId;
    cin>>stuId;//空格为间隔
    while(stuId>0)
    {
        STU_SCORE *pStu=pHead->pnext;
        while(pStu!=pHead)//链表已有记录
        {
            if(pStu->stuId==stuId)//有该学号
            {
                bool be=false;
                SCORE *pcourse=pStu->scoreHead->pnext;
                while(pcourse!=pStu->scoreHead)//已有该选课
                {
                    if(pcourse->courseId==cid)
                    {
                        be=true;
                        break;
                    } 
                    pcourse=pcourse->pnext;
                }
                if(!be)
                { //还没有选此课程
                    SCORE *pNewcourse=(SCORE *)malloc(sizeof(SCORE));
                    pNewcourse->courseId = cid;
                    pNewcourse->score = -1; // 初始化成绩为-1
                    pNewcourse->pnext = pStu->scoreHead->pnext;
                    pStu->scoreHead->pnext = pNewcourse;//头插法
                }
            } 
            pStu=pStu->pnext;
        }
        cin>>stuId;
    }
    int count=0;
    STU_SCORE *pStu=pHead->pnext;
    while(pStu!=pHead)//链表已有记录
    {
        SCORE *pcourse=pStu->scoreHead->pnext;
        while(pcourse!=pStu->scoreHead)
        {
            if(pcourse->courseId==cid)
            {
                count++;
            } 
            pcourse=pcourse->pnext;
        }
        pStu=pStu->pnext;
    }
    cout<<"共有"<<count<<"个学生选此课程\n";
    cout<<"继续新的选课输入?";
    char c;
    cin>>c;
    if(c=='y'||c=='Y')goto start;
    return 0;
}

//学生成绩输入
int inputData(STU_SCORE *pStuHead)
{
    int count;
start:
    count=0;
    cout<<"课程号:";
    int cid;
    cin>>cid;
    STU_SCORE *pStu=pStuHead->pnext;
    while(pStu!=pStuHead)//if链表已有学生记录
    {
        SCORE *pcourse=pStu->scoreHead->pnext;
        while(pcourse!=pStu->scoreHead)
        {
            if(pcourse->courseId==cid)
            {
                cout<<"学号:"<<pStu->stuId<<" 姓名:"<<pStu->name;
                cout<<" 成绩:";
                if(pcourse->score>=0)
                    cout<<"已输入";
                else
                {
                    cin>>pcourse->score;
                    count++;
                }
                break;
            }
            pcourse=pcourse->pnext;
        }
        pStu=pStu->pnext; 
    }
    if(count==0)
        cout<<"该课程无学生选!\n";
    else
        cout<<cid<<"课程成绩已输入完成!"<<"\n";
    cout<<"继续其他课程成绩输入?";
    char c;
    cin>>c;
    if(c=='y'||c=='Y')goto start;
    return 0;
}

//课程成绩查询
int scoreQuery(STU_SCORE *pStuHead)
{
    int stuId;//$$start
    cout << "学号: ";
    cin >> stuId;
    STU_SCORE *pStu = pStuHead->pnext;
    while (pStu != pStuHead)
    {
        if (pStu->stuId == stuId)
        {
            cout << "姓名:" << pStu->name << "  成绩:\n";
            SCORE *pcourse = pStu->scoreHead->pnext;
            while (pcourse != pStu->scoreHead)
            {
                cout << "课程号:" << pcourse->courseId << "  成绩:" << pcourse->score << endl;
                pcourse = pcourse->pnext;
            }
            break;
        }
        pStu = pStu->pnext;
    }
    cout << "继续查询?(y/n): ";
    char c;
    cin >> c;
    if (c == 'n' || c == 'N')
        return 0;
    else
        return scoreQuery(pStuHead);//$$end
    return 0;
}

//课程成绩修改
int modify(STU_SCORE *pHead)
{ 
    int stuId, courseId;//$$start
    cout << "学号:";
    cin >> stuId;
    cout << "课程号:";
    cin >> courseId;

    STU_SCORE *pStu = pHead->pnext;
    while (pStu != pHead)
    {
        if (pStu->stuId == stuId)
        {
            SCORE *pcourse = pStu->scoreHead->pnext;
            while (pcourse != pStu->scoreHead)
            {
                if (pcourse->courseId == courseId)
                {
                    cout << "原成绩:" << pcourse->score << " 成绩修改为:";
                    cin >> pcourse->score;
                    break;
                }
                pcourse = pcourse->pnext;
            }
            break;
        }
        pStu = pStu->pnext;
    }
    cout << "继续修改? (y/n): ";
    char c;
    cin >> c;
    if (c == 'n' || c == 'N')
        return 0;
    else
        return modify(pHead);//$$end
    return 0;
}



基于new bing部分指引作答:
这段代码是一个简单的学生成绩管理系统,使用了C++的结构体、指针和链表来存储学生信息和成绩数据。

程序中使用了两个结构体:SCORE 和 STU_SCORE。

SCORE 结构体定义了课程成绩的相关信息,包括课程号 (courseId) 和分数 (score),以及一个指向下一个结点的指针 (pnext),用于构建成绩链表。

STU_SCORE 结构体定义了学生的相关信息,包括姓名 (name)、学号 (stuId),以及一个指向课程成绩链表的头结点的指针 (scoreHead) 和一个指向下一个学生结点的指针 (pnext),用于构建学生信息链表。

主函数 main 中首先创建了一个头结点 head,并将其初始化为一个空结点。然后进入一个循环,等待用户输入命令选择不同的功能操作。根据用户的选择,调用不同的函数进行学生注册、选课、成绩输入、成绩查询和成绩修改等操作。

具体的函数功能和算法描述如下:
1、mainMenu():显示主菜单并等待用户输入命令,返回用户选择的命令编号。

2、countRecords(STU_SCORE *pHead):遍历学生信息链表,返回链表中的学生记录数。

3、stuReg(STU_SCORE *pHead):新生注册,从键盘输入学生姓名和学号,并插入到学生信息链表中。

4、selCourse(STU_SCORE *pHead):学生选课,从键盘输入课程号和选择该课程的学生学号,并将选课信息插入到相应学生的课程成绩链表中。

5、inputData(STU_SCORE *pHead):学生成绩输入,从键盘输入课程号和相应学生的成绩,并将成绩存储到相应的课程成绩链表中。

6、scoreQuery(STU_SCORE *pStuHead):课程成绩查询,从键盘输入学号,遍历学生信息链表,找到对应学号的学生,并打印其姓名和课程成绩。

7、modify(STU_SCORE *pHead):课程成绩修改,从键盘输入学号和课程号,遍历学生信息链表,找到对应学号和课程号的学生和成绩,并修改成绩。

以上函数中使用了链表的插入和遍历操作,采用的是头插法来插入新结点,即将新结点插入到链表的头部。

以下是链表结构示意图:

head --> stu1 --> stu2 --> ... --> stuN --> head
          |        |                 |
         score    score             score
          |        |                 |
         course   course            course

每个学生结点 (STU_SCORE) 包含学生的基本信息以及一个课程成绩链表头结点 (scoreHead),课程成绩链表由课程成绩结点 (SCORE) 组成,每个课程成绩结点包含课程号和分数信息。

这段代码中使用了一些 C 语言的写法,比如使用了 malloc 分配内存,而不是使用 C++ 的 new 运算符。另外,为了简化代码,没有进行内存释放的处理,实际应用中应该在适当的位置添加释放内存的代码,避免内存泄漏问题。

struct SCORE
{
    int courseId; //课程号
    int score; //分数
    SCORE *pnext;  //下个结点
};
struct STU_SCORE
{
    char name[16]; //姓名
    int stuId; //学号
    SCORE *scoreHead;//学生课程成绩链表
    struct STU_SCORE *pnext; //下个结点
};

这个程序的主要数据结构是这两个
说白了就是链表里面嵌套了链表
外层的
STU_SCORE 表示一个学生,并且 pnext 指向了下一个学生
而其中的
SCORE *scoreHead; 指向了这个学生的第一门成绩
这个链表存储了这个学生的各门成绩
至于别的,根据函数名也很好理解
modify 修改
input 输入
sel(ect)选择
query 查询

当涉及链表时,可以通过图形表示链表的结构。以下是对于代码中的链表结构的示意图:

+----+    +----+    +----+    +----+
|Head|--->|Node|--->|Node|--->|Node|--->NULL
+----+    +----+    +----+    +----+

上面的示意图表示了一个链表,其中每个节点(Node)包含一个数据项和一个指向下一个节点的指针。头节点(Head)是链表的起始点,指向第一个节点。每个节点包含数据和指向下一个节点的指针,最后一个节点的指针指向NULL。

在代码中,STU_SCORESCORE分别表示学生信息和课程成绩,它们通过指针进行链接,形成一个链表。链表可以动态地添加和删除节点,从而实现灵活的数据结构。

请注意,这只是一个简化的示意图,实际链表可能包含更多的节点和数据。当涉及链表时,可以通过图形表示链表的结构。以下是对于代码中的链表结构的示意图:

+----+    +----+    +----+    +----+
|Head|--->|Node|--->|Node|--->|Node|--->NULL
+----+    +----+    +----+    +----+

上面的示意图表示了一个链表,其中每个节点(Node)包含一个数据项和一个指向下一个节点的指针。头节点(Head)是链表的起始点,指向第一个节点。每个节点包含数据和指向下一个节点的指针,最后一个节点的指针指向NULL。

在代码中,STU_SCORESCORE分别表示学生信息和课程成绩,它们通过指针进行链接,形成一个链表。链表可以动态地添加和删除节点,从而实现灵活的数据结构。

请注意,这只是一个简化的示意图,实际链表可能包含更多的节点和数据。

楼上不错

完美实现

源于chatGPT仅供参考

链表是一种常用的数据结构,可以用于实现学生成绩系统管理。以下是使用链表实现学生成绩系统管理的基本原理和链表结构示例:

### 原理
1. 创建一个学生节点的结构体(或类),包含学生信息和成绩等字段。
2. 使用链表来存储学生节点,每个节点包含指向下一个节点的指针。
3. 根据用户需求,通过链表的插入、删除和查找操作来实现选课登记、学生成绩输入、成绩查询和修改成绩功能。

### 链表结构示例
```cpp
// 学生节点的结构体
struct Student {
    int id;          // 学生编号
    std::string name;     // 学生姓名
    float score;     // 学生成绩
    Student* next;   // 指向下一个节点的指针
};

// 链表类
class StudentList {
private:
    Student* head;   // 头节点指针
public:
    // 构造函数初始化链表为空
    StudentList() {
        head = nullptr;
    }

    // 插入学生节点
    void insertStudent(int id, const std::string& name, float score) {
        // 创建新的学生节点
        Student* newStudent = new Student;
        newStudent->id = id;
        newStudent->name = name;
        newStudent->score = score;
        newStudent->next = nullptr;

        if (head == nullptr) {
            // 如果链表为空,将头指针指向新节点
            head = newStudent;
        } else {
            // 遍历链表找到最后一个节点
            Student* current = head;
            while (current->next != nullptr) {
                current = current->next;
            }
            // 将新节点插入到最后
            current->next = newStudent;
        }
    }

    // 查询学生成绩
    Student* findStudent(int id) {
        Student* current = head;
        while (current != nullptr) {
            if (current->id == id) {
                return current;   // 返回找到的学生节点
            }
            current = current->next;
        }
        return nullptr;   // 没有找到返回空指针
    }

    // 修改学生成绩
    void modifyScore(int id, float newScore) {
        Student* student = findStudent(id);
        if (student != nullptr) {
            student->score = newScore;
        }
    }
};

以上是一个基本的链表结构示例,你可以根据实际需要进行扩展和改进。你可以在主函数中通过调用链表类的方法来实现选课登记、学生成绩输入、成绩查询和修改成绩等功能。

希望这些信息能够对你理解如何使用链表实现学生成绩系统管理提供一些帮助。如果你有其他问题,请随时提问。

```

img


参考GPT


#include <iostream>
#include <string>
using namespace std;

class Student {
public:
    string name;
    int studentID;
    float grade;
    Student* next;

    Student(string name, int studentID, float grade) {
        this->name = name;
        this->studentID = studentID;
        this->grade = grade;
        next = nullptr;
    }
};

class StudentList {
private:
    Student* head;
public:
    StudentList() {
        head = nullptr;
    }

    void addStudent(string name, int studentID, float grade) {
        Student* newStudent = new Student(name, studentID, grade);
        if (head == nullptr) {
            head = newStudent;
        } else {
            Student* current = head;
            while (current->next != nullptr) {
                current = current->next;
            }
            current->next = newStudent;
        }
    }

    void displayStudents() {
        Student* current = head;
        while (current != nullptr) {
            cout << "Name: " << current->name << endl;
            cout << "Student ID: " << current->studentID << endl;
            cout << "Grade: " << current->grade << endl;
            cout << "---------------------------" << endl;
            current = current->next;
        }
    }

    Student* findStudent(int studentID) {
        Student* current = head;
        while (current != nullptr) {
            if (current->studentID == studentID) {
                return current;
            }
            current = current->next;
        }
        return nullptr;
    }

    void updateGrade(int studentID, float newGrade) {
        Student* student = findStudent(studentID);
        if (student != nullptr) {
            student->grade = newGrade;
            cout << "Grade updated successfully!" << endl;
        } else {
            cout << "Student not found!" << endl;
        }
    }
};



int main() {
    StudentList studentList;

    while (true) {
        cout << "《学生成绩管理系统》" << endl;
        cout << "[0]新生注册 [1]选课登记 [2]学生成绩输入 [3]成绩查询 [4]修改成绩 [5]退出" << endl;

        int choice;
        cout << "请选择操作:";
        cin >> choice;

        if (choice == 0) {
            string name;
            int studentID;
            float grade;

            cout << "请输入学生姓名:";
            cin >> name;
            cout << "请输入学生学号:";
            cin >> studentID;
            cout << "请输入学生成绩:";
            cin >> grade;

            studentList.addStudent(name, studentID, grade);
            cout << "新生注册成功!" << endl;
        } else if (choice == 1) {
            // 选课登记功能的实现
            // ...
        } else if (choice == 2) {
            // 学生成绩输入功能的实现
            // ...
        } else if (choice == 3) {
            // 成绩查询功能的实现
            // ...
        } else if (choice == 4) {
            int studentID;
            float newGrade;

            cout << "请输入学生学号:";
            cin >> studentID;
            cout << "请输入新的成绩:";
            cin >> newGrade;

            studentList.updateGrade(studentID, newGrade);
        } else if (choice == 5) {
            cout << "退出程序,谢谢使用!" << endl;
            break;
        } else {
            cout << "无效的选择!请重新选择操作。" << endl;
        }
    }

    return 0;
}

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^