C 练习实例91(一文讲透)

更新时间:

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

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

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

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

前言

在编程学习的旅程中,实践是检验知识的唯一标准。本文将以 C 练习实例91 为例,带领读者深入理解结构体、文件操作以及排序算法的综合应用。这一实例不仅考察基础语法的掌握,更强调代码的逻辑设计能力。无论是编程初学者还是希望巩固基础的中级开发者,都能通过本文获得启发。


二级标题:实例概述与目标

C 练习实例91 的典型题目可能是这样的:

"编写一个程序,读取学生姓名、学号、成绩等信息,将其保存到文件中,并支持从文件读取数据后按成绩排序输出。"

这一实例的核心目标包括:

  1. 理解结构体(struct)的定义与使用
  2. 掌握文件的读写操作(fopen, fwrite, fread)
  3. 学习排序算法(如冒泡排序)的基本实现
  4. 综合运用上述知识点完成一个完整功能

通过解决这一实例,读者不仅能巩固基础语法,还能培养将现实问题转化为代码的逻辑思维能力。


二级标题:结构体:数据容器的"快递单"比喻

什么是结构体?

结构体(struct)可以看作是自定义的数据快递单。例如快递单需要记录收件人姓名、电话、地址等信息,结构体则允许我们将不同数据类型(如 char, int)组织成一个有意义的整体。

示例代码:

struct Student {
    char name[50];
    int id;
    float score;
};

结构体变量的声明与使用

struct Student stu1;
strcpy(stu1.name, "张三"); // 注意:字符数组用strcpy赋值
stu1.id = 1001;
stu1.score = 89.5f;

常见误区提醒

  • 结构体名前必须带 struct 关键字(除非已用 typedef 定义)
  • 字符数组需用 strcpy 等函数赋值,不可直接赋值(如 stu1.name = "李四" 是错误的)

二级标题:文件操作:与硬盘对话的艺术

文件操作如同与"数据保险柜"的交互,需要遵循严格的流程:

  1. 打开保险柜(fopen)
  2. 存取数据(fwrite/fread)
  3. 关闭保险柜(fclose)

文件操作核心函数详解

函数名功能描述模式参数示例
fopen打开文件"students.dat", "w+"
fwrite写入二进制数据sizeof(struct Student)
fread读取二进制数据&stu, 1, sizeof(struct Student)
fclose关闭文件fp

示例代码:写入数据

FILE *fp = fopen("students.dat", "wb");
struct Student stu = {"王五", 1002, 92.0};
fwrite(&stu, sizeof(struct Student), 1, fp);
fclose(fp);

关键点说明

  • 使用 wb 模式表示二进制写入,避免文本模式下的换行符转换问题
  • fwrite 的第三个参数是"元素个数",第四个是文件指针

二级标题:排序算法:让数据"排队"的智慧

冒泡排序的直观比喻

排序算法如同"整理书架":

  1. 比较相邻书籍的高度
  2. 交换位置更矮的书籍
  3. 重复操作直到有序

冒泡排序实现代码

void bubbleSort(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+1] = temp;
            }
        }
    }
}

算法优化思路

  • 提前终止:若某轮未发生交换,说明已有序
  • 双向冒泡:同时处理最大和最小值

二级标题:完整代码实现与调试技巧

完整程序代码

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

struct Student {
    char name[50];
    int id;
    float score;
};

void displayStudents(struct Student arr[], int count) {
    for (int i = 0; i < count; i++) {
        printf("Name: %s | ID: %d | Score: %.1f\n",
            arr[i].name, arr[i].id, arr[i].score);
    }
}

int main() {
    struct Student students[100];
    int count = 0;
    char choice;

    FILE *fp = fopen("students.dat", "wb+");
    if (!fp) {
        printf("文件打开失败\n");
        return 1;
    }

    // 输入学生信息
    do {
        struct Student temp;
        printf("输入姓名:");
        fgets(temp.name, 50, stdin);
        temp.name[strcspn(temp.name, "\n")] = 0; // 去除换行符

        printf("输入学号:");
        scanf("%d", &temp.id);
        getchar(); // 清除缓冲区

        printf("输入成绩:");
        scanf("%f", &temp.score);
        getchar();

        fwrite(&temp, sizeof(struct Student), 1, fp);
        count++;

        printf("继续输入(Y/N)? ");
        scanf("%c", &choice);
        getchar();
    } while (choice == 'Y' || choice == 'y');

    // 读取并排序
    fseek(fp, 0, SEEK_SET); // 移动文件指针到开头
    count = 0;
    while (fread(&students[count], sizeof(struct Student), 1, fp) == 1) {
        count++;
    }
    bubbleSort(students, count);

    displayStudents(students, count);
    fclose(fp);

    return 0;
}

调试与常见问题

  1. 文件写入后无法读取:检查 fopen 模式是否正确,确保写入后重置文件指针(fseek
  2. 字符串显示异常fgets 输入时的换行符需处理,避免截断
  3. 排序结果错误:检查比较条件是否与预期一致(升序/降序)

二级标题:进阶思考与扩展方向

性能优化建议

  • 二进制 vs 文本存储:二进制读写速度快但可读性差,文本存储更易调试
  • 内存管理:对于大量数据,考虑分批读取而非一次性加载

功能扩展方向

  1. GUI界面:使用图形库(如Windows API或跨平台库)
  2. 数据库集成:用SQLite替代文件存储
  3. 网络通信:通过TCP/IP协议实现多用户协作

结论

通过 C 练习实例91 的实践,我们不仅掌握了结构体、文件操作和排序算法的核心知识,更理解了如何将离散知识点整合为完整解决方案。编程如同搭建积木,每个概念都是基础模块,而解决问题的过程就是将这些模块组合成有意义的"建筑"。建议读者在掌握本文内容后,尝试以下练习:

  1. 将排序算法改为快速排序
  2. 添加删除学生记录的功能
  3. 实现按学号查询功能

编程之路永无止境,每一次实践都是向高手进阶的阶梯。希望本文能成为您攻克 C 练习实例91 的有力工具,并激发更多探索的热情。

最新发布