为什么要使用这种函数指针方法

时间:2014-05-30 06:03:20

标签: c pointers

昨天我了解了使用函数指针的这种非常酷的方法。 虽然我认为这是一件非常酷的事情,但我无法看到为什么会使用这种方法?

有人可以对此有所了解吗?

int Mul(int x , int y)
{
return x*y;
}

int Div(int x , int y)
{ return x/y;
}

typedef int (*FuncP)(int,int);

int compu(FuncP functionP, int x , int y)
{return functionP(x , y)}

//调用它看起来像

compu(Mul,5,10);

由于 车

2 个答案:

答案 0 :(得分:0)

指向函数的指针有多种用途,但是,坚持你的例子,指向函数的指针可以帮助你避免匆忙和丑陋的条件分支,如if&s;和switch:

如果创建操作字符的关联数组作为索引,并将函数指针指定为值:

//implementacion in C doesn't matter for the example
operations["*"] = Mul;
operations["/"] = Div;
operations["*"] = Add;
operations["-"] = Sub;

您可以这样做:

int op1;
int op2;
char operation;

cout << "Insert first number /n";
cin >> op1;
cout << "Insert second number /n";
cin >> op2;
cout << "Insert operator /n";
cin >> operation;
cout >> compu(operations[operation],op1,op2);

答案 1 :(得分:0)

如果您需要基于类似情况的动态:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdbool.h>

typedef int (*worker_operation)(int);

int check_for_new_woot(int inVal) {
  int ret = arc4random() % 10;
  if (ret < 5) {
    puts("Found new woot!");
    sleep(1);
    return 1;
  } else {
    puts("No new woot :(");
    sleep(1);
    return 0;
  }
}
int buy_current_woot(int inVal) {
  if (inVal != 0) {
    fprintf(stderr, "Insufficient funds!!!\n");
  }
  return 0;
}

int check_if_should_buy_woot(int inVal) {
  printf("Should we buy the latest woot? ");
  char input[10];
  read(STDIN_FILENO, input, 10);
  if (input[0] == 'y') {
    return 1;
  } else {
     return 0;
  }
}

void *worker_thread(void *inVal) {
  worker_operation *ops = (worker_operation *)inVal;
  int i = 0;
  worker_operation op = ops[i];
  int arg = 0;
  while (op) {
    arg = op(arg);
    op = ops[++i];
  }
  free(ops);
  return NULL;
}

pthread_t start_worker(worker_operation *ops) {
  pthread_t pt;
  pthread_create(&pt, NULL, worker_thread, ops);
  return pt;
}

int main(int argc, const char *argv[]) {
  bool autoBuy = true; // fetch whether we should automatically buy from woot.com from argv or stdin
  int numberLoops = 10; // fetch number of times to loop through the process
  int i;
  worker_operation *operations;
  if (autoBuy) {
    operations = (worker_operation *)malloc(sizeof(worker_operation) * (numberLoops * 2 + 1));
    for (i = 0; i < numberLoops; i++) {
      operations[2 * i] = check_for_new_woot;
      operations[2 * i + 1] = buy_current_woot;
    }
    operations[2 * i] = (worker_operation)NULL;
  } else {
    operations = (worker_operation *)malloc(sizeof(worker_operation) * (numberLoops * 3 + 1));
    for (i = 0; i < numberLoops; i++) {
      operations[3 * i] = check_for_new_woot;
      operations[3 * i + 1] = check_if_should_buy_woot;
      operations[3 * i + 2] = buy_current_woot;
    }
    operations[3 * i] = (worker_operation)NULL;
  }
  pthread_join(start_worker(operations), NULL);
  return 0;
}

请注意,在此代码段中,代码片段在两个位置使用函数指针。我们有一个与用户希望程序执行方式无关的函数,即start_worker只创建一个可以处理操作列表的工作线程。这可以很容易地用于创建一个程序,该程序具有多个具有不同操作队列的线程。第二位函数指针用于线程。 ptrhead_create调用使用函数指针来创建新线程(指定的函数是要在新线程上运行的函数)。

通常这称为命令编程范例。可以轻松地创建另一部分代码可以调用的操作,不知道该函数的功能。例如,在以下情况下,这对游戏很有用:

  

我们有一个提供输入的游戏控制器。用户点击“向上”。在代码中调用挂钩到'up'操作的操作。

这种模块化方法允许人们启用控件的设置,这样有人可以将“跳转”操作挂钩到“向上”或“向前移动”操作,或任何真正的操作。

希望这有帮助!