一、指针函数和函数指针
1.1 指针函数
指针函数
,其实就是返回值为指针的函数
例如:
long *func(int)
它是一个名为func,返回值为long *,参数为int的指针函数
1.2 函数指针
就像
数组名
是指向数组第一个元素的常指针
一样,函数名
是指向函数的常指针
可以声明一个
指向函数的指针变量
,并且用这个指针变量去调用其他函数,此时,需要函数指针
和这个被调用函数
在返回值和参数列表方面相同
例如:
long (*func)(int)
这里的func就是函数指针,它指向一个返回值为long,参数列表是int的函数
1.3 指针函数和函数指针的一些例子
示例1:
int (*(*func)(int , int))(int)
说明:这里func是一个函数指针,指向一个返回值为一个指针,参数列表为(int, int)的函数。
而这个函数返回的指针又指向一个返回值为int,参数列表也为int的函数。
示例2:
float (**def)[10];
说明:def是一个二级指针,它指向一个指针,这个指针指向一个能存放10个float类型元素的数组
示例3:
double*(*gh)[10];
说明:gh是一个指针,它指向一个能存放10个double*类型元素的数组
示例4:
double (*f[10])();
说明:f是一个含有10个元素的数组,数组里的每一个元素都是函数指针
,指向一个返回值类型为double,形参表为空的函数
示例5:
int*((*b)[10]);
说明:b是一个指针,指向一个能存放10个int*类型元素的数组
二、指针数组和数组指针
指针数组
:即存放元素是指针的数组,例如int *ptr[];
,数组ptr[]里存的是地址
数组指针
:即指向数组的指针,例如int (*ptr)[];
对于一个二维数组,可以这样表示:
int v[2][10] = { {1,2,3,4,5,6,7,8,9,0}, {11,12,13,14,15,16,17,18,19,20} };
也可以这样:int (*a)[10] = v;
,这里a是一个指针,指向一个10个int元素的数组
a+1
:表明指针a向后移动1*sizeof(数组大小)
,对上面的例子,共向后移动40个字节
*a+1
:仅针对这一行向后移动4个字节
示例1:
int (*a[10])(int);
说明:a是一个有10个指针的数组,该指针指向一个返回值和参数都为int的函数
解析:
① 一个有10个指针的数组:*a[10];
② 该指针指向一个函数:(*a[10])();
③ 该函数有一个整形参数:(*a[10])(int);
④ 并返回一个整型数:int (*a[10])(int)
所以int (*a[10])(int)
方法:阅读这种表达式的时候可以遵循以下的规则:从右向左,由近及远,括号优先
;比如从a符号开始。其右边是[10],说明a是个数组,其中存了十个元素。再看a的左边是一个*。说明数组中存的是指针。现在在看(*a[10])的右边是(int);说明所存的指针
是指向有一个int形参的函数现在看(*a[10])的左边是个int ,说明指向的函数的返回值为int类型
示例2:
int (*(*p)[10])(int*)
p是一个指针,p这个指针指向一个数组,数组元素是指针,数组元素的指针指向一个函数,这个函数参数是int*,返回值是int
示例3:
这里的第二个结果为什么是5
呢?
首先,赋值语句int *ptr = (int*)(&a + 1);
表示ptr指向a数组最后一个元素的下一个元素,即第六个元素,尽管它不存在。
时刻牢记
:数组名本身就是一个常指针,加上&,就变成了二级指针,这里的二级指针指的是二维数组,+1就是数组整体加一行