一、指针数组(存放指针的数组)
格式:类型名*数组名(数组长度) 如:int*p[2]
一个存放int类型的数组称为整型数组,那么存放指针的数组就叫指针数组。也就是数组中存放的每一个元素都是一个指针变量。
下面举个简单的例子:
#include<stdio.h>
int main()
{
int i = 0, j = 0;
int *p[2];
p[0] = &i;
p[1] = &j;
printf("%d\n", sizeof(p));
return 0;
}
此例数组p就两个元素,p[0]是指向i的指针,p[1]是指向j的指针。这两个指针都是int型指针,所以p是存放int型指针的数组。sizeof(p)返回数组占用的总空间,所以程序输出是8。
二、数组指针(指向数组的指针)
格式:类型名(*指针名)(指针步长) 如:int (*p)[4]
创建一个数组就是在内存里面开辟一块连续的空间,比如int a[4];就是在内存里面开辟了一个大小为4*sizeof(int)字节的内存空间。下面举个例子,通过程序的运行就能让我们对于数组指针有直观的了解。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i=0;
int a[3][4]={{1,2,3,4},{11,12,13,14},{21,22,23,24}};
int (*p)[4]; //该语句是定义一个数组指针,指针步长为4个int即16位。
p=a;
while(i<3)
{
printf("%d\t",(*p)[i]);
//数组指针,指向的是一个数组整体,相当于指针也带了下标,当执行i++操作时,下标+1,得到该数组的下一个元素,
//在该例中,指针没有位移,所以依次输出为1 2 3
/*printf("%d\t",(*p++)[0]);*/
//整型数组类型的指针,指向的是一个数组整体,当执行*p++操作时,指针位移该数组长度的位数
//在该例中,即指针位移4个int的长度,所以输出是1 11 21
i++;
}
return 0;
}
三、指针函数(带指针的函数)
格式:类型标识符 *函数名(参数表) 如:char* fun(char* p)
本质是一个函数,指针函数返回类型是某一类型的指针。 fun是函数名,返回值类型是一个char* 类型的指针。
#include <stdio.h>
char* fun(char* p)
{
printf("%s\n", p);
return p;
}
int main()
{
fun("world");
return 0;
}
输出结果就是·打印world字符串。
四、函数指针(指向函数的指针)
格式:函数类型 (*指针变量名)(形参列表); 如:int (*f)(int x, int y)
函数名和数组名一样代表了函数代码的首地址,因此在赋值时,直接将函数指针指向函数名就行了。
例如:
int max(int x, int y); /* 声明一个函数 */
int (*p) (int p1, int p2); /* 声明一个函数指针 */
p=max; /* 将max函数的首地址赋给指针f */
赋值时函数max不带括号,也不带参数,由于max代表函数的首地址,因此经过赋值以后,指针p就指向函数max(x,y)的代码的首地址。
#include<stdio.h>
int max(int x,int y) //声明一个函数
{
return(x>y?x:y);
}
int main()
{
int ret = 0;
int (*p)(int p1, int p2); //声明一个函数指针
p = max; //将max函数的首地址赋给p
ret = (*p)(2,3);
printf("%d\n", ret);
return 0;
}
五、函数指针数组(其元素是函数指针的数组)
格式:函数返回值类型 (*数组名)(形参列表) 如:int(*pf[2])(int a,int b)
#include<stdio.h>
int add1(int a1,int b1) //声明函数
{
return a1+b1;
}
int add2(int a2,int b2)
{
return a2+b2;
}
int main()
{
int numa1=1,numb1=2;
int numa2=2,numb2=3;
int(*pf[2])(int a,int b);//声明函数指针数组
int(*p1)(int x1, int y1);//声明函数指针
int(*p2)(int x2, int y2);
p1=add1; //将函数首地址赋给指针
p2=add2;
pf[0] = p1; //将函数指针存入数组
pf[1] = p2;
printf("%d %d\n", (*pf[0])(numa1,numb1),(*pf[1])(numa2,numb2)); //输出值为3和5
return 0;
}
六、函数指针数组指针
格式:函数返回值类型 (*(*数组指针名)[数组大小])(形参列表) 如: int(*(*pff)[2])(int, int)
通过我们对名字的分析,可知首先它是一个指针,这个指针指向的是一个数组,而这个数组里面存放的是指向函数的指针。
下面我们来在上例的基础上举一个函数指针数组指针的数组的例子。
#include<stdio.h>
int add1(int a1,int b1) //声明函数
{
return a1+b1;
}
int add2(int a2,int b2)
{
return a2+b2;
}
int main()
{
int(*pf[2])(int a,int b);//声明函数指针数组
int(*p1)(int x1, int y1);//声明函数指针
int(*p2)(int x2, int y2);
int(*(*pff)[2])(int, int) = &pf; //声明函数指针数组指针
p1=add1; //将函数首地址赋给指针
p2=add2;
pf[0] = p1; //将函数指针存入数组
pf[1] = p2;
printf("%d %d\n", (*(*pff)[0])(1, 2),(*(*pff)[1])(2, 3)); //输出值为3和5
return 0;
}