次の宣言の意味を理解するのに苦労しています。この宣言は標準ですか?
double* (*p[3]) (void* (*)());
この宣言の意味を理解するのを誰かが助けてくれますか?
http://cdecl.orgを使用してください:
pを関数へのポインタの配列3として宣言します(関数へのポインタはvoidにポインタを返します)doubleへのポインタを返します
詳細については、MSDNの記事「より複雑な宣言子の解釈」を参照してください。
しかし、typedefは役に立ちます:
typedef void *(*foo)(); // foo is a function-pointer type
typedef double *(*bar)(foo); // bar is also a function-pointer type
bar p[3];
foo
(明らかに、との代わりに適切な名前を使用してbar
ください!)
ヘアリー宣言を読み取るためのルール:左端の識別子を見つけて外側に向かって作業します。その前()
に[]
バインドする*
と、T *a[N]
へのポインタの配列、の配列へのポインタ、へのT
ポインタを返す関数、へのポインタです。関数はTを返します。関数プロトタイプはパラメーター名を省略している可能性があるため、またはのようなものが表示される場合があります。意味はほとんど同じ1で、長さが0の識別子があるふりをします。 T (*a)[N]
T
T *f()
T
T (*f)()
T *[N]
T (*)()
したがって、
p -- p
p[3] -- is a 3-element array
*p[3] -- of pointers
(*p[3]) ( ) -- to functions
(*p[3]) ( (*)()) -- taking a pointer to a function
(*p[3]) ( * (*)()) -- returning a pointer
(*p[3]) (void* (*)()) -- to void
* (*p[3]) (void* (*)()) -- returning a pointer
double* (*p[3]) (void* (*)()); -- to double
ここで重要なことは、を返す関数ではなく、の配列p
として宣言していることです。...
...
そのような獣は実際にはどのように見えるでしょうか?まず、ポイントする3つの関数が必要です。これらの各関数は、voidへのポインターを返す関数へのポインターである単一のパラメーターを取ります。
double *foo(void *(*)());
double *bar(void *(*)());
double *bletch(void *(*)());
double *(*p[3]) (void *(*)()) = {foo, bar, bletch};
、、およびのそれぞれはfoo
、渡された関数を呼び出し、どういうわけかへのポインタを返します。bar
bletch
double
foo
また、、、、bar
およびbletch
:のそれぞれのパラメータータイプを満たす1つ以上の関数を定義することもできます。
void *blurga() {...}
直接電話した場合foo
は、次のように電話します
double *pv;
...
pv = foo(blurga);
だから私たちは次のような呼び出しを想像することができます
double *pv = (*p[0])(blurga);
T a[]
とT a[N]
同じです。T *a
3つのケースすべてで、a
はへのポインタ T
であり、の配列ではありませんT
。これは、関数パラメータ宣言でのみ当てはまることに注意してください。したがって、T *[]
と同じになりT **
ます。
Yourp
は、ポインターを返す関数への3つのポインターの配列でありdouble
、ポインターを返し、引数をとらない別の関数へのポインターを引数としてvoid
取ります。
ただし、この構文は使用せず、代わりにtypedefを使用してみてください。
これは、関数ポインターの配列(サイズ3)であり、ポインターをdoubleに返し、別の関数ポインターを引数として取ります。
ポインタを配列に格納できる関数の double *(func)(void* (*)())
タイプ:ポインタを引数としてfuncに渡すことができる関数のタイプ:void *(func1)(void)
「「時計回り/スパイラルルール」と呼ばれる手法があり、Cプログラマーは頭の中でC宣言を解析できます!」
時計回りのスパイラルルール-http://c-faq.com/decl/spiral.anderson.html