指针:就是地址;
指针数组:它是一个数组,其内容都是地址。
例如:
int *arr[10];//由于优先级的关系,arr先与[]结合,再与*结合,所以它是一个指针数组;
int *arr[4];//同上;
int **arr[6];//这是一个二级指针,二级指针数组;
数组指针:它是一个指针,指向一个数组。
例如:
int *p;它的含义是指针变量P指向整型数据的指针。数组指针只是增加了一个数组;
int(*arr)[10];//p先与*结合,变为一个指针变量,然后与[10]结合,指向一个内容为整形的数组。
总结:指针数组还是数组指针是由优先级来决定的。
所以,要如何来存储数组的地址呢?
在VS2008上面运行时,第二行会报错。分析:等号左边的含义是:一个指向整形的指针变量,而等号右边的含义是一个数组的地址,很明显,左右两边的含义不相同。
而第三行是正确的。
由于前面的学习,我们知道一维数组在传参时,数组名会降级为其指向内部元素的指针。二维数组在传参时可以看做是一维数组。
例如:二维数组一般使用一下两种方法传参
void art(int arr[][5]){}
void art(int (*arr)[5]){}
三维数组在传参时可看做一维数组,其内容是指向二维数组。
函数指针:即保存函数地址的指针。
例如:printf("%p\n",prt);//prt为函数名;
priintf("%p\n",&prt);在这里,&prt和prt的内容是相同的。
那么,要如何保存一个函数的地址呢?
void (*prt)();//prt先与*结合,说明是指针,指针指向一个函数,该函数无参数,返回值类型为void。
现在来看两段复杂的代码:
(*(void(*)())0)();//函数调用------>含义是:解引用函数指针0作为函数的地址。
void (*signal(int,void(*)(int)))(int);//声明了一个函数,函数的参数有2个,一个整型,一个是函数指针,返回值为void(*)(int);
第二个可以化简为:
typedef void(*prt)(int);
prt signal(int,prt);
函数指针数组:把函数的地址存放到一个数组中,这个数组就叫函数指针数组。
例如:
int (*arr[6])();//arr先与[]结合,再与*结合,其数组的内容是int(*)()类型的函数指针。
那么,函数指针数组有什么用呢?----->转移表。
例如:用转移表来实现一个简单的计算器;
int (*p[5])(int,int)={NULL,Madd,Msub,Mmul,Mdiv};
函数指针的数组的指针:在上面的基础上改进:int(*(*arr)[6])();
//先确定数组先与哪个符号结合,然后与哪个结合......一步一步结合,一步一步分析。