C 练习实例97(千字长文)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

前言

在 C 语言的学习过程中,练习实例是巩固知识点的绝佳工具。C 练习实例97 以“学生信息管理系统”为核心,通过结构体、文件操作、算法排序等综合技术,帮助开发者理解如何将零散的语法知识整合为一个完整程序。本篇文章将从基础概念到实战案例,逐步拆解这一实例的实现逻辑,特别适合编程初学者和中级开发者进阶学习。


结构体基础:构建数据容器

什么是结构体?

结构体(Structure)是 C 语言中一种自定义的数据类型,允许将不同类型的数据组合成一个逻辑单元。例如,一个学生的姓名、学号、成绩可以封装在同一个结构体中,方便统一管理。

比喻:结构体就像一个档案柜,每个抽屉(成员变量)存放不同类型的信息,而柜子的标签(结构体名)帮助开发者快速定位数据。

struct Student {  
    int id;          // 学号  
    char name[50];   // 姓名  
    float score;     // 成绩  
};  

如何声明和使用结构体?

  1. 定义结构体类型:使用 struct 关键字定义结构体模板。
  2. 声明变量:通过结构体类型创建具体变量。
  3. 访问成员:使用 . 运算符操作成员变量。
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");  
}  

关键知识点总结

  1. 结构体:将相关数据封装为逻辑单元,提升代码可读性。
  2. 指针与数组:高效管理大量数据,避免重复代码。
  3. 文件操作:实现数据持久化,确保程序退出后数据不丢失。
  4. 排序算法:按需对结构体数组进行排序,提升信息管理效率。

结论

通过 C 练习实例97 的学习,开发者不仅能掌握结构体、文件操作等核心语法,更能理解如何将零散的知识整合为一个完整项目。建议读者在理解代码逻辑后,尝试以下进阶任务:

  • 添加删除学生功能
  • 实现按学号或姓名排序
  • 使用二分查找快速定位记录

编程的本质是“将复杂问题拆解为简单步骤”,希望本文能帮助你迈出这一步!

最新发布