不仅仅是(*p)指针
指针数组
首先它是一个 [数组],数组的元素都是指针,数组的元素都是指针;
数组占多少个字节由数组本身决定。
看代码 int *p1[10]
和 int (*p2)[10]
哪个是指针数组呢?
这里需要明白一个符号之间的优先级问题:
- “[ ]”的优先级比” * “要高;p1先与”[ ]”结合,构成一个数组的定义,数组名为p1;
- int * 修饰的是数组的内容,即数组的每个元素。
那我们清楚,这是一个数组,其中包含10个指向 int 类型数据的指针,即指针数组。 - 所以 p1 为指针数组,那么 p2 是接下来要介绍的数组指针
数组指针
int (*p2)[10]
- 在这里 “()”的优先级比” [ ] “高,” * “号和 p2 构成一个指针的定义,指针变量名为 p2 ;int 修饰的是数组的内容,即数组的每个元素。
- 数组在这里没有名字,是个匿名数组。
- 现在我们清楚p2 是一个指针,它指向一个包含10个int 类型数据的数组,即数组指针。
数组指针的使用
int arr[10]={0}; int (*p2)[10]=&arr;
- 验证结果表示上述代码正确;所以(p2)是数组指针,存放数组的地址是合适的。
函数指针
- 顾名思义,函数指针就是函数的指针。它是一个指针,指向一个函数
- 看例子:
char*(*fun)(char* p1,char* p2)
- 这里的 fun 不是什么函数名,而是一个指针变量。它指向一个函数;这个函数有两个指针类型的参数,函数的返回值也是一个指针。
看这个例子(*(void(*) ())0) ()
这是u什么?????
-
void (*)()
,可以明白这是一个函数指针类型;这个函数没有参数,没有返回值; -
(void(*)())0
,这是将0强制转换为函数指针类型,0 是一个地址,也就是说一个函数存在首地址为0 的一段区域内; -
(*void(*)()0)
,这是取0地址开始的一段内存里面的内容,其内容就是保存在首地址为0的一段区域内的函数; -
(*void(*)()0)()
,这就是函数调用。
函数指针数组
- 现在我们清楚表达式
char*(*pf)(char* p)
定义的是一个函数指针pf; - 既然是指针,那就可以储存在一个数组里面;
-
char*(*pf[3](char*p))
;这是定义一个函数指针数组,它是一个数组,数组名为pf ;数组内存储了3个指向函数的指针。 - 这个指针指向一个返回值类型为char*( 指向字符的指针 ),参数为char*p( 一个指向字符的指针 )的函数。
- 函数指针数组的用途是转移表
函数指针数组的指针
看例子char*(*(*pf)[3])(char*p)
- 注意:这里的 pf 是一个指针,这个指针指向一个包含了3 个元素的数组;
- 这个数字里面存的是指向函数的指针;
- 这些指向一些返回值类型为指向字符的指针,参数为一个指向字符的指针的函数。