簡體   English   中英

通過函數指針調用函數

[英]Calling a function through a function pointer

我不知道如何通過指針調用函數。

例如,我有這個指針: int (*ptr)() = a_function;

要調用一個函數,我必須寫這樣的東西ptr()(*ptr)()

這些通話之間有什么區別? 如果我寫printf("%p - %p", ptr, *ptr)在兩種情況下我都會得到一個地址

無論哪種。

這是因為當您在表達式中使用函數時,它會立即衰減為指針-除非它是&的操作數,否則無論如何都會獲得指向該函數的指針。

因此,當您編寫類似printf("hi") ,您將具有兩個操作數的函數調用操作符()printf和一個包含一個值"hi"的參數列表。

printf是一個函數,而不是&的操作數,因此函數調用operator ()實際獲得的是函數指針 這就是為什么ptr()在您的示例中起作用的原因:函數調用始終定義為與函數指針一起使用。

那么(*ptr)()呢? 好吧, ptr是一個函數指針,您可以對其取消引用以獲取函數...,該函數會立即衰減回指針,因此可以與()一起使用以調用它。

同樣的情況適用於printf (或任何其他函數)。 (*printf)()有效的原因幾乎相同: printf衰減到一個函數指針,該函數指針由*取消引用到一個函數,該函數立即又衰減到一個指針。

在許多情況下,函數類型的值會衰減為函數的指針類型的值,類似於數組類型的值如何衰減至指向數組第一個元素的指針的方式。

函數調用表達式是后綴表達式E(...) ,其中E是函數或函數指針類型的表達式。 這意味着各種調用語法都是有效的,並且都具有相同的含義:

void f(void);
void (*p)(void) = &f;

f();        // "f" is an expression of function type
p();        // "p" is an expression of pointer-to-function type

(*p)();     // *p is a function
(*f)();     // "f" decays to a pointer, "*f" dereferences that pointer
(****f)();  // like above, but continue decay and deref
(****p)();  // ditto
(**&f)();   // why not

順便說一句,沒有衰減的上下文之一是作為地址運算符的地址的操作數:因此,在&ff不會衰減,而是表示實際函數,其地址被占用。 或者,當您寫p = f; ,您可以使用f&f的隱式衰減。

C具有一些內置的魔術,其中包括指針和函數的等效性以及指針和數組的等效性。 因此,有時您可以“逃脫”,而不必在指針指向數組或函數時就完全取消對指針的完全取消引用。

但是,我想指出(哎呀,看看我在那兒做了什么?),C類型聲明的設計目標之一是對象的聲明和該對象的用法是相同的。

例如:

int   *p;   // p is a pointer to int

現在,我如何獲得一個int

int y =    /* wait for it ... */   *p;

同樣的,

float *****p[2];

float y =   *****p[0]; // or [1]

因此,如果您有以下聲明:

 int (*ptr)() = a_function;

然后,我們問一個問題:“如何獲得整數?” 也就是說,如何調用指向無參數返回整數的函數的指針? 答案是復制您已經聲明的內容:

 int y = (*ptr)();

是的,您可以說“ ptr是一個指針,並且函數和指向函數的指針之間具有神奇的等效性, p()可以使用”。 但是不要。 因為現在,您沒有足夠的信心做到這一點。 因此,只要相信對於任何C聲明,如果要在最左側獲得類型,您所需要做的就是在右側使用*[]() ,到達那里。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM