【问题标题】:Pointers to functions utility指向函数实用程序的指针
【发布时间】:2014-02-06 16:00:32
【问题描述】:

函数指针有什么用处?例如,如果我有这个:

#include <stdio.h>

void Print1(int(*number)(void)){
   printf("%d", number());
}

void Print2(int a)
{
   printf("%d", a);
}
int con(void)
{
   return 2;
}
int main(void)
{
   Print1(&con);
   Print2(con());
}

两者都给出相同的结果,一个带有指向函数的指针,另一个带有调用另一个函数的函数,结论?我看不出有什么区别。

【问题讨论】:

  • 你能更清楚Print1函数定义中的connumber吗?他们不会打字吗?

标签: c pointers function-pointers


【解决方案1】:

在你的第一个例子中:

Print1(&con);

您将函数本身传递给Print1。在你的第二个例子中:

Print2(con());

当您调用Print2 时,您正在调用con,并将该值传递给Print2。如果con 有副作用,这一点很重要。想象一个方法在后台做一些需要很长时间的事情(比如磁盘读取)。如果您构建它以获取指向完成函数的函数指针,则该函数将在任务完成时调用。如果你不这样做,你只是在启动函数之前调用了你的完成函数。

想象一下,如果你有一个这样定义的函数:

void LongTask(void(*completed)()) {
  sleep(5);
  completed();
}

它必须被定义为接受一个函数指针,否则回调将在函数开始之前被调用。

【讨论】:

    【解决方案2】:

    看stdlib.h中的函数qsort

     void qsort(void *base, size_t nmemb, size_t size,
            int(*compar)(const void *, const void *));
    

    它使用快速排序算法对大小为大小的对象的数组基数、大小 nmemb 进行排序 - 但具有您提供的比较功能。因此,如果您想对其中包含奇怪数据类型的数组进行排序,您只需要编写比较函数,而不是整个快速排序算法。

    显然windows在它的消息循环中也使用了回调函数,我想人们可以找到很多例子来展示它的用处(坦率地说,我觉得在某些情况下它几乎是必需的)

    【讨论】:

    • 而且回调函数的替代方案很糟糕:轮询。
    【解决方案3】:
    Print2(con());
    

    只是该函数的返回值,而不是指向该函数的指针。

    【讨论】:

      【解决方案4】:

      其他人已经对您的示例代码的细节发表了评论,所以我将尝试解决您的问题:函数指针有什么用处? 概括地说:

      函数指针在 C 中特别有用 *(见底部的 *)当你有一组相似的函数时,它们 包含相同的参数列表,但具有不同的输出。您可以定义一个函数指针数组,例如,可以更轻松地从开关、循环或在池中创建一系列线程时调用该系列中的函数,这些线程包括类似的工作函数作为参数。调用数组使其变得像更改数组的索引一样简单,以获得每个独特情况所需的特定功能。

      举个简单的例子strcat()strcpy()这两个字符串函数有一个参数列表:(char *, const char *),因此,可以赋值给一个数组的函数指针。首先创建函数指针数组:

      char * (*pStr[2])( char *a, const char *b);` //array of function pointers pStr[]  
      

      然后,将 strcat 和 strcpy 赋值给数组:

      void someFunc(void)
      {
          pStr[0] = strcat; //assign strcat to pointer [0]
          pStr[1] = strcpy; //assign strcpy to pointer [1]
      }
      

      现在,strcat()strcpy() 可以称为:

      int main(void)
      {
          char a[100]="kjdhlfjgls";
          char b[100]="kjdhlfjgls";
      
          someFunc();//define function pointers
      
          pStr[0](a, "aaaaaaaa");  //strcat
          pStr[1](b, "aaaaaaaa");  //strcpy
      
          return 0;
      }  
      

      示例输出

      这只是一个简单的例子。它没有探讨函数指针所能提供的全部用途,但说明了为什么函数指针在某些情况下可能更受欢迎的另一个原因。

      * 此插图仅针对 C,与 C++ 不同,在 C++ 中,该语言固有的继承和多态特性会导致这个建议是不必要的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多