C/C++:typedef用法详解
C/C++:type用法详解
用途一:类型别名
1 | typedef char* PCHAR; |
用途二:struct别名
1 | //c中不能用是struct [类名]来定义,不能只用类名,typedef可以简化代码 |
用途三: 跨平台迁移(其实也就是类型别名)
例如各平台支持最高精度不同,我们可以用typedef定义与平台无关的类型
1 | //平台一 |
在程序中只是用REAL,跨平台时可以减少代码更改数量
用途四:为复杂的声明定义一个简单别名
这部分才是重点,Linux源码中经常会看到如下定义,绝大多数人会看的一脸懵逼
1 | void * (* (*fp1) (int)) [10]; |
下边一步步来看,顺便了解一下右左原则,就可以顺利看懂上面的定义了
- 定义一个整型
int a;
- 定义一个指向整型的指针
int *p;
- 定义一个指向指针的指针,它指向的指针指向一个整型
int **pp;
- 定义一个包含10个整型数的数组
int arr[10];
- 定义一个指向包含10个整型数数组的指针
int (*pArr)[10];
到目前为止都还比较容易理解,写过C的多多少少都写过以上代码
- 定义一个指向函数的指针,被指向的函数有一个整型参数并返回整型数
int (*pfunc)(int);
- 定义一个包含10个指针的数组,其中包含的指针指向函数,这些函数有一个整型参数并返回整型
int(*arr[10])(int);
把6、7定义串起来
1 | //指向函数的指针 |
一方面很多人没用过函数指针,逐渐开始难以理解了,这是就需要理解复杂定义的右左法则
从变量名看起,先往右,再往左,碰到圆括号就调转阅读方向;括号内分析完就跳出括号,还是先右后左的顺序,如此循环。
以(6)为例:
1 | int (*pfunc)(int); |
以(7)为例:
1 | int (*arr[10])(int); |
具体怎么判断是函数指针、数组指针还是数组,可以抽象成以下几个模式:
- type (var)(...); // 变量名var与结合,被圆括号括起来,右边是参数列表。表明这是函数指针
- type (var)[]; //变量名var与结合,被圆括号括起来,右边是[]运算符。表示这是数组指针
- type (*var[])...; // 变量名var先与[]结合,说明这是一个数组(至于数组包含的是什么,由旁边的修饰决定)
到这里,已经具备了读懂复杂定义的全部能力,回来看一下本节开头的几个复杂定义:
一、 1
2
3
4
5
6void* (*(*fp1)(int))[10];
//找到变量名fp1,先往右为圆括号,调转阅读方向,往左为‘*’,则表示fp1为一个指针
//跳出圆括号,先往右为圆括号,表示fp1是函数指针,调转阅读方向,往左为‘*’,表示fp1为函数指针,函数参数为一个int类型,返回值为指针
//跳出圆括号,先往右为方括号,表示函数返回值为数组指针,在往左为void*,即数组内包含的类型为void *.
//即:fp1是一个指向函数的指针,这个函数接受一个整型参数,并返回含有10个(void*)类型的数组的指针1
2
3
4
5
6float (* (*fp2) (int, int, float)) (int);
//找到变量名fp2,先往右为圆括号,调转阅读方向,向左为‘*’,表示fp为指针
//跳出圆括号,先往右为圆括号,表示fp2为函数指针,调转阅读方向,往右为‘*’,表示fp2函数指针指向的函数,有int、int、float类型的三个参数,并且返回值为指针
//跳出圆括号,先往右为圆括号,调转阅读方向,往左为float,表示返回值指针为函数指针,该函数指针接受一个int类型参数,返回一个float类型值
//即:fp2是一个指向函数的指针,这个指针接受三个参数(int,int,float),并返回一个函数指针,这个函数指针接受一个参数(int),返回一个float。1
2
3
4
5
6
7
8typedef double (* (* (*fp3) ()) [10]) ();
//先无视typedef
//找到变量名fp3,先往右为右括号,调转阅读方向,向左为‘*’,表示fp3为一个指针
//跳出圆括号,先往右为圆括号,调转阅读方向,往左为‘*’,表示fp3是一个函数指针,这个函数指针无参数,且返回值为指针
//跳出圆括号,先往右为方括号,表示返回指针为数组指针,再往右为‘*’,表示数组内包含的为指针
//跳出圆括号,先往右为圆括号,表示数组内的指针为函数指针,该指向的函数参数列表为空,再往左为double,表示该函数返回值类型为double
//即:fp3为一个无参的函数指针,该函数的返回值为包含10个元素的数组指针,该数组内的元素为函数指针,数组内的函数指针不接收参数并返回double值fp3 a
。
四、 1
2
3
4
5
6int (* (*fp4()) [10]) ();
//先找到变量名fp4,先往右为圆括号,调转阅读方向为‘*’,表示fp4为函数,返回值为指针
//跳出圆括号,先往右为方括号,表示返回的指针为数组指针,往右为‘*’,表示该数组内包含的元素为指针
//跳出圆括号,先往右为圆括号,表示数组内指针为函数指针(无参),再往右为int,表示返回值为int
//即:fp4为无参函数,返回包含10个函数指针的数组的指针,数组内的函数指针无参,返回值为int类型