【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
{
    ...
};

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

相关推荐
朝朝辞暮i8 小时前
C++ 第 23 课:class —— 开始真正进入面向对象
开发语言·c++·算法
小师兄吃牛肉9 小时前
C语言篇:宏
c语言·开发语言
郑同学的笔记9 小时前
【c++随笔28】strcmp 和 memcmp对比
开发语言·c++
炸膛坦客9 小时前
单片机开发工具篇:(十四)配置输出 .map 文件及其本地路径
c语言·单片机·嵌入式硬件
言乐610 小时前
Python根据无法识别搜索词找出可能输入内容模型
开发语言·python·django·virtualenv·pygame
weixin_3077791310 小时前
有限产能智能排产与动态重排智能体:从需求解构到技术实现
开发语言·人工智能·算法·架构
kakakahahahaha10 小时前
Windows C盘临时文件清理:%temp%、Windows Temp、Prefetch、Windows.old与hiberfil.sys处理指南
c语言·开发语言·windows
朝朝辞暮i10 小时前
C++ 第 27 课:智能指针 shared_ptr
开发语言·c++·算法
朝朝辞暮i10 小时前
C++ 第 29 课:回调函数 Callback
开发语言·c++·算法
笨笨饿10 小时前
140_AI新手村MCP与Skills是干嘛的
开发语言·人工智能·python·stm32·单片机·嵌入式硬件·物联网