#define(文本替换,无类型)typedef(编译期真类型)一句话:"define 是复制粘贴,typedef 是起真名——粘贴会贴错,真名不会。"
#define 是预处理期的纯文本替换——无类型、无作用域、无错误检查;typedef 是编译期给类型起真名——有类型、有作用域、有检查。
#define MAX 100 常量 + typedef unsigned int u32; 类型别名,各干各的#define PINT int* → PINT a, b; 文本替换成 int* a, b; → a 是指针、b 是普通 inttypedef int* PINT2; → PINT2 c, d; c 和 d 都是指针(真类型整行生效)#define ADD(a,b) a+b → ADD(1,2)*3 展开成 1+2*3=7,不是 9(不会自动加括号)#define |
typedef |
|
|---|---|---|
| 处理阶段 | 预处理(编译前,纯文本替换) | 编译期(编译器认识真类型) |
| 类型检查 | ❌ 无 | ✅ 有 |
| 作用域 | ❌ 无(全局生效到 #undef) | ✅ 有(遵循代码作用域) |
| 声明多个变量 | PINT a,b; → b 是 int,翻车 |
PINT2 c,d; → 都是指针,安全 |
| 典型用途 | 常量、宏函数、条件编译 #ifdef、头文件保护 #ifndef |
类型别名、结构体别名、固定宽度类型 uint32_t |
#define MUL(a,b) a*b → MUL(2+3,4) = 2+3*4 = 14(宏不自动加括号)typedef char* STR; STR s1,s2; 与 #define STR2 char*; STR2 s3,s4; → s4 是 char,其余都是指针(char* s3, s4; 中 * 只粘 s3)typedef struct { int x; } Point; → 声明用 Point p;;带标签的 struct Point { int x; }; → 用 struct Point p;;匿名 struct { int x; }; → 没法再声明新变量,只能定义处直接带变量名#ifdef/#ifndef、头文件重复包含保护——typedef 替代不了<stdint.h> 里用 typedef 定义的类型别名,底层类型因平台而异(32 位平台是 unsigned int,16 位单片机可能是 unsigned long);_t 是 C 标准的类型命名约定(代表 type),凡 _t 结尾都是类型名(size_t、int16_t、uint32_t…)。嵌入式爱用是因为 C 基本类型字长随平台变,固定宽度类型让位操作和跨平台移植安全#define PINT int* 多变量声明翻车;匿名结构体无别名无法后续声明| 相邻概念 | 和本主题的关系 | 孤立理解会犯的错 |
|---|---|---|
| const | 宏常量 #define MAX 100 无类型;const int MAX 有类型、进只读段 |
以为宏能替代 const——查不出类型错、不进只读段 |
| 内联函数 | 宏函数 vs 内联函数:宏无类型检查、有副作用风险,内联是真正的函数 | 以为宏函数能替代函数 |
| struct/union | typedef 给结构体起别名,省 struct 关键字 |
以为匿名结构体也能被后续引用 |
| 跨平台 | typedef + _t 约定封装固定宽度类型(uint32_t) |
直接用 unsigned int,平台一换就崩 |
2026-08-03
每主题一页,复习时只翻本目录。