在这里我们关于指针讨论一下几个:
指针数组 数组指针 函数指针 函数指针数组 指向函数指针数组的指针
接下来,用一些例子来进行形象说明:
1.指针数组: 是数组,是一个存放指针的数组;
int *arr1[10];
int *arr2[4];
int **arr3[5];
2.数组指针:是指针,该指针有能力指向一个数组;
int (*p)[10];
上面代码解释:p是先和*结合的,说明p是一个指针变量,然后指向的是一个大小为10个整型的数组,所以说p是一个指针,指向一个数组,叫数组指针;
注意:[]的优先级高于*,所以必须加上()来保证p先和*结合.
3.函数指针:是指针,该指针有能力指向一个函数;
用一段代码对函数指针进行说明:
#include <stdio.h>
void test()
{
printf("hehe\n");
}
int main()
{
void(*Pfun)() = test;
Pfun();
return 0;
}
函数也有自己的地址,函数名就是函数的地址,对函数名进行取地址也行(&函数名).
如上述代码,将test函数的地址赋值给Pfun,间接打印出test函数的内容.
在函数中*是没有意义的,如(*Pfun)();是等价于Pfun();.
再例如:
#include <stdio.h>
int Add(int x,int y)
{
return x + y;
}
int main()
{
int(*Pfun)(int, int) = Add;
printf("%d\n", Pfun(1, 2));
return 0;
}
上述代码中,
Pfun可存放函数的地址,Pfun先和*结合,说明Pfun是一个指针,指针指向的是一个函数,指向函数的参数类型为int,int,返回值类型为int.
接下来看看两段有趣的代码:
代码1:
(*(void (*)())0)();
(void (*)())0是对零地址处的函数进行强制类型转换,转换成函数指针类型,总体来说还是函数指针;
代码2:
void (*signal(int,void (*)(int)))(int);
对上述代码的来说,signal是一个函数的声明,该函数的第一个参数类型是int,第二个参数类型是一个函数指针,该指针能够指向一个参数类型为int,返回值类型为void的函数,signal函数的返回类型也是一个函数指针,该指针能够指向一个参数类型为int,返回值类型为void的函数.
4.函数指针数组:把函数的地址存到一个数组中,把这个数组叫做函数指针数组;
int (*parr[10])();
对上述代码来说,parr先和[]结合,说明parr是一个数组,数组的内容是类型为int (*)()的函数指针。
函数指针的类型一般用于转移表。
函数声明可以没有形参名,但定义一定要有。
5.指向函数指针数组的指针;
指向函数指针数组的指针是一个指针,指针指向一个数组,数组的元素都是函数指针。
void test(const char *str)
{
printf("%s\n",str);
}
int main()
{
char *str = "abcd";
void(*Pfun)(const char *) = test;
void (*PfunArr[5])(const char *str);
PfunArr[0] = test;
void(*((PPfunArr[5])(const char *)) = &PfunArr;
return 0;
}
void(*Pfun)(const char *) = test;函数指针Pfun;
void (*PfunArr[5])(const char *str);函数指针的数组PfunArr;
void(*((PPfunArr[5])(const char *)) = &PfunArr;
——〉指向函数指针数组PfunArr的指针ppfunArr;