typedef 为已有类型声明别名,使复杂类型(结构体、指针、数组等)在源码中更易书写与阅读。与预处理器宏不同,typedef 由编译器处理并参与类型检查。
基本用法
为 int 起别名:
typedef int Integer;
int main(void) {
Integer n = 10;
printf("%d", n);
return 0;
}语法形式为:
typedef 已有类型 新名字;内置类型的别名
typedef long long ll;
int main(void) {
ll a = 20;
printf("%lld", a);
return 0;
}结构体类型别名
未使用 typedef 时,每次须写 struct 关键字:
struct Students {
char name[50];
int ID_no;
};
struct Students s;使用 typedef 后:
typedef struct Students {
char name[50];
int ID_no;
} stu;
int main(void) {
stu s;
s.ID_no = 108;
return 0;
}亦可省略结构体标签,仅保留 typedef 引入的别名:
typedef struct {
char name[50];
int ID_no;
} stu;结构体成员布局受对齐与填充影响,typedef 不改变内存布局。
指针类型别名
typedef int* ip;
int main(void) {
int a = 10;
ip ptr = &a;
printf("%d", *ptr);
return 0;
}数组类型别名
typedef int arr[4];
int main(void) {
arr a = { 10, 20, 30, 40 };
for (int i = 0; i < 4; i++)
printf("%d ", a[i]);
return 0;
}函数指针等复杂声明同样可用 typedef 简化。
typedef 与 #define 的区别
| typedef | #define |
|---|---|
| 编译器处理,属于类型声明 | 预处理器文本替换 |
| 类型一致,利于类型检查 | 无类型语义,易误替换 |
| 可在块作用域内声明 | 通常为文件作用域 |
| 不能定义带参代码片段 | 可定义函数式宏 |
用 #define 模拟指针别名时易出错:
#define intptr int*
intptr a, b; /* 等价于 int* a, b; ,b 的类型为 int */
typedef int* intptr2;
intptr2 c, d; /* c、d 均为 int* */为类型起别名时,应优先使用 typedef。枚举类型也常与 typedef 配合使用。
适用场景
- 结构体、共用体等需反复书写的复合类型。
- 函数指针、数组类型等冗长声明。
- 在项目中统一宽度整数等可移植类型名。
本节说明了 typedef 的语法与典型用法。下一节介绍Makefile,用于组织多源文件的编译与链接。