指针数组、数组指针、函数指针、函数指针数组、指向函数指针数组的指针的理解

来源:互联网 发布:源码怎么算 编辑:程序博客网 时间:2024/06/08 11:24

一、指针数组(存放指针的数组)

格式:类型名*数组名(数组长度)  如: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函数的首地址赋给pret = (*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和5return 0;}



0 0