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

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

相关推荐
caimouse1 小时前
ReactOS 窗口系统分析(24):输入法 — ime.c
c语言·reactos
for_ever_love__2 小时前
PySpark学习: 数据输出
开发语言·python·学习·spark
言乐62 小时前
Python实现自动拉人脚本示例
开发语言·windows·python·django·pygame
啊啊啊啊啊!!!!2 小时前
【c++】二叉搜索树
开发语言·c++
归去来 兮2 小时前
Python爬虫爬取数据案例
开发语言·爬虫·python
ShineWinsu2 小时前
对于 C++:C++20中Concept(概念) 与 Coroutine(协程)的解析
linux·开发语言·网络·c++·c++20·epoll
ly76892 小时前
C 语言从入门到进阶:语法、指针、内存管理与工程实践详解
c语言·开发语言
quantdash_cc3 小时前
历史数据断层与REST请求慢到崩溃?QuantDash高性能量化数据API终极解决方案
开发语言·python·缓存·php·量化·quantdash
breeze jiang3 小时前
Next.js 16 App Router 实战:从 About、Blog 动态路由到全局 404
开发语言·javascript·ecmascript