C语言struct结构体实现类定义

在 C 语言里,可以用 struct + 函数指针 来模拟"类":结构体里既放数据成员 ,也放成员函数指针。这就是 C 语言里常见的"用 struct 实现类定义"的写法。

下面把串口接收封装成一个"类"。

一、类定义(头文件风格)

cpp 复制代码
#ifndef __UART_RX_H
#define __UART_RX_H

#define TRUE   1
#define FALSE  0

#define RX_BUFFER_SIZE  256

/* 前向声明:类的类型名 */
typedef struct UartRx UartRx;

/* 类结构体:数据成员 + 成员函数指针 */
struct UartRx
{
    /* ---------- 数据成员 ---------- */
    char          buf[RX_BUFFER_SIZE];  /* 接收缓冲区       */
    unsigned int  index;                /* 写入位置         */
    unsigned char complete;             /* 接收完成标志     */
    unsigned char overflow;             /* 溢出标志         */

    /* ---------- 成员函数(函数指针) ---------- */
    void  (*init)  (UartRx *self);              /* 构造/初始化 */
    void  (*handler)(UartRx *self, char data);  /* 接收一个字节 */
    char *(*getString)(UartRx *self);           /* 取字符串     */
    void  (*reset) (UartRx *self);              /* 复位         */
};

/* 构造函数:返回一个初始化好的对象 */
void UartRx_Create(UartRx *self);

#endif

二、类的实现(.c 文件风格)

cpp 复制代码
#include <string.h>
#include "uart_rx.h"

/* ---------- 成员函数实现 ---------- */

static void UartRx_init(UartRx *self)
{
    memset(self->buf, 0, sizeof(self->buf));
    self->index    = 0;
    self->complete = FALSE;
    self->overflow = FALSE;
}

static void UartRx_handler(UartRx *self, char data)
{
    if (self->complete)                 /* 上一帧未处理 */
    {
        return;
    }

    if (data == '\n')                   /* 换行 → 一帧结束 */
    {
        self->buf[self->index] = '\0';
        self->complete = TRUE;
        return;
    }

    if (data == '\r')                   /* 忽略回车 */
    {
        return;
    }

    if (self->index < (RX_BUFFER_SIZE - 1))
    {
        self->buf[self->index++] = data;
    }
    else
    {
        self->overflow = TRUE;
        self->index    = 0;
    }
}

static char *UartRx_getString(UartRx *self)
{
    return self->buf;
}

static void UartRx_reset(UartRx *self)
{
    self->index    = 0;
    self->complete = FALSE;
    self->overflow = FALSE;
    memset(self->buf, 0, sizeof(self->buf));
}

/* ---------- 构造函数:绑定成员函数 ---------- */
void UartRx_Create(UartRx *self)
{
    self->init      = UartRx_init;
    self->handler   = UartRx_handler;
    self->getString = UartRx_getString;
    self->reset     = UartRx_reset;

    self->init(self);           /* 调用初始化 */
}

三、使用示例(像用对象一样)

cpp 复制代码
#include <stdio.h>
#include "uart_rx.h"

int main(void)
{
    UartRx uart1;                    /* 相当于"声明一个对象" */

    UartRx_Create(&uart1);           /* 相当于"构造对象" */

    const char *test = "Hello\r\n";
    const char *p = test;

    while (*p)
    {
        uart1.handler(&uart1, *p++); /* 调用"成员函数",显式传 self */

        if (uart1.complete == TRUE)
        {
            printf("收到一帧: %s\n", uart1.getString(&uart1));
            uart1.reset(&uart1);
        }
    }
    return 0;
}
相关推荐
菥蓂寻生8 小时前
STM32移植到GD32中以105为例
stm32·单片机·嵌入式硬件
§ꦿCFོ༉8 小时前
嵌入式八股文—C语言入门学习(四)
c语言·开发语言·学习
投图匠8 小时前
十种不同风格的 CTP接口 框架
开发语言·python
爱笑的k1111 小时前
nano-vllm 源码剖析:千行 Python 手写离线推理引擎的调度、显存与并行时序
开发语言·python·vllm
X1A0RAN13 小时前
PPT 图片批量处理教程:导出全部幻灯片 · 提取全部素材
开发语言·javascript·powerpoint
熊猫钓鱼>_>14 小时前
普通用户视角的端侧智能体验手记【鸿蒙心迹】
开发语言·人工智能·华为·智能手机·性能优化·ai编程·harmonyos
瑞雪兆丰年兮14 小时前
JavaWeb-day13-SpringBootWeb事务管理&AOP
java·开发语言·springboot·javaweb·事务·web·aop
布莱克60516 小时前
Swift 常量详解:从 let 到编译期优化
服务器·开发语言·ssh·swift·常量·let
布莱克60516 小时前
Swift 可选类型(Optionals)详解:从原理到实战
开发语言·安全·ssh·swift·optional·可选类型
橘为己有44117 小时前
51单片机:定时/计数器
单片机·51单片机