【问题标题】:Buffer of function pointers?函数指针的缓冲区?
【发布时间】:2015-03-04 22:05:38
【问题描述】:

我知道这听起来很科幻,但我真的想调用一个函数 x 次,方法是使用指向它的函数指针数组,而不涉及循环或任何可能减慢目标程序的东西。这可能吗?如果可以,具体怎么做?

【问题讨论】:

  • 当然有可能,但是为什么需要一个函数指针数组来调用函数 x 次呢?只需调用 x 次即可。
  • 您的编辑听起来像是一种微优化,在大多数实际场景中(至少在现代 CPU 上)不太可能产生影响。
  • 复制函数指针不会使函数线程安全。该函数仍然是一个函数,它的静态存储仍然在一个地方。如果函数已经是线程安全的,那么你不需要做任何事情,只需多线程即可。编辑:谷歌为 SPMD 或 OpenCL
  • 好吧,现在我完全糊涂了。您从 “运行函数 x 次而不是循环” 开始,然后移至 “同时调用许多函数”,然后移至 “函数 ... 是只调用一次”。我认为你需要决定你到底想做什么,然后编辑问题来描述它。
  • 你对循环的痴迷是什么?在所有情况下,函数 body 的执行成本(cpu 时间)都比调用者的 invocation 多。你真的想要 parallellism 吗? (在前一个函数调用返回之前调用一个函数)

标签: c function pointers c89


【解决方案1】:

这是一个深度有限递归的例子

void hello( int depth )
{
    printf( "hello %2d\n", depth );
    if ( depth > 1 )
        hello( depth - 1 );
}

int main()
{
     hello( 10 );    // call the hello function 10 times
     hello( 17 );    // call the hello function 17 times
}

这是一个使用跳转表多次调用函数指针的示例。请注意,对于跳转表,最大调用次数受限于跳转表的大小(本例中为 10),而对于递归,调用次数仅受堆栈大小的限制。

int hello( int n )
{
    n++;
    printf( "hello %2d\n", n );
    return n;
}

void executeFunction( int (*func)(int), int count )
{
    int n = 0;
    switch ( count )
    {
        case 10:  n = (*func)(n);
        case 9:   n = (*func)(n);
        case 8:   n = (*func)(n);
        case 7:   n = (*func)(n);
        case 6:   n = (*func)(n);
        case 5:   n = (*func)(n);
        case 4:   n = (*func)(n);
        case 3:   n = (*func)(n);
        case 2:   n = (*func)(n);
        case 1:   n = (*func)(n);
    }
}

int main()
{
    executeFunction( hello, 3 );   // call the hello function 3 times
    executeFunction( hello, 9 );   // call the hello function 9 times
}

【讨论】:

  • ....这会使程序长时间停滞不前,尤其是在函数调用次数很大的情况下。这就是为什么我明确地说..没有循环。好几次。 for(; ;) 是最明显的循环。
  • @DeltaProxy 你显然不明白 for 循环在这里的用途。这是一个“无限”循环,用于获取用户输入。这个答案的本质是递归。循环可以完全省略。
  • @DeltaProxy 那里,全部固定,没有循环。
  • 是的,实际上这必须按要求行事。
  • @user3386109 不幸的是,我只能使用递归函数来做到这一点。
【解决方案2】:

您可以使用预处理器将宏扩展为 x 个函数调用。你的代码会变大,你仍然会运行函数 x 次。它不会为你赢得任何东西。

#define REPEAT5(x) { x; x; x; x; x; }

请注意,您不能像调用函数一样调用该宏(如果以分号结束调用,它将扩展为语法错误)。一个更简洁的宏(尽管在这种情况下,这有什么关系?)将是:

#define REPEAT5(x) do { x; x; x; x; x; } while(0)

然后你可以像调用函数一样调用宏,但它会扩展为循环并且你说你不喜欢循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    • 2016-03-01
    相关资源
    最近更新 更多