左右法则——教你如何读懂一个定义
我们看到类似int * (* (*fp1) (int) ) [10]; 这样的例子时常常会傻眼,但是根据左右法则却会很好的帮助我们解决这个难题。
什么是左右法则呢?顾名思义,就是先找到一个变量,先读它的右边,在读它的左边。
举几个例子:
int a; //读a是一个变量,再读右边,是个分号,再读左边是个int,即这个式子为整形变量。
int *p;//先读p是一个变量,再读右边,是个分号,再读左边是*,即为指针,指针里面保存的是地址,右边没有东西了就像左边看,左边是int,即指针里保存的地址类型为整形,所以这个表达式就是整形指针变量。
int **p;//照样是先读P是一个变量,再度右边,分号,再度左边是*,即为指针,只是在继续往左读的时候又遇到了*,所以指针里保存的地址是一个指针变量的地址,该指针变量保存的地址是整形,所以为整形指针的指针变量。
int a[10];//依照以上的方法先读a,再读[10],再读int,很容易就知道这是一个整形数组。
int *a[10];//参照上一条,只不过在往左读的时候遇到了指针,很显然就知道指针里保存的地址是整形的,所以为整形指针数组。
int (*a)[10];//先读a,a是一个变量,往右是括号,往左是指针,所以a为指针变量,再继续往右,遇到了数组,即指针里保存的地址是数组的地址,在继续往左,遇到了int,所以数组里的数据是整形的,所以该式子为整形数组指针变量。
int (*a)(int);//照样先读a,a是一个变量遇到了指针,指针里保存的地址是函数的地址,该函数的形参为Int,返回值也为int,所以为函数指针变量。
Int(*a[10])(int);//我们还是先找a,向右看是一个数组,向左看是指针,指针里保存的地址是函数的地址,所以为函数指针数组,该函数的形参为Int,返回值也是int。
下面我们来看难一点的:
int * (* (*fp1) (int) ) [10];
先看fp1,很容易就知道,fp1是个函数指针变量,该函数是一个形参为int,返回值为数组指针。
int *( *( *arr[5])())();
1. 从变量名开始 -------------------------------------------- arr
2. 往右看,发现是一个数组 ---------------------------------- 一个5元素的数组
3. 向左看,发现一个* --------------------------------------- 指针
4. 跳出括号,向右看,发现() -------------------------------- 不带参数的函数
5. 向左看,碰到* ------------------------------------------- (函数)返回一个指针
6. 跳出括号,向右发现() ------------------------------------ 不带参数的函数
7. 向左,发现* --------------------------------------------- (函数)返回一个指针
8. 继续向左,发现int --------------------------------------- int类型
所以这个定义为函数指针数组,该数组指向一个形参为空,返回值为函数指针的函数,该指针指向形参为空,返回值为整形指针的函数。
float ( * ( *b()) [] )();
首先从函数开始,这是一个形参为空,返回值为数组指针的函数,该指针指向函数指针数组,数组里的元素是形参为空,返回值为浮点型的函数。
void * ( *c) ( char, int (*)());
首先从C开始,c是个指针,指针的地址是函数的地址,该函数的形参是char型,还有一个形参为函数指针,该函数指针的形参为char,返回值为void*