目录
typedef理解:
总结一句话:“加不加typedef,类型是一样的“,这句话可以这样理解:
没加typedef之前如果是个数组,那么加typedef之后就是数组类型;
没加typedef之前如果是个函数指针,那么加typedef之后就是函数指针类型;
没加typedef之前如果是个指针数组,那么加typedef之后就是指针数组类型
typedef char TA[5];//定义数组类型
typedef char *TB[5];//定义指针数组类型,PA定义的变量为含5个char*指针元素的数组(指针数组类型)
typedef char *(TC[5]);//指针数组类型,因为[]的结合优先级最高,所以加不加()没啥区别,TC等价于TB
typedef char (*TD)[5];//数组指针类型
一、给已定义的变量类型起个别名
① typedef unsigned char uint8_t; //uint8_t就是unsigned char的别名,这是最基础的用法
②
struct __person
{
char name[20];
uint8_t age;
uint8_t height;
};
typedef __person person_t;
//以上两段代码也可合并为一段,如下:
typedef struct __person
{
char name[20];
uint8_t age;
uint8_t height;
}person_t;
作用是给struct __person起了个别名person_t,这种这种用法也很基础
二、定义函数指针类型
我们首先来看一下如何定义函数指针变量,然后再看如何定义函数指针类型
1、定义函数指针变量
① int (*pFunc)(char *frame, int len);
定义了一个函数指针变量pFunc,它可以指向这样的函数:返回值为int,形参为char*、int
② int *(*pFunc[5])(int len);
定义了5个函数指针变量:pFunc[0]、pFunc[1]···,它们都可以指向这样的函数:返回值为int*,形参为int
2、定义函数指针类型
定义函数指针类型,必须使用typedef,方法就是,在“定义函数指针变量”加上typedef。
typedef int (*pFunc_t)(char *frame, int len);//定义了一个类型函数指针pFunc_t
typedef int (*pFunc_t)(char *frame, int len);//定义了一个类型pFunc_t
int read_voltage(char *data, int len)
{
int voltage = 0;
···//其他功能代码
return voltage;
}
int main(void)
{
pFunc_t pHandler = read_voltage;//使用类型pFunc_t来定义函数指针变量
···//其他功能代码
}
三、定义数组指针类型
这个问题还是分两步,先看如何定义数组指针变量,再看如何定义数组指针类型
1、定义数组指针变量
① int(*pArr)[5];//定义了一个数组指针变量pArr,pArr可以指向一个int [5]的一维数组
② char(*pArr)[4][5];///定义了一个数组指针变量pArr,pArr可以指向一个char[4][5]的二维数组
int(*pArr)[5];//pArr是一个指向含5个int元素的一维数组的指针变量
int a[5] = {1,2,3,4,5};
int b[6] = {1,2,3,4,5,6};
pArr = &a;//完全合法,无警告
pArr = a;//发生编译警告,赋值时类型不匹配:a的类型为int(*),而pArr的类型为int(*)[5]
pArr = &a[0];//发生编译警告,赋值时类型不匹配:a的类型为int(*),而pArr的类型为int(*)[5]
pArr = &b;//发生编译警告,赋值时类型不匹配:&b的类型为int(*)[6],而pArr的类型为int(*)[5]
pArr = (int(*)[5])&b;//类型强制转换为int(*)[5],完全合法,无警告
2、定义数组指针类型
如同上面定义函数指针类型的方法,直接在前面加typedef即可,例如
typedef int (*pArr_t)[5];//定义了一个指针类型pArr_t,该类型的指针可以指向含5个int元素的数组
typedef int(*pArr_t)[5];//定义一个指针类型,该类型的指针可以指向含5个int元素的一维数组
int main(void)
{
int a[5] = {1,2,3,4,5};
int b[6] = {1,2,3,4,5,6};
pArr_t pA;//定义数组指针变量pA
pA= &a;//完全合法,无警告
pA= (pArr_t)&b;//类型强制转换为pArr_t,完全合法,无警告
}
四、定义数组类型
如果我们想声明一个含5个int元素的一维数组,一般会这么写:int a[5];
如果我们想声明多个含5个int元素的一维数组,一般会这么写:int a1[5], a2[5], a3[5]···,或者 a[N][5]
可见,对于定义多个一维数组,写起来略显复杂,这时,我们就应该把数组定义为一个类型,例如:
typedef int arr_t[5];//定义了一个数组类型arr_t,该类型的变量是个数组
typedef int arr_t[5];
int main(void)
{
arr_t d; //d是个数组,这一行等价于: int d[5];
arr_t b1, b2, b3;//b1, b2, b3都是数组
d[0] = 1;
d[1] = 2;
d[4] = 134;
d[5] = 253;//编译警告:下标越界
}
typedef目的简化表达式:
定义指针:
int *p1,*p2;//传统做法
int *p1,p2;//这样是定义一个指针一个整型变量
//利用typedef定义指针:
typedef int*pint;
pint p1,p2;//利用typedef定义指针的方法,因为pint经过typedef后变成一个int*类型的别名
定义结构体:
typedef struct book{
int x;
int y;
}BOOK,*PBOOK,**PPBOOK;
//BOOK:就是struct book的别名;
//PBOOK:就是struct book*的别名
//PPBOOK:就是struct book**的别名
函数指针:
指针的类型是函数类型;
定义:int (*func)(int);
返回值:int*;
函数名:func;
参数:int
定义:typedef int*(*PFUNC)(int,char*)
//在不看typedef时,int*(*PFUNC)(int,char*)
中的PFUNC就是函数的变量名,所以在typedef的作用下
PFUNC就就变成int*(*变量名)(int,char*)类型
PFUNC pfunc;//pfunc是指针变量,就相当于定义了一个int*(*pfunc)(int,char*)的函数
如何对函数指针进行初始化:
例如:PFUNC pfunc://定义一个函数指针;
步骤:
1.先定义一个函数指针,该指针返回一个空值;
2.然后指针变量指向空指针变量名(因为一个函数本身就是一个地址,所以可以直接指向一个函数,但参数和返回值的类型要一致)
int* call(int n,char*str){
return NULL;
}
pfunc=call;//初始化函数指针
//使用:
pfunc(1,"hello");//传入参数