typedef和define详解

引入

因为在写数据结构的时候,发现自己对于纯C环境下structtypedef的理解并不是很清楚 于是写下这篇blog以供总结。

typedef 详解

首先介绍一下typedeftypedef是一种用户自定义类型,creates an alias that can be used anywhere in place of a (possibly complex) type name. 主要目的是简化代码复杂度[长度方面].

注意 :typedef名称是现有类型的别名,不是新类型的声明。

在算法竞赛方面,有许多需要进行别名更改以简化代码的代码量,这时候需要使用typedef来进行简化。

具体应用如下:

1
2
3
4
5
typedef long long ll;
typedef pair <int, int> PII;
typedef pair <ll, ll> PLL;
typedef pair <double, double> PDD;
...

这时候有人会问,这样岂不是和define的作用一样?实则不然,两个关键字都有自己各自的妙处。

例如:

typedef只能进行已有类型的重命名,即给这个类型一个别名,但不可以作用于函数

define可以声明一段函数语句用来进行代码简化。

具体应用如下:

1
2
3
4
5
6
7
#define IOS {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);}
#define rep(i, a, n) for(int i = a; i < n; i++)
#define per(i, a, n) for(int i = n - 1; i >= a; i--)
#define sqr(x) (x) * (x)
#define SZ(X) (int)X.size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f

这时候有的同学会问:如果这样的话,为什么我们不直接只用define进行代码处理呢?

看下一段代码:

1
2
3
4
5
#define Pstr2 char *
typedef char *Pstr1;

Pstr1 s1, s2;
Pstr2 s3, s4;

代码中,s1, s2, s3的类型都是char *类型,即字符指针类型,但s4char类型。

这是因为define只是简单的字符串替换而typedef则是为一个类型起新名字。

最后一行变成了

1
char *s3, s4;

显而易见~

陷阱

typedefconst同时出现时,就会发生一些不一样的事情。请看以下代码:

1
2
typedef char* PSTR;
int mystrcmp(const PSTR, const PSTR);

此时const PSTR是不是相当于const char *呢?

答案是 不是 这时候实际上相当于char* const .

原因在于const给予了整个指针本身以常量性,也就是形成了常量指针char* const

简单来说,记住当consttypedef一起出现时,typedef不会是简单的字符串替换就行。

typedef与struct的结合

struct主要用来声明结构体,在C98中,如果想要定义一个结构体类型变量,必须采用以下写法:

1
2
3
4
struct node {
int a;
};
struct node s;

注意到上述代码中,定义了一个新的数据类型,这个类型是一个结构类型 如果我们直接node s是会报错的,这个类型是struct node类型。

因此我们通常采用以下写法:

1
2
3
4
typedef struct node {
int a;
}qwq;
qwq s;

这个语句做了两件事:

第一件事是声明了一个新的数据类型 — 结构类型:

1
2
3
struct node {
int a;
};

第二件事是利用typedef关键字为这个结构类型起一个别名:

1
typedef struct node qwq;

因此qwq实际上相当于struct node 这时候就可以直接使用qwq来定义变量辣~

在数据结构中,使用结构体更多的是里边的成员通过递归定义,这时候声明时,就要加上struct,只有这样才表明是一个结构类型~

参考资料