• C++学习笔记之函数指针


    与数据项类似,函数也有地址。函数的地址是存储其机器语言代码的内存开始的地方。

    一、函数指针的基础知识

    假设要设计一个名为estimate()的函数,估算编写指定行数代码所需时间,并且希望不同的程序员都使用该函数,并且该函数允许每个程序员提供自己的算法来估计时间。为实现这种目标,采用的机制是,将程序员要使用的算法函数地址传给estimate(),必须完成以下工作:

    • 获取函数地址
    • 声明一个函数指针
    • 用函数指针来调用函数

    1.获取函数地址

    使用函数名(后面不跟参数)即可。如:think()是一个函数,则think就是该函数的地址。要将函数作为参数进行传递,必须传递函数名。

    一定要注意区分传递的是函数的地址还是函数的返回值:

    1 process(think);    //传递函数think()的地址给process()
    2 thought(think()); //传递函数think()的返回值给though()

    2.声明函数指针

    声明应指定指针所指向的函数的返回类型以及函数的特征标(参数列表),假设Pam编写了一个估算时间的函数,其原型如下:

    1 double pam(int);    // 函数声明

    则正确的指针类型声明如下:

    1 double (*pf) (int); 
    2 // pf指向一个输入一个int参数,返回一个double值得函数

    可以看出,就是将函数声明中的函数名替换为*pf, 于是pf就成为指向函数的指针,由指针的基本知识可以知道,(*pf)也是函数。

    必须在声明中用括号将*pf括起,否则如下:

    1 double *pf(int);

    这相当于声明了一个函数pf,它的返回值是一个指向double的指针,与我们想要声明的函数指针完全不是一码事。

    正确声明pf之后,便可以将相应的函数地址赋给它:

    1 double pam(int);
    2 double (*pf)(int);
    3 pf = pam;

    现在指针pf就指向函数pam()了。再次强调pam()的特征标和返回类型必须与pf相同。

    假设现在要将编写的代码行数和估算算法(如pam()函数)的地址传递给estimate(),原型如下:

    1 void estimate(int lines, double (*pf)(int));

    要让estimate()使用pam()函数,需要将pam()的地址传给它:

    1 estimate(50, pam);

    3.使用指针来调用函数

    上面讲过,(*pf)扮演的角色与函数名相同,因此使用(*pf)时,只需将它看作函数名即可:

    1 double pam(int);
    2 double (*pf)(int);
    3 pf = pam;
    4 double x = pam(4);   // 用函数名调用函数
    5 double y = (*pf)(5);  // 用指针pf调用函数

    但是,C++也允许像使用函数名那样使用pf:

    double y = pf(5);  //与double y = (*pf)(5)效果一样

    为何pf与(*pf)等价呢?因为存在两种看法,一种学派认为,由于pf是函数指针,而*pf是函数,因此应将(*pf)()用作函数调用;而另一种学派认为,由于函数名是指向该函数的指针,指向函数指针的行为应与函数名相似,因此应将pf()用作函数调用。看上去都是合理的说法,因此C++进行了折衷--两种方法都正确,虽然在逻辑上相互冲突。

    二、函数指针示例

     1 /*函数指针示例*/
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 //将会被调用的两个函数的声明
     7 double betsy(int);
     8 double pam(int);
     9 
    10 //estimate()声明
    11 void estimate(int lines, double (*pf)(int));
    12 
    13 int main()
    14 {
    15     int code;
    16 
    17     cout << "请输入代码行数:";
    18     cin >> code;
    19     cout << "Betsy的评估结果:
    ";
    20     estimate(code, betsy);
    21     cout << "Pam的评估结果:
    ";
    22     estimate(code, pam);
    23     return 0;
    24 }
    25 
    26 double betsy(int lns)
    27 {
    28     return 0.05 * lns;
    29 }
    30 
    31 double pam(int lns)
    32 {
    33     return 0.03 * lns + 0.0004 * lns * lns;
    34 }
    35 
    36 void estimate(int lines, double (*pf)(int))
    37 {
    38     cout << lines << "行代码将耗时 ";
    39     cout << (*pf)(lines) << " 小时
    ";
    40 }

    运行结果:

  • 相关阅读:
    HDU 1069 Monkey and Banana
    HDU 1029 Ignatius and the Princess IV
    HDU 1024 Max Sum Plus Plus
    Gym100923H Por Costel and the Match
    Codeforces 682C Alyona and the Tree
    Codeforces 449B Jzzhu and Cities
    Codeforces (ccpc-wannafly camp day2) L. Por Costel and the Semipalindromes
    Codeforces 598D (ccpc-wannafly camp day1) Igor In the Museum
    Codeforces 1167c(ccpc wannafly camp day1) News Distribution 并查集模板
    快乐数问题
  • 原文地址:https://www.cnblogs.com/90zeng/p/Cpp_function_pointer.html
Copyright © 2020-2023  润新知