【C语言】结构体typedef struct与struct的区别

这两种写法本质上都是定义结构体类型 ,但在 C 语言中有一些重要区别,主要体现在类型名、标签名(tag)、作用域和兼容性


1. 第一种写法

c 复制代码
typedef struct {

} xxx_t;

这是:

定义一个匿名结构体,并给它起一个类型别名 xxx_t

等价于:

c 复制代码
struct <匿名> {
    
};

typedef struct <匿名> xxx_t;

但是这个结构体没有名字(tag)

使用:

c 复制代码
xxx_t a;

可以。

但是:

c 复制代码
struct xxx_t b;

不可以。

因为根本不存在 struct xxx_t 这个类型。


例如:

c 复制代码
typedef struct {
    int age;
    char name[20];
} person_t;


person_t p1;   // 正确

struct person_t p2;  // 错误

2. 第二种写法

c 复制代码
struct xxx_t {

};

typedef struct xxx_t xxx_t;

这里做了两件事:

第一步:

定义一个有名字的结构体标签

c 复制代码
struct xxx_t {

};

第二步:

给它定义一个别名:

c 复制代码
typedef struct xxx_t xxx_t;

所以现在有两个名字:

名字 含义
struct xxx_t 结构体标签名
xxx_t typedef类型名

两个都可以使用:

c 复制代码
struct xxx_t a;

xxx_t b;

都合法。


3. 最大区别:前向声明

这是工程中最重要的区别。

例如链表:

c 复制代码
typedef struct node_t
{
    int data;
    struct node_t *next;

} node_t;

这里必须使用第二种。

为什么?

因为结构体里面包含自己:

c 复制代码
struct node_t *next;

编译器需要提前知道:

存在一个叫 node_t 的结构体


如果写:

c 复制代码
typedef struct {

    int data;
    struct xxx_t *next;

} xxx_t;

会失败。

因为:

c 复制代码
struct xxx_t

根本不存在。


4. 嵌套结构体引用区别

例如:

匿名结构体

c 复制代码
typedef struct
{
    int x;
} point_t;

只能:

c 复制代码
point_t p;

不能:

c 复制代码
struct point_t p;

有标签结构体

c 复制代码
typedef struct point_t
{
    int x;
} point_t;

可以:

c 复制代码
point_t p1;

struct point_t p2;

5. 实际工程推荐写法

在嵌入式项目(STM32、FreeRTOS等)中,一般推荐:

c 复制代码
typedef struct
{
    uint8_t id;
    float temperature;
    uint32_t timestamp;

} SensorData_t;

适合:

  • 数据结构
  • 配置结构
  • 参数结构

例如:

c 复制代码
SensorData_t sensor;

简洁。


对于可能扩展、需要互相引用的结构体,推荐:

c 复制代码
typedef struct Device_t Device_t;

struct Device_t
{
    uint8_t id;
    Device_t *parent;
};

或者:

c 复制代码
typedef struct Device_t
{
    uint8_t id;
    struct Device_t *parent;

} Device_t;

适合:

  • 链表
  • 驱动对象
  • C语言面向对象写法

例如很多 HAL 驱动:

c 复制代码
typedef struct
{
    SPI_HandleTypeDef *hspi;
    uint8_t state;

} SPI_Device_t;

或者:

c 复制代码
typedef struct UART_Device UART_Device;

struct UART_Device
{
    UART_Device *next;
    void (*send)(UART_Device *);
};

总结

区别 typedef struct{} xxx_t struct xxx_t{}; typedef ...
结构体是否有名字 ❌匿名 ✅有tag
能否写 struct xxx_t ❌不能 ✅可以
能否自引用 ❌困难 ✅可以
代码简洁 ✅更简洁 稍复杂
适合普通数据结构
适合链表/对象模型

在 STM32 驱动、FreeRTOS、协议栈这类大型 C 工程里,我更推荐第二种:

c 复制代码
typedef struct xxx_t xxx_t;

struct xxx_t
{
    ...
};

扩展性更好。对于简单的数据包、配置参数,第一种更常见。

相关推荐
matlab代码10 小时前
基于matlab数字图像处理的指纹识别系统【源码68期】
开发语言·matlab
matlab代码11 小时前
基于matlab的水果识别系统(苹果香蕉菠萝梨桃子)【源码65期】
开发语言·matlab
wuyk55511 小时前
从零吃透 MQTT 通信|第 8 章 FreeRTOS 多任务架构下 MQTT 工程架构,任务拆分、队列解耦、临界区保护
c语言·开发语言·stm32·学习·架构
weixin1997010801611 小时前
[特殊字符]《跨境二手ERP对接Back Market:标准化API + 7~10工作日技术合规审核实录》(附Python源码)
开发语言·python·pandas
尘客-追梦11 小时前
Day 01:插件化之前,先看清 ABI 这堵墙
开发语言·c++·qt
持敬chijing12 小时前
Python-数据类型-列表
开发语言·python·青少年编程
xx~t12 小时前
嵌入式——51单片机1
linux·c语言·单片机·嵌入式硬件·51单片机
写后端的胖头鱼13 小时前
【高频面试题】Java 基础类型 + 包装类 + String 互相转换
java·开发语言
matlab代码13 小时前
基于matlab自助水果超市水果识别收费系统(GUI界面)【源码67期】
开发语言·matlab
Navigator_Z13 小时前
LeetCode //C - 1240. Tiling a Rectangle with the Fewest Squares
c语言·算法·leetcode