一、什么是指针数组
一个数组,若其元素均为指针类型数据,称为指针数组,也就是说,指针数组中的每一个元素都存放一个地址,相当于一个指针变量。
int *p[4];
一般一维的指针数组的一般形式为:类型名 *数组名[]
由于[ ]的优先级比“ * ””高,因此先与[4]结合,形成p[4]形式,这显然是数组形式,表示p数组有4个元素,然后再与前面的“ * ””结合,“ * ””表示此数组是指针类型,每个数组元素(相当于一个指针变量)都可以指向一个整形。
例子:
#include <stdio.h>
#include <stdlib.h>
int getmax(int a,int b)
{
return a>b?a:b;
}
int getmin(int a,int b)
{
return a<b?a:b;
}
int getsum(int a,int b)
{
return a+b;
}
int main()
{
int a=10;
int b=20;
int (*pfnc[3])(int a,int b)={getmax,getmin,getsum};
int ret;
for(int i=0;i<3;i++){
ret=(*pfnc[i])(a,b);
printf("%d\n",ret);
}
}
二、什么是数组指针
数组指针,顾名思义,就是指向数组的指针。
我们是这样定义它的:int(* p)[n] = { }; (n为要定义的个数)
按照优先级运算
()与[ ] 优先级相同,根据结合律,就从左向右运算。
()里是*p,先定义了指针,所以p是个指针,然后后面是[ ],才是数组,即数组指针。它指向了含有n个int类型的数组。
如上图所示,假设定义 int (*p2)[5] = { 0, 0, 0, 0, 0}; 那么p2就指向了这个包含5个int类型的数组了。
( !!!注意:指向数组和指向数组首元素的地址是两码事。p2在内存中指向的是这个数组的首地址,是和数组有关联的,而绝不仅仅是指向数组首元素的地址。)
就比如:
int *p1 = b;
int a[5] = {1, 2, 3, 4, 5};
int *p2 = a;
指针p1和p2就单纯的指向了变量,p1指向了变量b的地址,p2指向的是a数组首元素的地址,而不是指向这个数组,它与整个的数组是无关的。
例子:
#include <stdio.h>
int main()
{
int temp[5] = {1, 2, 3, 4, 5};
int (*p)[5] = &temp;
int i;
for(i = 0; i < 5; i++)
{
printf("%d\n", *(*p + i)); //*p是首个元素的地址
//或者 printf("%d\n", (*p)[i]);
}
return 0;
}
1)第一行定义了含有5个int类型的数组temp;
2)第二行就定义了一个指向含有5个int类型数组的指针p,并把temp数组的首地址给了指针p。
注意:这里为什么不直接用 int (*p)[5] = temp;呢?
这是因为虽然temp和&temp的值都是相同的,但它们的意义却是不相同的:
*** temp指的是这个数组的 第一个元素 的首地址。
*** &temp 指的是这 整个数组 的首地址。