You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用指针关联C语言中的学生与课程结构体?附待补全代码

解决C语言中用指针关联Student与Courses结构体的问题

嘿,我来帮你搞定这个指针关联结构体的问题!核心思路是给学生结构体添加一个指针数组,用来指向他所选的课程,这样就能通过指针直接把学生和课程绑定起来。下面是完整的实现方案:

第一步:修改结构体定义

首先得调整原有的结构体,让学生能存储指向课程的指针,同时加一个计数器记录已选课程的数量:

#include <string.h>
#include <stdio.h>
#include <stdlib.h> // 用到atoi函数

// 提前声明Courses结构体,避免student引用时未定义
struct Courses;

struct student {
    char name[50], surname[50];
    int id, year;
    struct Courses* enrolled_courses[4]; // 指针数组:存储所选课程的指针
    int course_count; // 记录已选课程的数量
};

struct Courses {
    char course_name[50];
    int course_id, course_credit;
};

第二步:实现核心功能函数

我们需要两个辅助函数来快速找到对应ID的学生和课程,避免重复写循环:

// 根据ID查找学生,返回指针(找不到返回NULL)
struct student* find_student(struct student std[], int total_students, int target_id) {
    for (int i = 0; i < total_students; i++) {
        if (std[i].id == target_id) {
            return &std[i];
        }
    }
    return NULL;
}

// 根据ID查找课程,返回指针(找不到返回NULL)
struct Courses* find_course(struct Courses crs[], int total_courses, int target_id) {
    for (int i = 0; i < total_courses; i++) {
        if (crs[i].course_id == target_id) {
            return &crs[i];
        }
    }
    return NULL;
}

第三步:完整程序实现

把输入、选课逻辑和最终打印整合起来,下面是完整代码:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

struct Courses;

struct student {
    char name[50], surname[50];
    int id, year;
    struct Courses* enrolled_courses[4];
    int course_count;
};

struct Courses {
    char course_name[50];
    int course_id, course_credit;
};

struct student* find_student(struct student std[], int total_students, int target_id) {
    for (int i = 0; i < total_students; i++) {
        if (std[i].id == target_id) {
            return &std[i];
        }
    }
    return NULL;
}

struct Courses* find_course(struct Courses crs[], int total_courses, int target_id) {
    for (int i = 0; i < total_courses; i++) {
        if (crs[i].course_id == target_id) {
            return &crs[i];
        }
    }
    return NULL;
}

int main() {
    struct student std[2];
    struct Courses crs[4];
    char input_buffer[10];
    int student_id, course_id;

    // 初始化学生的课程计数为0
    for (int i = 0; i < 2; i++) {
        std[i].course_count = 0;
    }

    // 输入学生信息
    printf("Enter information of students:\n");
    for (int i = 0; i < 2; i++) {
        printf("Enter student id:");
        scanf("%d", &std[i].id);
        printf("Enter first name:");
        scanf("%s", std[i].name);
        printf("Enter last name:");
        scanf("%s", std[i].surname);
        printf("Enter year:");
        scanf("%d", &std[i].year);
        printf("\n");
    }

    // 输入课程信息(原代码里scanf("%s",&crs[i].course_name)多了&,已修正)
    printf("Enter information of courses:\n");
    for (int i = 0; i < 4; i++) {
        printf("course id:");
        scanf("%d", &crs[i].course_id);
        printf("course name:");
        scanf("%s", crs[i].course_name);
        printf("course credit:");
        scanf("%d", &crs[i].course_credit);
        printf("\n");
    }

    // 显示初始信息
    printf("-Displaying Courses-\n");
    for (int i = 0; i < 4; i++) {
        printf("course id:%d\n", crs[i].course_id);
        printf("course name :%s\n", crs[i].course_name);
        printf("course credit:%d\n", crs[i].course_credit);
        printf("\n");
    }

    printf("-Display Students-\n");
    for (int i = 0; i < 2; i++) {
        printf("student id:%d\n", std[i].id);
        printf("student name and surname:%s %s\n", std[i].name, std[i].surname);
        printf("year:%d\n", std[i].year);
        printf("\n");
    }

    // 选课操作循环
    printf("\n--- Add Course Operation ---\n");
    printf("Type 'exit' to stop adding courses.\n");
    while (1) {
        printf("Enter student ID: ");
        scanf("%s", input_buffer);
        // 判断是否输入exit
        if (strcmp(input_buffer, "exit") == 0) {
            break;
        }
        // 把字符串转成整数ID
        student_id = atoi(input_buffer);

        printf("Enter course ID: ");
        scanf("%d", &course_id);

        // 查找对应的学生和课程
        struct student* selected_student = find_student(std, 2, student_id);
        struct Courses* selected_course = find_course(crs, 4, course_id);

        // 边界检查
        if (selected_student == NULL) {
            printf("❌ Error: Student with ID %d doesn't exist!\n", student_id);
            continue;
        }
        if (selected_course == NULL) {
            printf("❌ Error: Course with ID %d doesn't exist!\n", course_id);
            continue;
        }
        // 检查是否已选过该课程
        for (int i = 0; i < selected_student->course_count; i++) {
            if (selected_student->enrolled_courses[i] == selected_course) {
                printf("❌ Error: Student %d already enrolled in course %d!\n", student_id, course_id);
                goto next_loop; // 跳过后续操作
            }
        }
        // 检查是否达到选课上限
        if (selected_student->course_count >= 4) {
            printf("❌ Error: Student %d can't enroll more than 4 courses!\n", student_id);
            continue;
        }

        // 关联课程指针到学生
        selected_student->enrolled_courses[selected_student->course_count] = selected_course;
        selected_student->course_count++;
        printf("✅ Success! Added course %d to student %d.\n", course_id, student_id);

        next_loop:;
    }

    // 打印最终选课信息
    printf("\n--- Final Student Enrollment Details ---\n");
    for (int i = 0; i < 2; i++) {
        printf("📝 Student ID: %d\n", std[i].id);
        printf("Name: %s %s\n", std[i].name, std[i].surname);
        printf("Year: %d\n", std[i].year);
        printf("Enrolled Courses (%d):\n", std[i].course_count);
        for (int j = 0; j < std[i].course_count; j++) {
            struct Courses* course = std[i].enrolled_courses[j];
            printf("  - Course ID: %d, Name: %s, Credit: %d\n", course->course_id, course->course_name, course->course_credit);
        }
        printf("\n");
    }

    return 0;
}

关键逻辑说明

  • 指针关联原理:student结构体里的enrolled_courses是指针数组,每个元素直接指向一个Courses结构体实例,这样学生和课程就通过指针建立了关联,不需要复制整个课程数据。
  • 输入处理:用字符串接收学生ID输入,方便判断是否输入exit,避免整数输入导致的程序异常。
  • 边界检查:涵盖了学生/课程不存在、重复选课、选课上限等情况,让程序更健壮。

内容的提问来源于stack exchange,提问作者DarkSpy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 15:48:02