2012-06-24 49 views
5

考慮到這點代碼3型動物函數調用的語義:函數調用與不同的語義

void f(void){ 
    puts("OK"); 
} 

int main(void){ 
    f(); 
    (*f)(); 
    (&f)(); 

    return 0; 
} 

首先是調用F的標準方式,

第二是語義解引用函數指針,

但在第三我運用&運算符的函數名稱,它似乎工作正常。

第二和第三種情況會發生什麼?

謝謝。

+1

的函數指針被解除引用在第三個呼叫。 –

+5

爲了好玩嘗試'(********** f)();' – Flexo

+0

我在問什麼情況下有人應該使用第二個和第三個電話...... –

回答

8

函數調用是總是通過函數指針執行。從C99第6.5.2.2節開始:

表示被調用函數的表達式應該有指向函數的類型指針。

但是,在幾乎所有情況下,函數類型都衰減爲函數指針類型。從C99節6.3.2.1:

除了當它是sizeof操作者的操作數 或一元&操作者,功能指示器與 型「函數返回類型」被轉換到具有表達類型「指向 函數返回類型」。

所以,你的三個電話因此被評價:

(&f)(); 
(&(*(&f)))(); 
(&f)(); 

全部都是有效的。但顯然,第一個(f())是最乾淨和最容易閱讀的。

+0

why(&( &f)())有效。當&f衰減到函數指針類型? – Raulp

+0

@softy:'&f'已經**了**函數指針類型。所以'&& f'是一個函數指針指針類型。 –

+6

@OliCharlesworth - 只有'&f'是一個r值,所以它不能是另一個'&'一元運算符的參數。 – rodrigo

1

在第二種情況下,您正在使用函數指針。函數指針用於記憶對函數的引用,並且可以在您的調用的其他地方調用它。它們通常用於實現回調。 所以,如果你有一個指向函數的指針,你應該使用第一個符號。

我想第一個和第三個是等價的。 在如果聲明一個函數指針其實你可以初始化以下兩個方面:

void AFunction(); 
void (*funcPtr)() = NULL; 

funcPtr = AFunction; 
funcPtr = &AFunction; 
相關問題