听到这几个名词不知道大家什么感受,反正我是一脸懵逼,不过我还是比较好学的,在老师的指导下,自己下去也钻研了一下,有一些自己的见解,我想在学习过程中也有童鞋遇到了相同的问题,希望我的总结能给你带来帮助。


   首先我们先明确一下这几个概念,知道他们都表示什么,ok,请看:

函数指针函数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针有两个用途:调用函数和做函数的参数

指针函数:指针函数是指带指针的函数,即本质是一个函数。函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。

指针数组:在C语言C++语言中,数组元素全为指针的数组称为指针数组。

一维指针数组的定义形式为:“类型名 *数组标识符[数组长度]”

数组指针数组名的指针,即数组首元素地址的指针。即是指向数组的指针


    以上这些来自百度百科,概念还是有些抽象,不知所云,估计还是不知道怎么区分。ok接下来我谈下我的看法。


   按照我的理解,不管是函数指针还是指针函数,或者说数组指针指针数组,我们想看后两个字,这两个字就决定了这个东西的大前提。我们分别来看,对函数指针来说,首先它是一个指针,只不过它比较特殊,是一个指向函数的指针,所以它叫函数指针。说它特殊其实也不特殊,我们可以想一下我们声明×××指针、字符指针等指针,他们是不是代表指向×××的指针、字符的指针,只是我们再定义命名时没有注意,那么这样我们就可以解释函数指针了,指向函数的指针。后边我会用代码再解释一下。那么对于数组指针,我们是不是可以理解了呢?就是指向数组的指针。写道这里,我想起了上一篇博文,数组名,那么他就是一个数组指针。区别了这两个,我们接着来看另外两个,按照我前边说的看后两个字,对于指针函数,首先来说,它是一个函数,对于函数我们比较关心的有两个比较关键的因素,一个是返回值,另一个是参数,这里我们涉及到的就是它的返回值。有人就会问了,那为什么不是参数,这个很好解释,就从参数所处的位置就可以区分出来,好了言归正传,对于指针函数就是说函数的返回值是指针类型的,比如像我们常用的库函数malloc(),就是指针函数。最后我们再说指针数组,前三个我都解释,我想这个聪明大家就可以自己解释,这里我还是在解释一下,所谓指针数组,就是存储指针的数组,至于指针数组是存储什么类型的指针,就要看我们声明什么类型的数组,就像我们声明×××数组,存储×××数组,浮点型数组,存储浮点型数据。从概念上区分了清了,但是我们还是见了具体的东西,你不认识我,我不认识你,接下来我就来解决这个问题


   为什么会出现什么指针函数、函数指针等,在这里我们先要再引入c语言的运算符优先级表,这些就是由于运算符的优先级造成的。


        c语言运算符优先级表


wKiom1jWbFeTHxNZAADsqSMqPUE664.jpg-wh_50

wKioL1jWbFjjezdaAACZPGGNLGc233.jpg-wh_50


    这里我们只关心[]、()与*的优先级,我们可以从图中很明显的得知[]、()的优先级高于*,因而标识符,就会首先与运算级高的结合,先结合的就决定了它的性质。ok,下来我通过代码解释;请看下边的代码:


测试代码


#include<stdio.h>


/*

**输出两个×××数据的最大值

*/

int Int_Max(int a, int b )

{

    return a>b?a:b;

}


/*

**输出两个双精度浮点数的最大值

*/

double Double_Max(double a,double b)

{

    return a>b?a:b;


}


/*

**定义一个指针函数

*/

int *Fun_Arry(int x, int y)              

{

    static int  arry3[5]= {0};

    int *p;

    p = arry3;

    return p;


}


/*

**定义两个函数指针,用来间接操作刚才定义的两个函数

*/

int (*function1)(int ,int );            

double (*function2)(double ,double );             



int main()

{

    int a = 1, b = 5;                  //声明两个×××数据

    double c = 3.4, d = 3.6;              //声明两个浮点型数据

    int arry1[5] = {0};                      //声明一个×××数组

    int DoubleArry_1[3][2];                 

    int DoubleArry_2[3][3];

    int *lp1 = NULL, *lp2 = NULL, *lp3 = NULL, *lp4 = NULL, *lp5 = NULL;


int *arry_2[5] ;               //声明一个指针数组,用来保存×××指针




int (*arry_3)[2];                 //声明一个数组指针,指向一个数组

        int (*arry_4)[5];              //声明一个数组指针,指向一个数组

        int (*arry_5)[3][3];              //声明一个数组指针,指向一个数组



    /*

    **变量arry_3是一个数组指针,它指向一个包含2 个int 类型数据的数组,即数组指针

    **并且只能指向有两个int类型数据的数组

    */

        arry_3 = DoubleArry_1;  

        arry_4 = &arry1;

        arry_5 = &DoubleArry_2; 



/*

**function1和function2是我们之前声明的函数指针,用来指向函数是指针,并且由于function1声明为int型的,所以只能指向返回值为int型的函数,

**那么对于function2函数就只能指向返回值为double型的函数,因而,下边分别让他们分别指向了我之前定义的两个函数。

*/

function1 = Int_Max;

function2 = Double_Max;


/*

**arry_2是一个指针数组,按照我上文说的,那它就是用来保存指针的,

**由于我在这里声明的为×××指针数组,所以,这里我们看到保存了我个×××指针。

*/

    arry_2[0] = lp1;

    arry_2[1] = lp2;

    arry_2[2] = lp3;

    arry_2[3] = lp4;

    arry_2[4] = lp5;


/*

**为了验证函数指针的正确性,我做了一下测试前两行我用函数名,

**直接调用函数,分别得到×××、浮点型的最大值。

*/

        printf("Result of origonal function---->Int_Max = %d\n",Int_Max(a,b));

        printf("Result of origonal function---->Double_Max = %f\n",Double_Max(c,d));

        printf("----------------------------------------------------------------\n");

        printf("Result of Function Pointer ----->Int_Max = %d\n",function1(a, b));

        printf("Result of Function Pointer ----->Double_Max = %f\n",function2(c, d));



    return 0;

}


运行结果测试图



wKioL1jWliizD-ibAACVOHaRsIk401.png-wh_50


   测试代码中我已经尽可能多的给出了注释,我在这里再重点提一个数组指针,数组指针就是指向数组的指针,注意看代码中我用红色标注的部分,分别声明了三个不同类型的数组指针,arry_3是一个指向两个×××元素的数组的指针,并且对于此指针只能指向有两个×××元素的数组,arry_4是一个指向5个×××元素数组的指针ok,这也将涉及到上一篇博文遗留的一个问题,数组名到底是什么。arry_5是一个指向3行3列的二维数组的指针。ok,定义完了了我们来看后边的赋值,arry_3是一个指向两个×××元素的数组的指针,。然后用它接收了一个二维数组名,是不是有疑问,对于arry_3,不是应该指向一个一维数组吗?怎么把一个二维数组名给它了,首先我来告诉你,这是对的,我的上一篇博文是不是谈到,数组名就是代表一个数组,其保存着该数组的首元素的地址,对于二维数组从存储结构上来看,首元素就是一个一维数组,所以用把二维数组名赋值给arry_3,其本质是将一个一维数组赋并且只有两个×××元素的数组的地址赋值给arry_3,我们接着来看,arry_4,我把一个一维数组的地址给它,这时arry_4就指向了一维数组arry1,再看最后一条,如果要操作二维数组,就要把二维数组名的地址给相同类型的数组指针。ok对于这几个很麻烦的的概念,按照自己理解总结了一下,希望能帮到遇到同样问题的你,最后我在总结一下今天写的以及一些注意事项。


 函数指针:就是指向函数的指针。

    1、函数名就是函数的入口地址

    2、指向函数的指针就是函数指针

     使用函数指针是要达到 三同  即:1、函数返回值相同2、参数个数相同3、参数对应的类型相同

    3、其他类型的指针均可自增自减,但是对于函数指针不允许自增自减

 指针数组:存储指针的数组。

    1、 数组中的三值合一:数组名、数组首元素地址、数组名的地址

数组名中保存首元素的地址 《 数组名取地址 代表针对整个数组取地址》

    2、数组名取地址代表整个数组的地址   当要接收数组名的地址时就要定义一个数组类型的指针

    3、一维数组可以通过一级指针接收数组的地址,达到引用数组并操作数组的目的,

     但是二维数组却不能通过定义二级指针来接收数组名,达到引用并操纵数组的目的。始终注意:数组名代表整个数组,然后数组名有值保存了数组首元素的地址

   4、对于二维数组,从本质上讲是一个一维数组,但是每个元素是一个数组;    

 数组指针:就是指向数组的指针。

 指针函数:返回指针的函数就是指针函数。