C 语言 typedef 的用法

📅 2026/7/5 2:35:44 👁️ 阅读次数 📝 编程学习
C 语言 typedef 的用法

一、typedef 是什么

typedef类型别名关键字,作用:给已存在的数据类型起一个新名字,不会创建新类型,只是原有类型的别名。 语法格式:

typedef 原类型 新类型名;

二、基础用法(简单内置类型)

1. 基础数据类型简化

#include <stdio.h> // 给int起别名Integer typedef int Integer; // 无符号整型别名 typedef unsigned int Uint; // 长整型别名 typedef long long ll; int main() { Integer a = 10; Uint b = 100; ll c = 9999999999; printf("%d %u %lld", a, b, c); return 0; }

2. 指针类型别名

普通指针

typedef int* PInt; int main() { int x = 5; PInt p = &x; // PInt等价int* *p = 10; return 0; }

易错点:typedef 指针和宏定义区别

#define P_INT int* typedef int* PInt; P_INT a, b; // 等价 int* a; int b; 宏单纯文本替换 PInt c, d; // 等价 int *c, *d; 全部都是指针

重点typedef会把整个类型绑定,宏只是文本替换,这是最常踩坑点。

三、结构体搭配 typedef(最常用场景)

C 语言原生结构体使用必须带struct关键字,typedef可以省略。

1. 标准写法

// 先定义结构体,再起别名 struct Student { char name[20]; int age; }; typedef struct Student Stu; Stu s1; // 不用写struct Student

2. 一步简写(工程最常用)

typedef struct { char name[20]; int age; } Stu; Stu s2;

结构体指针别名

typedef struct { int id; } Node, *PNode; // Node = 结构体类型 // PNode = 结构体指针 Node* Node n; PNode p = &n;

四、数组类型别名

1. 固定长度数组

// 长度100的int数组别名 Arr100 typedef int Arr100[100]; Arr100 arr; // 等价 int arr[100]; arr[0] = 1;

2. 函数参数数组简化

typedef int Vector[5]; void print(Vector v) { for(int i=0;i<5;i++) printf("%d ",v[i]); } int main() { Vector v = {1,2,3,4,5}; print(v); return 0; }

五、函数指针 typedef(复杂场景核心)

函数指针语法极繁琐,typedef是最佳简化方案。

1. 普通函数指针别名

// 原函数:int calc(int a, int b); // 给“接收两个int、返回int的函数”起别名 Func typedef int (*Func)(int, int); int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int main() { Func f1 = add; Func f2 = sub; printf("%d", f1(10,20)); return 0; }

2. 回调函数、结构体中存储函数指针

typedef void (*Callback)(int); void printNum(int x) { printf("%d", x); } typedef struct { Callback cb; // 结构体存放回调函数 } Task; int main() { Task t; t.cb = printNum; t.cb(666); return 0; }

六、枚举类型 typedef

省去每次写enum

typedef enum { RED, GREEN, BLUE } Color; Color c = RED;

七、const 和 typedef 组合(难点)

typedef别名是完整类型,const修饰规则和直接写原生类型不同。

typedef int* PInt; const PInt p; // 等价 int *const p; 指针本身不可修改,指向的值可改 // 不是 const int *p int a = 1, b = 2; const PInt p = &a; *p = 100; // 合法 p = &b; // 报错,指针只读

拆解:PInt = int*const PInt = const (int*) = int *const

八、typedef 作用与优势

1. 简化复杂类型:函数指针、多层结构体、长类型名大幅精简代码

2. 提升可读性PNodeCallback语义清晰,比裸指针好理解

3. 便于跨平台移植:

// 不同平台long长度不同,统一别名 typedef long long Int64; typedef int Int32;

更换平台时只需修改 typedef 一行,不用全局改所有变量。

4. 省略关键字:struct /enum 不用每次重复书写

九、typedef 和 #define 的核心区别

特性typedef#define
本质编译器识别的类型别名预处理器文本简单替换
指针处理typedef int* P; P a,b;两个都是指针#define P int*; P a,b;仅 a 是指针
const 绑定整体类型生效单纯文本替换,易出错
作用域遵循 C 作用域(局部 / 全局)全局生效,无作用域限制
typedef char* Str; #define STR char* Str s1, s2; // char *s1, *s2; STR s3, s4; // char *s3; char s4;

十、综合实战示例(链表标准写法)

工程中最经典的 typedef 结构体 + 指针用法:

#include <stdio.h> #include <stdlib.h> // 链表节点+节点指针一步定义 typedef struct Node { int data; struct Node *next; } Node, *List; // 创建新节点 List createNode(int val) { List newNode = (List)malloc(sizeof(Node)); newNode->data = val; newNode->next = NULL; return newNode; } int main() { List head = createNode(10); printf("%d", head->data); return 0; }

十一、常见误区总结

  1. typedef 不生成新类型,只是别名,typedef int A; intA完全等价
  2. 不要用宏代替 typedef 定义指针、数组、函数类型,极易出错
  3. const修饰 typedef 指针时,只读作用在指针本身,不是指向内容
  4. 函数指针 typedef 括号不能省略:typedef int (*F)();,少括号会变成返回指针的函数