为什么使用函数指针而不是直接调用函数

时间:2014-12-15 04:11:53

标签: c

我遇到了函数指针。我知道这是如何工作的。但我不太确定,它会在什么情况下使用。在Stack Overflow中进行了一些google和其他搜索。我知道它将在两种情况下使用

  

使用回调机制时

     

存储一系列函数,动态调用。

在这种情况下,为什么我们不直接调用函数。在回调机制中,当特定事件发生时,回调指针被分配给该函数(地址)。那就叫了。我们不能直接调用函数而不是使用函数指针。有些人可以告诉我,函数指针的确切用法是什么,以及在什么情况下。

5 个答案:

答案 0 :(得分:6)

看一下需要回调的功能,比如

比较器为

bsearchqsort,处理程序为signal或其他。

另外,您希望如何编写其他可扩展的机制,如C ++ - 如虚拟调度(vptr - 带有函数指针和其他东西的表)?

简而言之,函数指针用于通过使用户定义的行为的一部分来使函数通用。

答案 1 :(得分:3)

当您尝试实现回调函数时,函数指针很有用的情况之一。

例如,在我用C实现的服务器中,libevent接受来自客户端的消息并确定要做什么。我没有定义数百个switch-case块,而是存储要在哈希表中调用的函数的函数指针,以便可以将消息直接映射到相应的函数。

Event handling in libevent API(读取有关event_new())还演示了在API中使用功能点的有用性,以便用户可以在特定情况下定义自己的行为,而无需修改主函数的代码,这会创建灵活性,同时保持一定的抽象水平。此设计也广泛用于内核API。

答案 2 :(得分:1)

你说:

  

在回调机制中,当特定事件发生时,回调指针被分配给该函数(地址)。

回调函数的注册位置与调用回调函数的位置非常不同。

一个简单的例子:

在GUI中,按下按钮时注册功能的位置是您的顶级应用程序设置。调用函数的位置是按钮的实现。它们需要保持分离,以允许按钮的用户在按下按钮时具有他们想要做的自由。

通常,当需要存储指针以供将来使用时,需要一个函数指针。

答案 3 :(得分:0)

在回调情况(包括中断驱动代码)的情况下,单个逻辑进程可能会发生一系列回调或中断。假设您有一组函数,如step1(),step2(),...,以执行某些过程,其中使用公共回调来逐步执行序列。初始调用将回调设置为step1(),当调用step1()时,它将指向函数的指针更改为step2()并启动下一步。当该步骤完成时,调用step2(),它可以设置指向step3()的函数的指针,依此类推,具体取决于执行序列所需的步骤数。我主要使用这种方法来处理中断驱动的代码。

答案 4 :(得分:0)

有时我使用函数指针只是为了使代码更清晰,更容易更改(我认为)。但这是一个品味问题,没有一个'正确'的方式。函数指针代码可能会慢一点,但可能只是稍微有点当然,就性能而言,它总是一个测量问题,通常更多的是选择比微优化更好的算法。

一个例子是你有两个函数,有相同和长的参数列表,有时你想调用一个,有时你想调用另一个。你可以写

if ( condition)
{ one( /* long argument list */);
}
else
{ other( /* long argument list */);
}

或者你可以写

(condition ? one : other)(/* long argument list */);

我更喜欢第二个,因为只有一个长参数列表的实例,因此更容易正确,并且更改。

另一种情况是实施状态机;一个人可以写

switch( state)
{ case STATE0: state = state0_fun( input); break; 
// etc
}

typedef int (*state_f)( void*);
state_f statefs[] = { state0_fun /* etc */}

state = statefs[ state](input);

我再次发现第二种形式更易于维护,但也许只是我。