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,用于组织多源文件的编译与链接。