c++ - 传递函数指针

标签 c++ c function pointers parameter-passing

对于如何将指针传递给指针函数,我有点困惑。我有一个函数,它需要一个指向我理解没有问题的函数的指针(ExecBlock)。但是我得到了另一个函数原型(prototype)(ExecBlock2),它接受取消引用的指针(我不确定它到底是什么),并且如果传递的函数有任何参数,它也会接受参数。如果有人可以解释优先级以及取消引用指针函数会做什么。那不只是传递函数本身吗?在这种情况下 (void *) 做了什么?

int ExecBlock (void (*f) (void), int isSet)
{
    return ExecBlock2( HOW TO PASS HERE? , NULL, isSet);
}

int ExecBlock2(void *(*f)(void *), void *arg, int isSet)
{
    ... more code
}

最佳答案

void (*f) (void)

表示指向函数的指针,没有返回 void 的参数。

void *(*f)(void *)

表示指向函数的指针,该函数接受一个 void 指针并返回一个 void 指针。

由于类型不同,编译器不允许您在不强制转换的情况下将一个传递给另一个。 (请注意,强制转换在这里并不是真正的正确答案,正如@detly 指出的那样,会导致未定义的行为。)

至于解引用函数指针,您不必在函数指针之前显式放置一个“*”来调用它。例如,你可以调用你的函数指针 f 只是这样做

f();

函数指针示例

假设你有一个函数 f,你想将它传递给一个名为 takes_a_function 的函数。 takes_a_function 可能会有一个类似

的类型
void takes_a_function(void (*f)(void *data), void *data);

注意 takes_a_function 有两个参数,一个函数指针和一个指向某些数据的 void 指针。另请注意,函数 f 恰好将 void 指针作为参数。这个想法是您可以将数据传递给 takes_a_function,然后它会将其传递给 f。例如,takes_a_function 可以这样定义

void takes_a_function(void (*f)(void *), void *data) {
  f(data);
}

现在,让我们编写一个函数来传递给 takes_a_function。我们的函数只会打印一个传递给它的 int。

void prints_an_int(void *data) {
  // The idiom for converting a void pointer to another kind
  // of pointer.  NO NEED TO CAST.  Note this behavior is only
  // defined if the pointer data really does point to an int.
  int *i = data;
  printf("%d", *i);
}

int i = 0;
takes_a_function(prints_an_int, &i);

关于这个例子的几个关键点:

  • prints_an_inttakes_a_function 所期望的函数指针具有相同的类型。无需转换。
  • 无需使用 & 运算符来创建对函数的引用。这就是为什么我们可以直接将 prints_an_int 传递给 takes_a_function 的原因。但是我们也可以说takes_a_function(&prints_an_int, &i),也是一样的。
  • void* 基本上意味着“指向未知类型的指针”。要实际使用它,您必须将 void* 类型的变量分配给另一个您期望其类型的指针变量。仅当您实际传入正确的指针类型时,才能保证有效!在这个例子中,我们可以将 data 分配给 int*,因为 data 确实指向一个 int。如果您想要更多的数据而不仅仅是整数,一种常见的模式是创建您自己的结构类型,其中包含您想要的所有字段,然后将其传递。
  • 作为一种特殊情况,编译器不要求您在将 void 指针分配给其他指针时进行强制转换,反之亦然。但同样,只有最终将 void 指针转换回正确的类型时,您才会得到定义的行为。

关于c++ - 传递函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19417826/

相关文章:

c - 如何使用数字数组中的十六进制字符创建数组

c函数指针解释

c++ - 带有参数的模板传递成员函数和返回值作为参数c++

python - 返回和打印在 python 中的区别?

c++ - 将秒转换为分钟且余数小于10秒时如何包含前导零?

c++ - 在 Visual Studio 2017 中使用函数从 main 创建和初始化数组

使用 getchar() 读取字符串的 C 提示排序

c - 使用 Visual Studio 2015 进行编译时,将控制台(或标准输出)重定向到命名管道不再起作用

c++ - 翻译以前绘制的元素 (OpenGL)

c++ - 测试 stream.good() 或 !stream.eof() 读取最后一行两次