次の宣言の意味を理解するのに苦労しています。この宣言は標準ですか?
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]TT *f()TT (*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、渡された関数を呼び出し、どういうわけかへのポインタを返します。barbletchdouble
fooまた、、、、barおよびbletch:のそれぞれのパラメータータイプを満たす1つ以上の関数を定義することもできます。
void *blurga() {...}
直接電話した場合fooは、次のように電話します
double *pv;
...
pv = foo(blurga);
だから私たちは次のような呼び出しを想像することができます
double *pv = (*p[0])(blurga);
T a[]とT a[N]同じです。T *a3つのケースすべてで、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