浅谈:
指针数组
数组指针函数指针
函数指针数组
指向函数指针数组的指针
1.指针数组:char* arr[5]
首先,它是一个数组,一个可以存放5个指针的数组.
里面每个元素存的是指向字符/字符串的指针。
声明:char*(arr[i]),因为[]的优先级高于*。所以 char* arr[i],也可以
但是我觉得(char*)arr[i]不行,因为C语言中,()和[]的优先级是一样的
想想它表示什么。
2.数组指针:char(*arr)[5]
首先,它是一个指针,一个数组的指针。
他指向的是一个存放5个char型元素数组的指针
声明:char(*arr)[i],[]中可以写除0外任意数。但是写数组表示长度能直观看出指针所指向数组元素个数
例子:
int arr[3][5] = {0,1,2,3,4};
int (*p)[5] = arr;
printf("%d",*(*(p+0)+1));
return 0;
此时arr是一个二级指针常量(arr[1][1] == *(*(arr+1)+1)),
p是一个指针变量,他现在指向的是arr数组的第一行,相当于有5个元素的一维数组。所以p的增量以一维素组长度为单位
所以*(p+0)就相当于第一行数组,此时将其放入式子*(*(p+0)+1),它就相当于第一行数组的首元素地址,首元素地址+1就是第一行第二个元素。
3.函数指针:void (*p)( int x)
首先,它是一个指针,一个函数的指针。
指向的是函数入口的地址。(函数名相当于一个函数入口地址的符号,在编译时替换为函数地址)
声明:int fun(int x);//先声明一个函数
int(*p)(int x),//int x是函数参数的类型声明
p = fun; //此时指针变量p就可以指向函数fun了
例:
int fun(int x)
{
return x;
}
int main()
{
int (*p)(int a) = fun;
printf("%d\n",p(5));
printf("%d\n",(*p)(5));
}
此时p(5)和(*p)(5)的返回值是一样的,为什么?
因为两者在编译时做了相同的事。
它只是语法上的便利本质上是一样的
类似的语法上的便利还有:
p->h 通过指针访问结构成员,等价于 (*p).h
p[n] 通过指针访问数组元素等价于 *(p+n)
(*p)的值与p一样这也是一个C标准规定的性质。没什么内在特殊。
4.函数指针数组 int (*p[i])(int x)
首先,它是一个数组,一个函数指针的数组
里面每个元素都是函数指针
声明:
int add(int x, int y)
int sub(int x, int y)
int mul(int x, int y) //三个 参数类型,参数个数,返回类型相同的函数
int (*p[])(int a,int b) //此时p[]就是一个函数指针数组,可以存放上面类型的函数
p[] = {add,sub,mul} //此时将add等函数作为元素存放在函数指针数组中
例:
int add(int x,int y)
{
return x+y;
}
int sub(int x,int y)
{
return x-y;
}
int main()
{
int (*p[])(int a,int b) = {add,sub};
printf("%d",p[1](3,2));
}
还可以 typedef int (*p[])(int a ,int b)
这样定义之后在其它函数里面可以直接使用 oper_func类型:
使用方法如下:
p p1= {add,sub,mul,div1};
例:
int add(int x,int y)
{
return x+y;
}
int sub(int x,int y)
{
return x-y;
}
int main()
{
typedef int (*p[])(int a,int b);
p p1 = {add,sub};
printf("%d",p1[1](3,2));
}
5.指向函数指针数组的指针 int (*(*p)[2])(int x,int y)
首先,它是一个指针,一个数组的指针
这个指针指向的数组是一个存放函数指针的数组
声明: int (*(*p)[2])(int x,int y)
//p是一个指针,指向的数组大小为2,该数组中存放的是函数指针,该函数指针所指函数 返回类型为int
,有两个参数,参数类型都是int
例:
int (*p[])(int a,int b) = {add,sub};
int (*(*p1)[2])(int a,int b) = &p;
printf("%d",(*(p1[0]))(5,4))