引言

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

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

正文

typedef与define

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

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

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

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

typedef long long ll;

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

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

声明与定义

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

//变量
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无法做到的

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实现过程,中间出现了

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

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

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

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

补充要点

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

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

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

小结

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