8

次の宣言の意味を理解するのに苦労しています。この宣言は標準ですか?

double* (*p[3]) (void* (*)());

この宣言の意味を理解するのを誰かが助けてくれますか?

4

5 に答える 5

10

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ください!)

于 2012-06-06T13:12:56.510 に答える
10

ヘアリー宣言を読み取るためのルール:左端の識別子を見つけて外側に向かって作業します。その前()[]バインドする*と、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);


1-違いは、関数パラメーター宣言のコンテキストでの違いであり、;T a[]T a[N]同じです。T *a3つのケースすべてで、aへのポインタ Tであり、の配列ではありませんT。これは、関数パラメータ宣言でのみ当てはまることに注意してください。したがって、T *[]と同じになりT **ます。

于 2012-06-06T13:58:32.287 に答える
2

Yourpは、ポインターを返す関数への3つのポインターの配列でありdouble、ポインターを返し、引数をとらない別の関数へのポインターを引数としてvoid取ります。

ただし、この構文は使用せず、代わりにtypedefを使用してみてください。

于 2012-06-06T13:13:12.063 に答える
1

これは、関数ポインターの配列(サイズ3)であり、ポインターをdoubleに返し、別の関数ポインターを引数として取ります。

ポインタを配列に格納できる関数の double *(func)(void* (*)())
タイプ:ポインタを引数としてfuncに渡すことができる関数のタイプ:void *(func1)(void)

于 2012-06-06T13:14:06.377 に答える
0

「「時計回り/スパイラルルール」と呼ばれる手法があり、Cプログラマーは頭の中でC宣言を解析できます!」

時計回りのスパイラルルール-http://c-faq.com/decl/spiral.anderson.html

于 2012-06-09T13:58:49.390 に答える