zoukankan      html  css  js  c++  java
  • [函数指针]关于函数指针与指针函数

    指针函数

    指针函数顾名思义,本质还是函数,不同的是改函数的返回类型为指针类型。接下来我们举个例子。

    #include <iostream>
    using namespace std;
    
    char *Output()
    {
        return "success!!!";
    }
    
    int main()
    {
        cout << "执行Output函数的结果是:" << Output() << endl;
        return 0;
    }

    这里的 char *Output(); 就是个指针函数——char*的函数,即返回值为char*类型的。(这里的代码,如果gcc/g++版本比较高的话,可能会有警告)

    warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

    函数指针

    同上我就不再赘述,本质是指针。接下来我们同样拿代码实例。

    #include <iostream>
    using namespace std;
    
    int square(int num)
    {
        return num * num;
    }
    
    int main()
    {
        int num;
        int (*p)(int); //这里表示指针名为p,传入的参数类型为int类型的
    
        cout << "请输入一个整数:";
        cin >> num;
    
        //p = &square;
        p = square;
        //这里可以用上面一种写法,但是函数名就相当与首地址,所以省略。
        
        cout << num << " * " << num << " = " << (*p)(num) << endl;
        //这里也可以写为p(num),但是像普通的函数调用
        return 0;
    }

    这是两者的写法上的差别:

    指针函数:int *p();

    函数指针:int (*p)();

    扩展

    1.函数指针作为参数

    #include <iostream>
    using namespace std;
    
    int add(int num1, int num2)
    {
        return num1 + num2;
    }
    
    int sub(int num1, int num2)
    {
        return num1 - num2;
    }
    
    int calc(int (*p)(int ,int ), int num1, int num2)
    {
        return (*p)(num1, num2);
    }
    
    int main()
    {
        cout << "1 + 2 = " << calc(add, 1, 2) << endl;//调用calc,第一个参数为函数名
        cout << "1 - 2 = " << calc(sub, 1, 2) << endl;
        return 0;
    }

    2.函数指针作为返回值

    #include <iostream>
    using namespace std;
    
    int add(int num1, int num2)
    {
        return num1 + num2;
    }
    
    int sub(int num1, int num2)
    {
        return num1 - num2;
    }
    
    int calc(int (*p)(int ,int), int num1, int num2)
    {
        return (*p)(num1, num2);
    }
    
    int (*select(char op))(int, int)//函数指针作为返回值
    {
        switch(op)
        {
            case '+' : return add;
            case '-' : return sub;
        }
    }
    
    int main()
    {
        int num1, num2;
        char op;
        int (*p)(int, int);//定义一个函数指针
    
        cout << "请输入一个公式(例如:3+3):";
        cin >> num1 >> op >> num2;
    
        p = select(op);
        cout << p << endl;//这里好奇的输出p,结果答案为1,不清楚怎么回事
        cout << num1 << " " << op << " " << num2 << " = " << (*p)(num1, num2) << endl;
        return 0;
    }

    这里我来解释一下 int (*select(char op))(int, int); 的构成,把该式子看成 int (*)(int, int);,这是不是函数指针了。为什么这么处理了。在C/C++ 中括号是有结合性和优先级的,括号内的select是函数的名称,char op是参数,*是返回类型,*具体返回的是什么呢,就是我们拆分的式子。

    3.回调函数(在一个项目文件下)

    //1.cpp
    #include <iostream>
    using namespace std;
    extern void fun(void(*p)(int));
    
    static void Output(int a)//被static修饰后,外部文件不能直接调用
    {
        cout << a << endl;
    }
    
    int main()
    {
        fun(Output);
        return 0;
    }
    //2.cpp
    void fun(void (*p)(int))
    {
      p(200);
    }

    这个例子比较绕,在1.cpp中调用2.cpp中的fun()函数,该函数的参数为函数指针,回到1.cpp中调用Output函数,最后输出该值。

    调用fun() ——函数指针——> fun() ——回调——> Output() 

    4.函数指针数组

    #include <iostream>
    using namespace std;
    
    int add(int num1, int num2)
    {
        return num1 + num2;
    }
    
    int sub(int num1, int num2)
    {
        return num1 - num2;
    }
    
    int main()
    {
        int i = 0, value;
        int data1, data2;
        int (*p[2])(int, int) = {add, sub};
    
        do{
            cout << "1: add" << endl;
            cout << "2: sub" << endl;
            cout << "else: exit" << endl;
            cout << "请选择:"  << endl;
            cin >> i;
    
            cout << "input data1, data2:" << endl;
            cin >> data1 >> data2;
            value = p[i-1](data1, data2);
    
            cout << "值为:" <<value << endl;
        }while(i == 1 || i==2);
        return 0;
    }

    个人不太清楚在定义数组时,是否要标明类型和个数,我亲测的,不一致的话是不行的。

    本人若有错误,请留评论区,虚心接受,谢谢!!!

    记录点点滴滴
  • 相关阅读:
    Markdown学习
    二叉树的最近公共祖先
    javaCompiler简析
    自定义类加载器
    聚合和组合的区别
    拓扑排序
    C++ map和unordered_map
    静态文件加载路径
    文件上传
    jackson
  • 原文地址:https://www.cnblogs.com/1by1/p/10362821.html
Copyright © 2011-2022 走看看