2

我在这里看到了几乎所有流行的回调问题,但仍然不明白为什么在回调中使用函数指针而不是简单地通过普通函数使用回调。这是一个热门问题 的公认答案(修改后)

void populate_array(int *array, size_t arraySize,
            int getNextValue(void))  // Note that, here I use normal function call.
{
    for (size_t i=0; i<arraySize; i++)
        array[i] = getNextValue();
}

int getNextRandomValue(void)
{
    return rand();
}

int main(void)
{
    int myarray[10];
    populate_array(myarray, 10, getNextRandomValue);
    ...
}

正如你在上面看到的,我仍然可以通过简单的函数实现回调实现,那么为什么要使用函数指针来实现回调。(即为什么要通过参考),当我可以做到这一点时。

此外,我们可以qsort, bsearch在没有函数指针的情况下实现以在其中提供回调。那么,为什么要使用指向函数的方式。

4

1 回答 1

2
void populate_array(int *array, size_t arraySize,
        int getNextValue(void))  // Note that, here I use normal function call.

这不是函数调用:你不能在声明中调用函数。getNextValue是一个指向函数的指针,它不带参数并返回int使用不同语法声明的函数。

考虑这个类比:您可以为指针定义一个新类型,int并在函数声明中使用它

typedef int* intptr_t;
void myFunction(intptr_t ptr) {
    ...
}

或者你可以说这ptr是一个指向int声明内部的指针:

void myFunction(int* ptr) {
    ...
}

同样,您可以在声明中使用函数指针之前定义函数指针的类型

typedef void generator_t(void);
void populate_array(int *array, size_t arraySize, generator_t getNextValue) {
}

或者您可以说这getNextValue是使用您帖子中的替代语法的函数指针。

使用typedeffor 函数指针的一个原因是当您想要创建函数指针数组时进行一致性检查:如果您的库函数使用在该函数声明中定义的函数指针,则需要在自己的代码中重新创建相同的声明以创建一个要作为指针传递给库的指针数组。这可能会导致不一致,这些不一致仅在调用库函数时可见,而不是在数组声明时可见,从而使潜在问题更难追踪。

于 2013-07-19T15:12:35.307 回答