2013-01-01 97 views
16

我的問題很簡單。C函數指針語法

正常,聲明某些變量的時候,你把它的類型之前,如:

int a; 

一個函數指針可以有這樣類型:int(*)(INT,INT)的情況下,我們點一個接受兩個int並返回一個int的函數。但是,聲明這樣的指針時,它的標識是不是類型後,如:

int(*)(int,int) mypointer; 

相反,必須在中間寫標識符:

int(*mypointer)(int,int); 

爲什麼會這樣? 對不起,我知道這是一個不容易的問題...

感謝大家的回覆。 A.S.

+3

這不是唯一的情況,您也可以在數組聲明中使用該樣式。 – effeffe

+2

搜索「聲明反映使用」。 –

回答

7

該結構反映了正常函數是如何聲明(和使用)的。

考慮一個正常的函數定義:

int foo (int bar, int baz, int quux); 

現在考慮定義一個函數指針,以相同的簽名的函數:

int (*foo) (int, int, int); 

注意兩個結構是如何互爲鏡像?這使得*foo更容易識別爲函數指針而不是別的。

11

我在答覆中解釋這Why was the C syntax for arrays, pointers, and functions designed this way?,它基本上可以歸結爲:

作者最好使語法變量爲中心,而不是類型爲中心的語言。也就是說,他們希望程序員看看聲明並認爲「如果我編寫表達式*func(arg),那將導致int;如果我編寫*arg[N],我將擁有一個浮點數」而不是「func必須是指向這個函數取這個並返回「。

C entry on Wikipedia聲稱:

裏奇的想法是在類似環境使用它們來聲明標識符:「聲明反映的使用」。

...引用K & R2的p122。

3

如果你正在處理一個函數(而不是一個指針),名字也在中間。它如下所示:return-type function-name "(" argument-list ")" ...。例如,在int foo(int),int是返回類型,foo的名稱和int的參數列表。

指向函數的指針的工作方式幾乎相同 - 返回類型,然後是名稱,然後是參數列表。在這種情況下,我們必須添加一個*以使其成爲指針,並且(因爲指針的*是前綴)一對括號,以將*綁定到名稱而不是返回類型。例如,int *foo(int)意味着一個名爲foo的函數,它接受一個int參數並返回一個指向int的指針。爲了得到* foo而不是,我們需要括號,給int (*foo)(int)

當您需要指向函數的指針數組時,這會變得特別難看。在這種情況下,大多數人都會覺得最容易使用的一個typedef爲指針類型,然後創建一個類型的數組:

typedef int (*fptr)(int); 

fptr array[10]; 
1

我曾在一些地方函數指針聲明

INT看到(* foo)(int a,int b);

並且在某些地方a和b沒有提及,兩者仍然有效。

so int(* foo)(int,int)也是正確的。

很簡單的方法,我發現要記住的是低於

假設函數聲明爲提到:INT函數(INT A,INT B);步驟1 - 簡單地把函數放在paranthases中:int(function)(int a,int b); Step2-在函數名前面加一個*並更改名稱: int(* funcPntr)(int a,int b);

PS:在這個答案中,我沒有遵循適當的命名約定等編碼準則。