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 小时前
校园安全平台过等保二级,开发阶段要注意什么
开发语言·安全·php
只睡四小时8 小时前
端侧推理:face-api.js 首屏 92% 是白下载的
开发语言·javascript·人脸识别·ecmascript·tensorflow.js·face-api.js·端侧推理
yuzhiboyouye8 小时前
com.fasterxml.jackson.annotation 里最常用高频的注解,可以按“控制字段、控制格式、控制结构、控制流程”来记
java·开发语言
HAPPY酷8 小时前
C++ 内存泄漏排查:从裸 new 到 RAII 修复,附 ASan 实战
开发语言·c++
坐看风云变幻9 小时前
《嵌入式工程师的软硬件修仙之路》第 5 期|STM32/GPIO 寄存器操作:从地址映射到点亮一盏灯的全过程
stm32·单片机·嵌入式硬件
POMAGTOR9 小时前
【硬件笔记|磁吸连接器安装规范、失效分析与选型验证方案】
网络·嵌入式硬件
十年Java程序媛9 小时前
Java 面试常问 this、super:构造方法调用顺序避坑
java·开发语言·spring boot·面试·个人开发
路上有只喵9 小时前
认识元器件 ·贴片电阻· 规格书解读
嵌入式硬件·硬件架构
yuniko-n9 小时前
【JUC】内存屏障
java·开发语言
Linux运维技术栈9 小时前
近期 PHP 高危安全风险排查与多环境升级实操
开发语言·安全·php