数组指针:
数组指针的意思:指向数组的指针。
这里的数组指针的解释:1,指向num这个数组。2,该数组中有5个元素。3,该数组中元素的类型是int。
注意:&arr是数组的地址,它的类型是int (*)[5],而arr是该数组的首地址,类型是int *,所以这里如果用int (*p)[5]=arr;是错误的。
但你会发现&arr和arr打印出来的值是一样的。但如果数组地址加1则直接跳过该数组,而数组的首地址加1则是跳到下一个元素。
#include <stdio.h>
int main()
{
int i=0,j=0;
int arr[5]={1,2,3,4,5};
int (*p)[5]=&arr;
for(i=0;i<5;i++)
{
printf("%d ",(*p)[i]);
}
for(j=0;j<5;j++)
{
printf("%d",*(*p+j));
}
return 0;
}
指针数组:
指针数组的意思:数组中的每个元素是指针。
这里的指针数组的解释:1,该指针数组有5个元素。2,该数组中元素的类型是char*。
所以这时可以把arr1,arr2两数组的首地址(char*类型)存入该数组中。
一:
#include <stdio.h>
int main()
{
char arr1[5]="my ";
char arr2[5]="name";
char *q[5];
q[0]=arr1;
q[1]=arr2;
printf("%s",q[0]);
printf("%s",q[1]);
return 0;
}
二:
这里的指针的解释:1,一个长度为2的数组。2,该数组元素的类型是数组指针,即p[0]中存放了数组str的地址,p[2]中存放了数组str1的地址。
#include <stdio.h>
int main()
{
char str[10] = "hello ";
char str1[10] = "world";
char(*p[2])[10];
p[0] = &str;
p[1] = &str1;
printf("%s", p[0]);
printf("%s", p[1]);
return 0;
}
函数指针:
函数指针:指向函数地址的指针。(获得函数地址即可调用函数)
这里的函数指针的解释:1,p中存放Add函数的地址。2,函数参数的类型是(int,int)。3,函数的返回值是int。
#include <stdio.h>
int Add(int x,int y)
{
return x+y;
}
int main()
{
int (*p)(int,int)=Add;
printf("%d\n",Add(1,2));
printf("%d\n",(*p)(1,2));
return 0;
}
函数指针的数组:
解释:一个指针数组,里面放的都是函数指针
看似好像没什么用,其实很是有用的。假设你有多个函数,分别解决不同的问题,函数指针数组可以对应的调出所需要的函数解决问题,如果有新的函数也可以直接加入该数组。
#include <stdio.h>
int Add(int x,int y)
{
return x+y;
}
int Sub(int x,int y)
{
return x-y;
}
int Mul(int x,int y)
{
return x*y;
}
int Div(int x,int y)
{
return x/y;
}
int main()
{
int (*p[5])(int,int)={0,Add,Sub,Mul,Div};
printf("%d ",(*p[1])(2,3));
printf("%d ",(*p[2])(2,3));
printf("%d ",(*p[3])(2,3));
printf("%d ",(*p[4])(2,3));
return 0;
}
函数指针数组的指针:
#include <stdio.h>
int Add(int x,inty)
{
return x+y;
}
int main()
{
int (*p)(int,int); //函数指针
int (*p[5])(int,int); //函数指针数组
int (*(*pp)[5])(int,int); //指向函数指针数组的指针
return 0;
}
测试:
其实并不难,只是烦,套娃。可以试着分析下下面两个指针
第一个:(*(void(*)())0)();
1, void(*)() //一个函数指针
2, (void(*)()0) //强制类型转化,0变成函数的地址
3, (*)() //函数指针的解引用
4, (*(void(*)())0)()//调用地址为0的函数
第二个:void(*test(int,void(*)(int)))(int);
1,test(int,void(*)(int)) //函数名为test的函数,参数类型是 (int,函数指针)
2,void(* )(int) //是不是像一个函数指针
3,所以表达的是一个名为test的函数,他的参数类型是(int,函数指针),它的返回类型是函数指针。
注意: 这里的*就不是解引用了,本来test就是一个函数解引用不了
void(*)() test(int,void(*)(int)) 不要以为是这样,这是错误的。
总结:
回调函数,使用一些复杂的函数时都会用到指针。对指针的理解还是很重要的。