C 练习实例97(千字长文)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在 C 语言的学习过程中,练习实例是巩固知识点的绝佳工具。C 练习实例97 以“学生信息管理系统”为核心,通过结构体、文件操作、算法排序等综合技术,帮助开发者理解如何将零散的语法知识整合为一个完整程序。本篇文章将从基础概念到实战案例,逐步拆解这一实例的实现逻辑,特别适合编程初学者和中级开发者进阶学习。
结构体基础:构建数据容器
什么是结构体?
结构体(Structure)是 C 语言中一种自定义的数据类型,允许将不同类型的数据组合成一个逻辑单元。例如,一个学生的姓名、学号、成绩可以封装在同一个结构体中,方便统一管理。
比喻:结构体就像一个档案柜,每个抽屉(成员变量)存放不同类型的信息,而柜子的标签(结构体名)帮助开发者快速定位数据。
struct Student {
int id; // 学号
char name[50]; // 姓名
float score; // 成绩
};
如何声明和使用结构体?
- 定义结构体类型:使用
struct
关键字定义结构体模板。 - 声明变量:通过结构体类型创建具体变量。
- 访问成员:使用
.
运算符操作成员变量。
struct Student student1;
student1.id = 1001;
strcpy(student1.name, "张三");
student1.score = 90.5;
指针与结构体数组:高效管理数据集合
指针在结构体中的作用
当需要处理大量学生信息时,直接使用多个结构体变量效率低下。此时,结构体数组和指针能提供更灵活的解决方案。
比喻:指针就像档案柜的钥匙,可以快速打开不同抽屉,而结构体数组则是由多个相同规格的档案柜组成的长列。
struct Student students[100]; // 定义容量为100的数组
struct Student *p = &students[0]; // 指向第一个元素的指针
p->score = 85.0; // 通过指针访问成员
动态内存分配(可选技巧)
如果数据量不确定,可以使用 malloc
动态分配内存:
struct Student *students = (struct Student*)malloc(size * sizeof(struct Student));
文件操作:数据持久化存储
文件读写的核心函数
C 练习实例97 要求将学生信息保存到文件中,以便程序退出后数据不丢失。关键函数包括:
fopen()
:打开文件(模式如 "r" 读、"w" 写、"a" 追加)。fwrite()
:将内存数据写入文件。fread()
:从文件读取数据到内存。
比喻:文件操作如同将档案柜中的资料存入保险柜(文件),下次需要时再取出。
写入文件示例:
FILE *fp = fopen("students.dat", "wb"); // 二进制写模式
fwrite(&student1, sizeof(struct Student), 1, fp);
fclose(fp);
读取文件示例:
FILE *fp = fopen("students.dat", "rb"); // 二进制读模式
fread(&student2, sizeof(struct Student), 1, fp);
fclose(fp);
排序算法:结构体数组的高效管理
冒泡排序的实现
在学生信息管理系统中,按成绩排序是一个常见需求。通过冒泡排序算法,可以对结构体数组进行排序:
void sortStudents(struct Student arr[], int n) {
for (int i = 0; i < n-1; i++) {
for (int j=0; j < n-i-1; j++) {
if (arr[j].score < arr[j+1].score) {
// 交换两个结构体
struct Student temp = arr[j];
arr[j] = arr[j+1];
arr[j] = temp;
}
}
}
}
注意事项:
- 需要根据具体排序条件(如按学号、姓名或成绩)调整比较逻辑。
- 对于大规模数据,可考虑更高效的排序算法(如快速排序)。
完整代码解析:从零构建学生管理系统
以下是一个简化版的 C 练习实例97 实现代码,包含添加、显示、排序和保存数据的功能:
#include <stdio.h>
#include <string.h>
#define MAX_STUDENTS 100
struct Student {
int id;
char name[50];
float score;
};
void addStudent(struct Student students[], int *count);
void displayStudents(struct Student students[], int count);
void saveToFile(struct Student students[], int count);
int main() {
struct Student students[MAX_STUDENTS];
int count = 0;
int choice;
while (1) {
printf("\n学生管理系统\n");
printf("1. 添加学生\n2. 显示学生\n3. 保存数据\n4. 退出\n");
scanf("%d", &choice);
switch(choice) {
case 1:
if (count < MAX_STUDENTS) {
addStudent(students, &count);
} else {
printf("学生数量已达上限!\n");
}
break;
case 2:
displayStudents(students, count);
break;
case 3:
saveToFile(students, count);
break;
case 4:
return 0;
default:
printf("无效选项,请重新输入!\n");
}
}
}
void addStudent(struct Student students[], int *count) {
printf("请输入学号:");
scanf("%d", &students[*count].id);
printf("请输入姓名:");
scanf("%s", students[*count].name);
printf("请输入成绩:");
scanf("%f", &students[*count].score);
(*count)++;
}
void displayStudents(struct Student students[], int count) {
printf("\n学号\t姓名\t成绩\n");
for (int i = 0; i < count; i++) {
printf("%d\t%s\t%.1f\n",
students[i].id,
students[i].name,
students[i].score);
}
}
void saveToFile(struct Student students[], int count) {
FILE *fp = fopen("students.dat", "wb");
if (fp == NULL) {
printf("文件打开失败!\n");
return;
}
fwrite(students, sizeof(struct Student), count, fp);
fclose(fp);
printf("数据已保存!\n");
}
关键知识点总结
- 结构体:将相关数据封装为逻辑单元,提升代码可读性。
- 指针与数组:高效管理大量数据,避免重复代码。
- 文件操作:实现数据持久化,确保程序退出后数据不丢失。
- 排序算法:按需对结构体数组进行排序,提升信息管理效率。
结论
通过 C 练习实例97 的学习,开发者不仅能掌握结构体、文件操作等核心语法,更能理解如何将零散的知识整合为一个完整项目。建议读者在理解代码逻辑后,尝试以下进阶任务:
- 添加删除学生功能
- 实现按学号或姓名排序
- 使用二分查找快速定位记录
编程的本质是“将复杂问题拆解为简单步骤”,希望本文能帮助你迈出这一步!