【C语言】结构体模块化编程

在模块化编程中,结构体作为数据存储的主要方式之一,它不仅用于存储数据,还帮助实现代码的封装与隐私保护。通过将结构体定义放在 .c 文件中并使用 get_set_ 函数进行访问,我们可以实现对结构体数据的保护,同时降低模块之间的耦合度,提高内聚性。接下来,我们将详细讲解结构体的规范格式、get_set_ 函数的设计、函数设计规范、以及如何在 .c 文件中定义结构体来保护数据隐私。

目录

    • [1. 结构体规范格式](#1. 结构体规范格式)
    • [2. get_ 和 set_ 函数设计](#2. get_ 和 set_ 函数设计)
    • [3. 函数设计规范表格](#3. 函数设计规范表格)
    • [4. 增加使用代码](#4. 增加使用代码)
      • [4.1 `car.c` 文件](#4.1 car.c 文件)
        • [4.1.1 关键说明](#4.1.1 关键说明)
      • [4.2 `car.h` 文件](#4.2 car.h 文件)
      • [4.3 `main.c` 文件](#4.3 main.c 文件)
      • [4.4 运行结果](#4.4 运行结果)
    • [5. 内聚与耦合的部分讲解](#5. 内聚与耦合的部分讲解)
    • [6. 结束语](#6. 结束语)
    • 相关文章:

1. 结构体规范格式

结构体的基本格式遵循规范,建议将定义放在 .c 文件中,以保护数据隐私,同时通过 get_set_ 函数实现对成员的访问与修改。以下是常见结构体的定义格式:

c 复制代码
struct StructName {
    type member1;  // 成员变量1
    type member2;  // 成员变量2
    // 可继续添加其他成员变量
} name1, name2, ...; // 可同时声明多个结构体变量

示例:车辆信息结构体

c 复制代码
struct Car {
    char model[50];     // 车辆型号
    int speed;          // 速度
    int fuel_level;     // 燃油量
};

2. get_ 和 set_ 函数设计

模块化编程中,通过 get_set_ 函数访问结构体的成员,可以:

  1. 保护隐私:防止外部直接修改成员变量。
  2. 增强安全性:添加输入校验。
  3. 提高灵活性:支持后续扩展。

函数设计规则

  • set_ 函数用于设置结构体成员,通常无返回值。
  • get_ 函数用于获取成员,返回对应成员的值。
  • 私有函数通过 static 修饰,仅能在定义文件中使用。

示例

c 复制代码
void set_car_model(struct Car *car, const char *model);
const char* get_car_model(const struct Car *car);

void set_car_speed(struct Car *car, int speed);
int get_car_speed(const struct Car *car);

void set_car_fuel(struct Car *car, int fuel_level);
int get_car_fuel(const struct Car *car);

3. 函数设计规范表格

函数名称 功能 参数类型 返回值类型
set_car_model 设置车辆型号 struct Car *car, const char *model 无返回值
set_car_speed 设置车辆速度 struct Car *car, int speed 无返回值
set_car_fuel 设置车辆燃油量 struct Car *car, int fuel_level 无返回值
get_car_model 获取车辆型号 const struct Car *car const char* (车型)
get_car_speed 获取车辆速度 const struct Car *car int (速度)
get_car_fuel 获取车辆燃油量 const struct Car *car int (燃油量)
_reset_car_fuel 重置车辆燃油量(私有) struct Car *car 无返回值

4. 增加使用代码

4.1 car.c 文件

c 复制代码
#include "car.h"
#include <string.h>

// 静态私有函数
static void _reset_car_fuel(struct Car *car) {
    car->fuel_level = 0;
}

// 设置函数
void set_car_model(struct Car *car, const char *model) {
    strncpy(car->model, model, sizeof(car->model) - 1);
    car->model[sizeof(car->model) - 1] = '\0';
}

void set_car_speed(struct Car *car, int speed) {
    car->speed = (speed > 0) ? speed : 0;  // 校验速度为正
}

void set_car_fuel(struct Car *car, int fuel_level) {
    car->fuel_level = (fuel_level >= 0) ? fuel_level : 0;  // 校验燃油量非负
}

// 获取函数
const char* get_car_model(const struct Car *car) {
    return car->model;
}

int get_car_speed(const struct Car *car) {
    return car->speed;
}

int get_car_fuel(const struct Car *car) {
    return car->fuel_level;
}

// 公开函数调用私有函数
void reset_car_fuel(struct Car *car) {
    _reset_car_fuel(car);
}
4.1.1 关键说明
  1. static 的作用
    • car.c 中,_reset_car_fuel 函数被声明为 static,它只能在 car.c 文件内调用,无法被 main.c 或其他文件直接访问。
    • 这种设计可以隐藏实现细节,保护数据的隐私和安全,避免其他模块错误地直接调用私有函数。
  2. 公共函数和私有函数的协作
    • reset_car_fuel 是公开的接口,它调用了私有的 _reset_car_fuel 函数,从而实现了对燃油数据的安全重置。
  3. main.c 中的使用
    • 只能调用公共函数,例如 set_car_modelreset_car_fuel 等。
    • 直接调用 static 函数(如 _reset_car_fuel)会导致编译错误,确保数据和逻辑封装的完整性。

这种设计展示了模块化编程中隐私保护和安全设计的理念,同时满足了实际项目开发的需求。

4.2 car.h 文件

c 复制代码
#ifndef CAR_H
#define CAR_H

struct Car {
    char model[50];
    int speed;
    int fuel_level;
};

// 公共函数声明
void set_car_model(struct Car *car, const char *model);
void set_car_speed(struct Car *car, int speed);
void set_car_fuel(struct Car *car, int fuel_level);

const char* get_car_model(const struct Car *car);
int get_car_speed(const struct Car *car);
int get_car_fuel(const struct Car *car);

void reset_car_fuel(struct Car *car);  // 公开函数
#endif

4.3 main.c 文件

c 复制代码
#include "car.h"
#include <stdio.h>

int main() {
    struct Car my_car;

    // 使用公开函数设置数据
    set_car_model(&my_car, "Tesla Model S");
    set_car_speed(&my_car, 100);
    set_car_fuel(&my_car, 80);

    // 使用公开函数获取数据
    printf("Model: %s\n", get_car_model(&my_car));
    printf("Speed: %d\n", get_car_speed(&my_car));
    printf("Fuel Level: %d\n", get_car_fuel(&my_car));

    // 重置燃油量
    reset_car_fuel(&my_car);
    printf("Fuel Level after reset: %d\n", get_car_fuel(&my_car));

    return 0;
}

4.4 运行结果

当运行上述代码时,输出如下:

Model: Tesla Model S
Speed: 100
Fuel Level: 80
Fuel Level after reset: 0

5. 内聚与耦合的部分讲解

内聚(Cohesion)

内聚指模块内部元素之间的关联程度。结构体模块化编程的内聚性体现在:

  1. 逻辑统一car.c 文件封装了车辆相关的数据结构及操作函数。
  2. 功能完整 :所有与 Car 相关的操作均通过该模块完成,避免了外部直接操作数据的情况。

耦合(Coupling)

耦合指模块之间的依赖程度。降低耦合的设计体现在:

  1. 接口统一 :通过 get_set_ 函数提供统一接口,隐藏数据实现细节。
  2. 减少直接依赖 :外部仅需包含 car.h,无需了解 car.c 的实现细节。

内聚与耦合的平衡

  • 提高内聚性可以增强模块的独立性,但需要注意接口的设计,避免过多暴露实现细节。
  • 降低耦合性可提高模块的复用性,但不能过度简化接口,以免增加使用复杂度。

6. 结束语

  1. 本节内容已经全部介绍完毕,希望通过这篇文章,大家对C语言结构体模块化编程有了更深入的理解和认识。
  2. 感谢各位的阅读和支持,如果觉得这篇文章对你有帮助,请不要吝惜你的点赞和评论 ,这对我们非常重要。再次感谢大家的关注和支持点我关注❤️

相关文章:

相关推荐
xianwu5433 分钟前
反向代理模块。。
开发语言·网络·数据库·c++·mysql
Winston-Tao5 分钟前
skynet 源码阅读 -- 「揭秘 Skynet 网络通讯」
c语言·网络编程·epoll·skynet
Wyyyyy_m11 分钟前
2025寒假训练——天梯赛训练(1)
c++·算法
weixin_3077791330 分钟前
C++和Python实现SQL Server数据库导出数据到S3并导入Redshift数据仓库
数据库·c++·数据仓库·python·sqlserver
新知图书1 小时前
Linux C\C++编程-Linux系统的字符集
linux·c语言·c++
利刃大大1 小时前
【Linux系统编程】二、Linux进程概念
linux·c语言·进程·系统编程
别NULL2 小时前
机试题——最小矩阵宽度
c++·算法·矩阵
Icomi_2 小时前
【外文原版书阅读】《机器学习前置知识》1.线性代数的重要性,初识向量以及向量加法
c语言·c++·人工智能·深度学习·神经网络·机器学习·计算机视觉
apocelipes2 小时前
Linux glibc自带哈希表的用例及性能测试
c语言·c++·哈希表·linux编程
Tanecious.3 小时前
C语言--分支循环实践:猜数字游戏
android·c语言·游戏