函数指针一例分析

首先,贴上一段代码和它的运行结果。

#include 
#include 

typedef char (*fnp)() ;//声明函数指针的时候是不需要带参数的,但是要规定返回值

int fn1(char a , int b)
{
    return a;
}

char fn2(char a , int b ,int c)
{
    return a;
}

//这样是一个返回为返回值为int的函数
int (* intptr_function())()
{
    return fn1;//返回值是fn1
}



int main(int argc, char *argv[])
{
    void *p  = fn1;
    void *p0 = fn1(8 , 90);//这是错误的,p0保存的是函数的返回值

    fnp p1 = fn1; //p1、p2是函数指针的正规用法
    fnp p2 = fn2 ;

    printf("Values of function p? are :\n%d\t%d\t%d\t%d\n\n" ,
           ((fnp)p)(4,5),   //将p强制转换成函数指针类型
           p0, p1(4,6) ,
           p2(9,6,3)) ;
    printf("Sizes of these values are :\n%d\t%d\t%d\t%d\n\n" ,
           sizeof(((fnp)p)(4,5) ),
           sizeof(p0),  //结果为4,因为p0是void*类型,
           sizeof(p1(4,6)) ,
           sizeof(p2(9,6,3))) ;

    printf("Values of function p? are :\n%d\t%d\t%d\t%d\n\n" ,
           ((int(*)())p)(4,5),   //此处与上不同,
                                //p被强制转换成int(*)()类型的指针,
                                //指向返回值为int的函数
           p0, p1(4,6) ,
           p2(9,6,3)) ;
    printf("Sizes of these values are :\n%d\t%d\t%d\t%d\n\n" ,
       sizeof(((int(*)())p)(4,5) ), //结果为4,因为强制转换后反函数返回值为int型
       sizeof(p0),
       sizeof(p1(4,6)) ,
       sizeof(p2(9,6,3))) ;



    /***************使用返回值为函数的函数指针*****************/

    int (* (*fnptr)())();//这是一个指向返回为返回值为int的函数
    fnptr = intptr_function ;
    printf("The result of that function is %d.\n" , fnptr()(9,6));

    return 0;
}

函数指针一例分析_第1张图片

函数指针的声明形如:

char (*fnp)(char, char)

其实可以不必声明参数,即:

char (*fnp)()
在这里,使用 typedef char (*fnp)() ; 来定义fnp为返回值为char类型的指针。


函数名是指向函数本身的指针,但是,把函数赋值给void * 类型的指针,并不是像下面这样。
void *p0 = fn1(8 , 90);
这样子做,只是意味着,在p0初始化的时候,把fn1(8,90)的运算结果赋值给它。
我们通过打印sizeof(p0)可以看出,它到底只是一个指针类型的变量,而不是我们函数的返回值char类型。

正确的方法是把函数名赋值给void*型指针变量,然后,把它强制转换为函数指针类型再传入参数执行。
void *p  = fn1;//函数名赋值给p

((fnp)p)(4,5);//把p强制转换为函数指针后执行

强制转换的方法除了像上文,先typedef为某个类型,还可以如下,不过比较晦涩:

((int(*)())p)(4,5);//它的类型是(int(*)()

最后还有一个老生常谈的问题,定义一个返回值为函数的函数指针,即函数A执行的结果是一个指针,而这个指针指向函数B。

最直观的方法当然是先把函数B的函数指针typedef,然后再去定义函数A的函数指针。形如:

typedef char (*fnp)() ;
fnp (*ptr) ();//ptr就是返回值为函数的函数指针

或者直接这样声明:

int (* (*fnptr)())();

那么这个返回值为函数指针的函数怎么写?
同样,最直观可以写成:

fnp intptr_function()
{
/******/
}
也可以写成:
int (* intptr_function())()
{
    return fn1;//返回值是fn1
}

你可能感兴趣的:(函数指针一例分析)