2016-03-02 42 views
1

發生在這裏我有被傳遞給另一個函數的函數,但我不知道爲什麼這兩個工作,不產生任何警告。這有什麼函數指針

typedef short (*COMP)(char *, char *); 

DATA *bst_get(BST *, char *, COMP); 

short cmp(char *a, char *b) 
{ 
    if (strstr(a, b)) 
     return 0; 
    return strcmp(a, b); 
} 

// Both of these produce the same results 
//  the difference is '&cmp' vs 'cmp' 
data = bst_get(bst, "textA", &cmp); 
data = bst_get(bst, "textA", cmp); 

那麼哪個是正確的用法呢?有關係嗎?

+0

通常你應該使用'&cmp',但'cmp'也被接受。函數標識符衰減爲指向該函數的指針。 –

+1

@ Jean-BaptisteYunès:「通常你應該使用'&cmp'」 - 爲什麼?使用這個名字是非常好的接受。 – Olaf

+0

這就是我所說的。如果你想要的東西的地址,你必須使用'&東西'的東西,但對於一些特殊的東西(數組,函數)對象的名稱本身代表一個地址... –

回答

1

cmp是用「功能型」的表達式。與這些類型的表達式(幾乎)總是隱式轉換爲表達式與相應的功能指針類型,類似(*參見在末端紙幣)到如何與陣列型表達式隱式轉換爲指針指向第一個數組元素。這種隱式轉換通常稱爲衰減,儘管這不是C語言標準(但是由C++)使用的術語。

,另一方面&cmp使轉換明確:在這裏,你正在做一個函數的地址,從而接收一個函數指針。

所以,底線:它們是等價的,並且至少在C中,使用一個在另一個之間沒有實際的區別。

在標準的相關部分:

功能指示符是具有功能類型的表達式。除了當它是sizeof操作者的操作數時,_Alignof操作者,或一元&操作,功能指示器,類型爲「函數返回類型」被轉換爲具有鍵入一個表達式「函數指針返回類型」 。

[N1570§6.3.2.1/ 4]

注:這意味着,是 「明確的」 所有的時間將意味着寫函數調用是這樣的:

#include <stdio.h> 

void foo(void) { 
    printf("Awesome\n"); 
} 

int main() { 
    (&foo)(); 
    return 0; 
} 

*)重要:提到的相似之處在於存在隱式轉換。雖然func&func產生確切相同的結果(值和類型),array&array產量不同結果(不同的指針類型)。原因是array被隱式轉換爲&(array[0])。所以,重複一次,相似之處在於存在隱式轉換。實際的轉換是不同的。

+1

只使用一個函數的名稱是與使用'&'運算符一樣明確。一個函數調用需要一個_explicit_括號後綴運算符。 – Olaf

+0

@Olaf我真的不明白你想告訴我什麼。我的意思是'cmp'是一個帶有函數類型的表達式,它(幾乎總是)被(隱式地)轉換爲一個帶有指向函數類型的表達式,就像在使用運算符'&'時顯式做的那樣。 –

+0

「(幾乎總是)」 - 什麼時候不?它不像數組。它是**只有**作爲一個函數被調用,如果一個**明確的**'('後面的 – Olaf

1

在C中,功能被轉換在表達式中使用時的指針的函數。
cmp&cmp都在這裏表示的函數的地址,因此二者是等價爲一個函數參數bst_get

相關問題