更蛋疼的函数指针

本文使用C++/Pascal两种语言

上次说到了C++的指针,还不算很蛋疼,今天这个是相当蛋疼:函数指针!

所谓函数指针,顾名思义,就是指向函数的指针。说白了,就是这个指针可以指向不同的函数,通过这个指针,可以调用不同的函数。原来我以为只有PHP这类动态语言才会有这种东西,前几天看了看C++ Primer才知道C/C++也是可以的。Code time!
1
2
3
4
5
6
7
8
double pow(double a, int b)
{
  double ans = 1;
  for (int i=1; i<=b; ++i) ans*=a;
  return ans;
}
double (*aa)(double, int) = &pow;//定义了一个指针aa,并把它指向了形参列表和返回类型都匹配的函数pow
cout << aa(2, 10);//等同于调用pow(2, 10);
指针函数要求所指向的函数的形参列表和返回类型与指针的定义相同(inline除外),pascal同理,但更好理解点:
1
2
3
4
5
6
7
8
9
10
var aa:function (a:extended;b:longint):extended;
function pow(a:extended;b:longint):extended;
  var i:longint;
  begin
    pow:=1;
    for i:=1 to b do pow:=pow*a;
  end;
begin
  writeln(aa(2,10));
end.
有个简单的应用例子:输入a,输入一个二元运算符,输入b,输出计算结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
#include <iomanip>

inline double plus(double a, double b)
{
  return a+b;
}
inline double minus(double a, double b)
{
  return a-b;
}
inline double multiply(double a, double b)
{
  return a*b;
}
inline double divide (double a, double b)
{
  return a/b;
}
double power(double a, double b)
{
  int B = static_cast<int>(b);
  double ans = 1;
  for (int i=1; i<=B; ++i) ans*=a;
  return ans;
}

typedef double (*operatorType)(double, double);
operatorType fun[256];

int main()
{
  fun['+'] = &plus;
  fun['-'] = &minus;
  fun['*'] = &multiply;
  fun['/'] = &divide;
  fun['^'] = &power;

  double x, y;
  char ope;
  std::cin >> x >> ope >> y;
  std::cout << std::setprecision(4) << fun[ope](x, y);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{$inline on}
type OperatorType=function (a,b:extended):extended;
var x, y:extended;
    ope:char;
    fun:array[#0..#255]of OperatorType;
function plus(a,b:extended):extended;inline;
  begin
    exit(a+b);
  end;
function minus(a,b:extended):extended;inline;
  begin
    exit(a-b);
  end;
function multiply(a,b:extended):extended;inline;
  begin
    exit(a*b);
  end;
function divide(a,b:extended):extended;inline;
  begin
    exit(a/b);
  end;
function power(a,b:extended):extended;
  var i:longint;
  begin
    power:=1;
    for i:=1 to trunc(b) do power:=power*a;
  end;
begin
  fun['+']:=@plus;
  fun['-']:=@minus;
  fun['*']:=@multiply;
  fun['/']:=@divide;
  fun['^']:=@power;

  readln(x);
  readln(ope);
  readln(y);
  writeln(fun[ope](x,y):0:4);
  readln;
end.

Comments