2016-06-10 99 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參數,寄存器參數或存儲器的參數。對於接近通話,這三種方法都可用。對於遠程調用,只有中間和內存參數可用。這意味着通常,通過指針調用函數將會有一點損失,因爲調用的地址必須在使用其他指令進行實際調用之前從內存中加載。中間操作數調用還必須加載從內存調用的地址(在指令獲取階段),但不需要單獨的指令來執行此操作,所以這比較快(一個或兩個週期)。