---
title: "C++中typedef的一些思考"
date: 2026-08-23
category: "C++"
tags: ["C++", "typedef"]
summary: "引言\n\n对于typedef，初学者最常用的是在C中对struct T类型名作简化，或者将long long定义成ll，但是typedef的内容远不如此。\n\n在此篇文章中，我将记录下自己对typedef的理解，以供思考，如有不足之处欢迎指正。…"
series:
  name: "C++特性及用法"
  order: 0
---

## 引言

对于typedef，初学者最常用的是在C中对struct T类型名作简化，或者将long long定义成ll，但是typedef的内容远不如此。

在此篇文章中，我将记录下自己对typedef的理解，以供思考，如有不足之处欢迎指正。

## 正文

### typedef与define

typedef是c++中的一个关键字，作用是为类型创建一个别名以供使用，如

```cpp
struct Node{
    int x;
    struct Node* next;
};
typedef struct Node Node_t;
Node_t root;//等价于struct Node root;
```

这么看来typedef和define宏是很像的，只不过前后顺序不一样：

```cpp
#define ll long long//define的类型名在前方

typedef long long ll;
```

对于一般的情况，使用typedef或者define，效果是完全相同的。
尽管如此，我还是建议使用typedef，因为define宏经常会造成一些不安全的结果，使得结果预期和实际情况不符，具体情况这里不作展开。

typedef作为c++关键字，在编译期被处理，因而语义被编译器所理解，安全性有所保证，也方便了调试和编写代码。

### 声明与定义

想要创建一个变量，我们有两种方式，声明和定义。
声明和定义外形上很相似，某些情况下甚至一起出现，我们区分二者的方式，是看变量是否被分配内存。
声明只是告诉编译器这里有一个T类型的变量X，而定义同时还为X分配了T类型的内存空间。

```c
//变量
extern int x;//声明，未分配内存
int y；
int z=10;//两个均是定义，均分配了内存，且z被初始化

//函数
int add(int x,int y);//声明函数
int add(int x,int y){
    return x+y;
}//定义函数内容

//结构体
struct Node;//声明结构体
struct Node{
    int x;
    struct Node* next;
}//定义结构体内容
struct Node root;//定义变量且分配内存
```

>对于同一变量，可以多次声明，但是只能定义一次，这也可以作为一个判别方式

实际上，所有的定义都是声明，但声明不一定是定义。我们一般说的声明是纯声明，定义是包含定义的声明。
### typedef语法

对于typedef的深入认识，需要从其语法开始理解。

***typedef的公认语法是用在声明语法之前,表示将声明中的变量名提升至类型名***

>考虑到有"typedef int t"这种使用，我认为这里的声明还包括**无初始化的定义**

除了基础类型和指针，typedef的其他用法均是#define无法做到的

```cpp
typedef int int_t;
int_t x;//int x;

typedef int* pint_t;
pint_t y;//int* y;

typedef int array_t[10];
array_t z;//int z[10];

typedef struct Node{
    int x;
    struct Node* next;
}Node_t;
Node_t w;//struct Node w;

typedef int (*pfun_t)(int ,int );
pfun_t add;//int (*add)(int ,int );
```

很明显可以看出typedef定义的类型名在定义变量时，可以直接用变量名替代类型名的位置来获取变量的类型。

### 对于函数指针的一些理解

写这篇文章的动机来源于小彭老师讲授的std::function实现过程，中间出现了

```cpp
typedef void (*pfun);
//或者带参
typedef void (*pfun)(int,char*);
```

这让我联想到一般的定义语句如int x，使用x相当于取x内存地址中的值返回解析成int数据。如果我们把函数名当作一个变量来理解，会好理解的多：

(*pfun)表示一个函数变量，是对pfun的解引用，则**pfun**是一个指向返回值为空的无参函数的函数指针。

而实际上，函数在汇编代码中，也确实是一段内存地址，和变量的区别只是存放的段不一样，所以这样理解应该是没有什么问题的。

### 补充要点

typedef用于将类型封装成别名，别名使用时必须当作一个整体来看待。

```cpp
typedef char* str;
const str s;//const修饰str类型整体，所以s是一个const指针，但是指向的字符数组内容可以变化。
//想要指向const内容必须在typedef时定义
typedef const char* str；
```

另外，typedef不能直接模板化，模板化建议使用using。

## 小结

typedef本身确实不难，但是其背后的思想值得学习借鉴。
