【问题标题】:Why use this method of function pointers [duplicate]为什么要使用函数指针的这种方法[重复]
【发布时间】:2014-05-30 06:03:19
【问题描述】:

昨天我了解到这种使用函数指针的非常酷的方法。 虽然我认为能够做到这一点真的很酷,但我看不出为什么会在哪里使用这种方法?

有人能解释一下吗?

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);

谢谢 购物车

【问题讨论】:

  • 它们可以用作事件驱动编程中的回调函数以及其他各种东西

标签: c pointers


【解决方案1】:

如果您需要根据这样的情况进行动态处理:

#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;
}

请注意,在这段代码中,sn-p 在两个地方使用了函数指针。我们有一个函数不知道用户希望程序如何执行,即start_worker 只是创建一个工作线程来处理操作列表。这可以很容易地用于创建一个程序,该程序具有多个线程,所有线程都使用不同的操作队列。使用函数指针的第二个地方是线程。 ptrhead_create 调用使用函数指针来创建新线程(指定的函数是要在新线程上运行的函数)。

这通常称为命令编程范式。可以轻松地创建另一部分代码可以调用的操作,而与函数的作用无关。例如,这可能对以下情况下的游戏有用:

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

这种模块化方法允许启用控件设置,以便某人可以将“跳跃”操作与“向上”或“前进”操作挂钩,或任何其他操作。

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    指向函数的指针有多种用途,但是,按照您的示例,指向函数的指针可以帮助您避免像 if 和 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);
    

    【讨论】:

    • 使用 c++ 我不相信你可以有一个名为 operator 的变量:P
    • @DanZimm 你是对的!我是从头顶写的例子,没有考虑关键字。好点子。无论如何,我使用 C++ 是为了简单和快速原型,并没有任何特殊原因。
    • 一切都好,只是被砍了;D
    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多