鱼C论坛

 找回密码
 立即注册
查看: 1450|回复: 2

[技术交流] 函数指针、函数引用、函数指针引用混个脸熟

[复制链接]
发表于 2016-6-29 17:16:58 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 yundi 于 2016-6-29 17:18 编辑

先声明,菜鸟学习中的理解,肯定不够准确,欢迎指正。

1.先定义两个函数
#include <iostream>
//两个函数
int fadd(int a,int b){return a+b;}
int fsub(int a,int b){return a-b;}


2.函数指针。把函数名fadd替换成(*fp),就成了函数指针
void main(void)
{
    int (*fp) (int ,int );
    fp = fadd;//指向某函数
    std::cout << fp(3,4) << std::endl;
}


3.函数引用。把函数名fadd替换成(&rf),就变成函数引用
void main(void)
{
    int (&rf)(int,int)(fadd); //初始化为fadd函数的引用
    std::cout << rf(3,4) << std::endl;
    //rf = fsub; //不能再引用到另一个函数
    system("puase");
}

引用一旦初始化,就不能再赋值。所以,不能再引用到另一个函数。


4.函数指针引用。把函数指针*fp替换为* & rfp,即是函数指针引用
void main(void)
{
    int (* &rfp)(int,int)(fp);
    std::cout << rfp(3,4)<<std::endl;
    fp = fsub; //指针可以修改
    std::cout << rfp(3,4)<<std::endl;
}

是对指针的引用,当指针的指向修改到另一个函数时,就间接引用到另一个函数。


5.函数作为参数。设想一种情况,要根据某条件选择调用其中一个函数,可能会这样写:
int funselect(int num,int a,int b)
{
    switch(num)
    {
        case 1:return fadd(a,b);//条件1就fadd
        case 2:return fsub(a,b);//条件2就fsub
        default:return 0;            
    }
}

另一个方法就是把函数作为参数传进去
int funpram(int a,int b,int (fpram)(int,int))
{
    return fpram(a,b);
}        
std::cout << funpram(3,4,fadd) << std::endl;   //调用

还有一种是把函数指针作为参数
int pfunpram(int a,int b,int (* pfpram)(int,int))
{
    return (* pfpram)(a,b);
}
std::cout << pfunpram(3,4,fadd) << std::endl;  //调用

再就是把函数引用作为参数
int rfunpram(int a,int b,int (& rfpram)(int,int))
{
    return rfpram(a,b);
}
std::cout << rfunpram(3,4,fadd) << std::endl;  //调用

最后把函数指针引用作为参数
int rpfunpram(int a,int b,int (* & rpfpram)(int,int))
{
    return * rpfpram(a,b);
}
void main(void)
{
    int (*fp) (int ,int )(fadd); //定义并初始化函数指针,等效 int (* fp) (int,int) = fadd;
    std::cout << rpfunpram(5,5,fp) << std::endl;  //调用
}

上面仅仅列举了作为参数的几种可能形态,至于之间有什么区别,该如何运用,还有待学习


6.继续变形。

返回类型为函数,不带这么玩~

返回类型为函数指针,指向int(*)(int,int)型函数
int (* retfp())(int,int)
{
    return fadd;
}
void main(void)
{
    int (*fp) (int ,int ); //定义函数指针变量
    fp = retfp();//调用函数
    std::cout << fp(5,3) << std::endl;  //调用
}

返回类型为函数引用,引用int()(int,int)型函数
int (& retrf())(int,int)
{
    return fsub;
}
void main(void)
{
    int (*rf2) (int ,int ) = retrf(); //定义就必须初始化
    std::cout << rf2(5,3) << std::endl;  //调用
}

返回类型为函数指针引用 ?
int (* & retrfp())(int,int)
{
    //…… ?
}


7.再复杂点。综合5、6,让返回值、参数都和函数指针、函数引用挂上关系。例如:
int (* z(int x,int(*y)(int)))(int)
int (* & z(int x,int(* & y)(int)))(int)

------------以下是练习代码----------

#include <iostream>

int fadd(int a,int b){return a+b;}
int fsub(int a,int b){return a-b;}

        int funselect(int num,int a,int b)
        {
            switch(num)
            {
                case 1:return fadd(a,b);//条件1就fadd
                case 2:return fsub(a,b);//条件2就fsub
                default:return 0;            
            }
        }
//参数是函数
int funpram(int a,int b,int (fpram)(int,int))
{
    return fpram(a,b);
}
//参数是函数指针
int pfunpram(int a,int b,int (* pfpram)(int,int))
{
    return (* pfpram)(a,b);
}
//参数是函数引用
int rfunpram(int a,int b,int (& rfpram)(int,int))
{
    return rfpram(a,b);
}
//参数是函数指针引用
int rpfunpram(int a,int b,int (* & rpfpram)(int,int))
{
    return (* rpfpram)(a,b);
}

//返回值是函数指针,指向int fun(int,int)型函数
int (* retfp())(int,int)
{
    return fadd;
    //int (* frel)(int,int) = fadd;
    //return frel;
}

//返回值是函数引用
int (& retrf())(int,int)
{
    return fsub;
}

//返回值是函数指针引用

void main(void)
{
    //1.函数指针
    int (*fp) (int ,int );
    fp = fadd;
    std::cout << fp(3,4) << std::endl;
    //2.函数引用
    int (&rf)(int,int)(fadd);
    std::cout << rf(3,4) << std::endl;
    //3.函数指针引用
    int (* &rfp)(int,int)(fp);
    std::cout << rfp(3,4)<<std::endl;
    fp = fsub;
    std::cout << rfp(3,4)<<std::endl;

    //4.函数作为参数
    std::cout << funpram(3,4,fadd) << std::endl;

    //5.函数指针作为参数
    std::cout << pfunpram(3,4,fadd) << std::endl;
    std::cout << pfunpram(5,4,fsub) << std::endl;

    //6.函数引用作为参数
    std::cout << rfunpram(3,4,fadd) << std::endl;

    //7.函数指针引用作为参数
    std::cout << rpfunpram(5,5,fp) << std::endl;
    fp = fadd;
    std::cout << rpfunpram(5,5,fp) << std::endl;

    //8.返回值是函数指针
    fp = retfp();
    std::cout << fp(5,6) << std::endl;

    //9.返回值是函数引用
    int (&rf2)(int,int) = retrf();
    std::cout << rf2(8,9) << std::endl;

    //10.返回值是函数指针引用

    system("pause");
}

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-6-30 10:47:52 | 显示全部楼层
谢谢脸熟君
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-6-30 11:18:23 | 显示全部楼层
一直觉得这几个好难啊,一直没有怎么理清楚
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-27 04:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表