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;
}
相关推荐
LCG元1 小时前
STM32L431 QSPI驱动W25Q256实战:内存映射模式配置、4字节地址模式陷阱与读写吞吐实测
stm32·单片机·嵌入式·flash
万年咸鱼1 小时前
GD32 IIC(I2C)通信详解:从原理到实战
单片机·嵌入式硬件
ESDWAN1 小时前
跨境电商网络专线怎么选?从带宽、延迟到SD-WAN部署与带宽管理的完整落地指南
开发语言·网络·php
lhbweilai1 小时前
深挖FreeRTOS内核实现(上)
stm32·单片机·链表
web打印社区1 小时前
Lodop 提示未安装或请升级:Chrome 里先分清该装哪套
开发语言·前端·javascript·chrome·websocket·http
重生之我复员之后重当黄毛1 小时前
vscode配置c/c++环境
c语言·前端·visual studio
shangan_31 小时前
C语言学习
c语言·开发语言·学习
栈溢出了1 小时前
LangGraph State 学习笔记
开发语言·人工智能·python
HEJOO91 小时前
Go 语言结构体定义与实例详解
开发语言·算法·golang