2013-01-01 5 views
16

私の質問はとても単純です。いくつかの変数を宣言するときC関数ポインタの構文

は、通常、あなたは次のように、その前にその型を置く:

int a; 

のようなタイプがあり、関数ポインタ:私たちはを指す場合のint(*)(int型、int)を、 2つの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主張:

リッチーのアイデアは、その使用に似た状況に識別子を宣言することであった「宣言は、使用を反映しています」。

... p122のK & R2を挙げると、

3

関数(ポインタを指すポインタではない)を扱っている場合、その名前も真ん中にあります。それは次のようになります:return-type function-name "(" argument-list ")" ...。たとえば、int foo(int)の場合は、戻り値のタイプがint、引数のリストが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は言及されず、どちらも動作します。

だから、int(* foo)(int、int)も正しいです。

の下に言及したものと想定機能は次のように宣言されているように私が覚えがわかっ

非常に簡単な方法は次のとおりです。(、int型B int型)int型の機能; Step1 - 関数を単にparanthasesに入れます。int(function)(int a、int b); ステップ2 - 関数名の前に*を置き、名前を変更します。 int(* funcPntr)(int a、int b);

PS:この回答では命名規則などのコーディングのガイドラインに従っていません。