2012-06-04 48 views
6

你好朋友,
How can I use an array of function pointers?
如果我們將看到上面的鏈接,它告訴我們函數指針如何工作。
現在的問題是爲什麼我應該選擇函數指針?
爲什麼我不能直接使用函數調用?
函數指針會帶來什麼好處?
函數指針與函數調用有什麼區別?

enum{a, b, c}; 
void A(); 
void B(); 
void C(); 
void (*fun[3])() = {A, B, C}; 

Now when I need to call a function I am doing like, 
fun[a](); // This calls function A 
// And so on... 

同樣可以在功能上做也

調用就像當我需要調用函數A,B或C. 直接我可以用鼠標右鍵像

A(); 
B(); 
or 
C(); 

那麼,爲什麼function pointer

+2

我不知道爲什麼有兩個反對票對我的問題。但我知道的一件事,並不意味着如果你知道每個人都應該知道的東西。無論如何+ ve或-ve投票並不重要,只要我的疑惑得到解決。 –

回答

5

現在的問題是爲什麼我應該選擇函數指針?
函數指針會帶來什麼好處?

當需要實現異步機制時使用函數指針。
發生事件時,需要一個異步調用的函數。
您如何知道要調用哪個函數?
每個函數的地址都是唯一的,所以您需要使用和存儲函數地址。
你在哪裏存儲這個函數地址?
一個函數指針

2

函數指針是指向函數地址的指針(如變量指針)。當你像引用函數一樣將它們解引用時,它們實際上會調用底層函數。

一個函數指針的主要優點是,你可以把它傳遞給另一個函數的參數例如...

3

以我的經驗,函數指針,主要用來傳遞函數作爲參數到另一個功能。看看你的代碼,它們也可以像數組一樣使用,所以你可以循環遍歷整個數組(它可以包含數百個函數指針),它將只執行它們。

11

有很多理由使用函數指針,特別是爲C.

一般做的事情,你會看到使用他們的主要場所是作爲參數傳遞給一個函數。例如與功能bsearch,它使用了一個比較功能,作爲一個函數指針傳遞,比較項目和排序數據:

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

這使得bsearch是通用和排序任何類型的數據,由於只比較函數必須知道數據的類型。


另一個與避免多重檢查有關。即。

void makePizza(void) { } 

void bakeCake(void) { } 

iWantPizza = 1; 
... 
if (iWantPizza) 
    makePizza(); 
else 
    bakeCake(); 
/* want to call the same function again... */ 
if (iWantPizza) 
    makePizza(); 
else 
    bakeCake(); 

.. 

/* alternative */ 
void (*makeFood)(void) = iWantPizza ? makePizza : bakeCake; 

makeFood(); 
/* want to call the same function again... */ 
makeFood(); 
6

對於您顯示的示例,還可以做一件事。

可以說有一堆功能需要運行一些設備操作。 簡單地說,您可以將所有函數調用寫入另一個主函數,並調用該函數。

另一種方法是將所有函數名寫在一個大括號中,並使用函數指針和循環來調用它們。這看起來很聰明。我不知道如何以更好的方式幫助你,但我在linux內核代碼中看到了這一點。


我同意這裏的所有答案。除此之外,我還有一些自己的判斷使用函數指針。讓我們舉一些複雜的數學計算(如打印斐波那契,積分,傅立葉變換等等)。

你有一個函數FX(它可以完成複雜的數學計算或其他任何事情),你可以在程序中使用很多次。此功能用於許多不同的工作。

使用你的程序幾個月後,你會發現,對於某些工作,你可以改進功能,對於某些人來說,最好的方法是最好的。 你會做什麼?寫一個新的函數,去所有地方更改函數名稱。

每次你找到更好的東西,你都會做同樣的事情。

而是對不同的工作使用不同的函數指針。在初始階段,所有的指針都可以指向一個函數。當你爲某些工作發現更好的功能時,只需轉移指針即可完成。


另一種情況。 在這裏,你有一個真正的大代碼,如手機操作系統。 (不完全開放,但一半編譯)。 您需要爲特定硬件添加藍牙驅動程序。

現在,您可以添加或者您可以離開是OS中可用的選項。

您可能需要從許多地方打開/關閉藍牙。

所以操作系統是做什麼的,它使一個函數指針將藍牙打開並在需要的地方使用它。此代碼已經編譯完畢,因此您無法在其中添加代碼。但是可以做的是,您可以編寫函數並將該指針指向您的函數。

這是我在Android OS下已經看到的。(不完全但更接近)

+1

我真的很喜歡複雜的數學計算的例子。 – johnny

3

函數指針與函數調用有什麼區別?

這就像要求編譯器「告訴我國家美術館的地址(我可能想稍後去那裏並且我想要做好準備去做)」之間的區別,而不是「帶我去國家美術館現在(但我不會關注你如何讓我在那裏,所以不要指望我以後知道)「。最重要的是,如果你問地址/指針,你可以在「下週日下午的大行程」這樣的地方寫下來......你甚至不必記住它是你要去的國家美術館 - 當你到達那裏時,它可能是一個令人驚喜的驚喜 - 但你立刻知道你星期天的娛樂節目是全部排序的。

函數指針會帶來什麼好處?

那麼,如上所述,在設置函數指針時,您需要做出關於稍後調用的地方的決定,但是您可以忘記做出該決定的所有原因,並且知道後來的目的地全部準備好使用。當你真的在做東西的時候......「我的星期天的例行公事:睡到10,吃大早餐,回去睡覺,洗澡,如果我有足夠的錢,然後去我的星期天下午的大旅行,結識朋友吃晚飯「......之前的決定剛剛開始讓你去畫廊。最重要的是,您可以繼續使用熟悉的星期日程安排,並在他們吸引您的目光時開始「指向」下一個星期日下午的「大旅程」地址/指針,即使它們在您的大致時間安排形成時並不存在。

您可以看到這種事後靈活性,可將目的地更改爲在舊程序中的一個步驟,以及AusCBloke提到的bsearchqsort是另一個典型的例子 - 它知道有效排序任意事物數組的大圖邏輯,但必須告訴哪裏去比較兩個實際使用它的東西。

1

這些都是很好的例子,尤其是Urvish上面的第一個例子。我想知道同樣的事情,我想答案是純粹的設計。在我看來,它們是相同的結果,因爲在你可以指向一個函數並得到一個+ b或者你可以定期調用一個函數並且得到一個+ b,並且通過SO上的例子,它們通常是小而平凡的爲了說明。 但是,如果你有一個10k行的C程序,並且你必須改變50次因爲你做了改變,你可能會很快拿起你爲什麼要使用函數指針。

這也讓你體會到OOP語言的設計和OOD背後的哲學。

相關問題