相信学习过c语言的很多同学都对typedef很陌生,感觉它离自己很遥远,自己很少用到。但实际上,我们看很多地方,包括很多大神级别的代码中,它却又经常使用。今天我们就详细描述下它,使我们对它有一个更深的认识。
一,定义和作用
typedef:为现有类型创建别名,定义易于记忆的类型别名,可以理解为一个类型的同义词。首先使用typedef可以起到加强标志的作用,让我们更容易记忆;再次使用typedef可以让我们对一些复杂类型进行简化,便于我们使用和理解;最后使用typedef可以当我们类型调整时候,只需修改一处代码即可完成所有修改。
二,用法
为基础类型创建别名:
- typedef int result;
- 那么我们就可以进行如下使用:
- result a = 100;
- result *p;
- result ab[4];
cpp
int main(int argc, char *argv[]) {
typedef int result;
result a = 100;
printf("the a value is %d\n", a);
return 0;
}
数组类型别名
- typedef char array[10];
- array a1, a2; //那么a1和a2都是含有10个char类型元素的数组
cpp
int main(int argc, char *argv[]) {
typedef char array[10];
array a1 = "tpc good";
printf("the a1 is %s\n", a1);
return 0;
}
指针类型别名
- typedef int * ptr;
- ptr p1, p2; //那么p1和p2都是int类型指针
cpp
int main(int argc, char *argv[]) {
typedef int *ptr;
ptr p1,p2;
int a = 100;
p1 = &a;
p2 = &a;
printf("the value of *p1 is %d, *p2 is %d\n", *p1, *p2);
return 0;
}
函数类型别名
- typedef int * (*fun)();
- fun f1; //那么f1是代表为返回一个int指针的函数类型指针
cpp
int *test1(){
int *p = (int *)malloc(sizeof(int));
*p = 100;
return p;
}
int main(int argc, char *argv[]) {
typedef int *(*fun)();
fun f1 = test1;
int *p = f1();
printf("the function return value is %d\n", *p);
free(p);
return 0;
}
三、进阶用法
3.1,typedef和结构体
我们使用结构体的时候,经常用到typedef:
cpp
typedef struct student{
char * name;
int age;
int score;
char *address;
} stu;
这个时候,stu就相当于struct student的类型别名,我们直接可以如下使用:
cpp
stu stu1;
stu1.name = NULL;
stu1.age = 12;
stu1.score = 98;
stu1.address= NULL;
重点1:
有些时候,我们使用如下形式进行类型别名:
cpp
typedef struct student{
char * name;
int age;
int score;
char *address;
} student;
那么这个时候下面两种方式进行变量定义都是一样的:
struct student stu1;
student stu1;
我们不建议这样使用,一般建议类型别与结构体名字不同。
重点2:
如下两个student代表的意思是不同的:
cpp
typedef struct student{
char * name;
int age;
int score;
char *address;
} student;
cpp
struct student{
char * name;
int age;
int score;
char *address;
} student;
第一个student代表结构体student的类型别名;第二student代表结构体student定义的一个变量。
重点3:
类型别名是不能直接作为结构体指针使用:
cpp
int main(int argc, char *argv[]) {
struct student{
char * name;
int age;
int score;
char *address;
student *next;
} student;
return 0;
}
这是因为这里的stu是结构体student的类型新名字,现在结构体struct都没有声明完成,怎么可以用来使用定义指针。我们可以进行如下修改:
cpp
int main(int argc, char *argv[]) {
typedef struct student stu;
struct student{
char * name;
int age;
int score;
char *address;
stu *next;
};
return 0;
}
重点4:
typedef和结构体的规范做法:
cpp
struct student{
char * name;
int age;
int score;
char *address;
stuct student *next;
};
typedef student stu;
typedef student * pstu;
3.2,typedef和复杂类型
我们使用linux编程的时候,会遇到一个非常重要的函数signal,也就是系统发生中断的时候会调用的函数。
这个函数的标准声明如下:
void (*signal(int sig, void(* func)(int)))(int)
signal是一个函数,它还返回一个函数指针(指向的函数接受一个int参数并返回void)。
下面我们通过typedef进行简化:
typedef void (*pfun)(int)
那么signal函数将简化如下:
pfun signal (int, pfun);