Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么是函数指针而不是直接调用函数_C - Fatal编程技术网

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

C 为什么是函数指针而不是直接调用函数,c,C,我遇到了函数指针。我知道这是怎么回事。但我不太确定,在什么情况下它会使用。经过一些谷歌和其他搜索,堆栈溢出。我知道它将用于两种情况 当使用回调机制时 存储函数数组,以便动态调用 在这种情况下,我们为什么不直接调用函数呢。在回调机制中,当特定事件发生时,回调指针也被分配给该函数(地址)。那就叫做。我们不能直接调用函数而不是使用函数指针吗。有人能告诉我,函数指针的确切用法是什么,在什么情况下。看看需要回调的函数,比如 或用于比较器、处理程序或其他 另外,您希望如何编程其他开放式可扩展机制,比如类似C

我遇到了函数指针。我知道这是怎么回事。但我不太确定,在什么情况下它会使用。经过一些谷歌和其他搜索,堆栈溢出。我知道它将用于两种情况

当使用回调机制时

存储函数数组,以便动态调用


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

看看需要回调的函数,比如

或用于比较器、处理程序或其他

另外,您希望如何编程其他开放式可扩展机制,比如类似C++的虚拟分派(
vptr
-table,带有函数指针和其他东西)

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

您说过:

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

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

一个简单的例子:

在GUI中,按下按钮时注册函数的位置是顶级应用程序设置。调用函数的地方是按钮的实现。它们需要保持分离,以允许按钮的用户在按下按钮时可以自由地执行他们希望执行的操作


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

函数指针有用的一种情况是当您尝试实现回调函数时

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


API(了解event_new())还展示了在API中设置函数点的有用性,这样用户可以在特定情况下定义自己的行为,而无需修改主函数的代码,从而在保持一定抽象级别的同时创造灵活性。这种设计也广泛用于内核API。

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

有时,我使用函数指针只是为了(在我看来)使代码更清晰,更易于更改。但这是一个品味的问题,没有一个“正确”的方法。函数指针代码可能会变慢,但可能只是稍微慢一点,当然,就性能而言,这始终是一个衡量的问题,通常更多的是选择更好的算法,而不是微观优化

一个例子是,当您有两个函数,具有相同且较长的参数列表,并且有时要调用其中一个,有时要调用另一个。你可以写

if ( condition)
{ one( /* long argument list */);
}
else
{ other( /* long argument list */);
}
(condition ? one : other)(/* long argument list */);
或者你可以写

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
}


我再次发现第二种形式更易于维护,但可能这只是我的问题。

函数指针在您事先不知道将调用哪个函数时使用。不能将函数作为参数传递给另一个函数,只能传递函数指针。简单的例子是谓词。处理速度有什么不同吗?直接调用函数或指向该函数的函数指针是的,间接调用通常效率较低。尽管如此,除非你真的确定(测量!)这是瓶颈,否则不要对此感到困扰。而且,当你不得不使用它的时候,你就这么做。