2016-06-10 103 views
3

我想知道什么是它的名字一样调用函数用C用它的名字和函数指针

int sum(int x,int y) 
{ 
    return x+y; 
} 

int main() 
{ 
    int z = sum(5,7); 
} 

调用函数之间的差别,并通过指针调用的功能就像

int sum(int x,int y) 
{ 
    return x+y; 
} 

int main() 
{ 
    int (*ptr)(int,int); 
    ptr =∑ 
    int z = (*ptr)(5,7); 
} 

执行时间或任何东西有任何区别吗?

+1

答案是:使用_profiler_(如[gprof的(http://sourceware.org/binutils/docs/gprof/),也看看[这里](https://en.wikipedia.org /wiki/List_of_performance_analysis_tools#C_and_C.2B.2B)) – ForceBru

+1

查看生成的汇编代码... – LPs

+1

您还可以将您的最后一个示例写为'ptr = sum; int z = ptr(5,7);'。 – melpomene

回答

6

对于编译器,这是很easyer优化,通过名字调用函数的代码,因为它是在编译时什么代码调用该函数闻名。

另一方面,使用(非const)函数指针很难知道指针指向哪个函数,因此编译器可能无法通过函数指针优化(例如内联)函数调用。

+0

性能最相关的方面。额外获取指令可以忽略不计 – Illishar

0

第一个将被汇编翻译为带有inmediate参数的CALL。第二个将被转换为一个带有寄存器或内存地址作为参数的CALL(间接调用)。

查阅这两种方法的performane由目标机器的支持调用与其它的子程序比inmediate参数的能力来确定。

例如,the x86 instruction set允许CALL指令有一个inmediate参数,寄存器参数或存储器的参数。对于接近通话,这三种方法都可用。对于远程调用,只有中间和内存参数可用。这意味着通常,通过指针调用函数将会有一点损失,因为调用的地址必须在使用其他指令进行实际调用之前从内存中加载。中间操作数调用还必须加载从内存调用的地址(在指令获取阶段),但不需要单独的指令来执行此操作,所以这比较快(一个或两个周期)。