如何用指针关联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
相关产品推荐
相关产品推荐

