2016-12-13 31 views
4

私はCを学ぼうとしているので、いくつかのソースコードを読んでみました。
は、しかし、私はこれが意味するかもしれないもの見当がつかない:引数を持つ関数としての配列?

static const char*(*const functab[])(void)={ 
     ram,date 
}; 

最初の部分、関数であるように思われるようstatic const char*が、大丈夫です、staticは、それが唯一であることを意味すべきである(タイプvoidの引数を持ちます)このファイルに表示されており、const char*は、値を変更することはできないが、アドレスは変更できることを意味するはずです。
しかし、それは(*const functab[])含むfunctab呼ばconstの配列がある代わりに、関数名の

static const char * date(void); 
static const char * ram(void); 

の場合と同様に、その場合には、それは、関数名以下の最後の部分の後に意味がありません。アドレス?
これは関数ramとdateを含む何らかのラッピング関数ですか?配列を宣言するいくつかの代替方法?

+0

これは役立つかもしれませんします。http:// cdecl.org/。 – paulotorrens

+0

@paulotorrensいいえ、そのサイトはかなりばかです。 OPの例で完全に細かいコードを試してみると、「構文エラー」が発生します。私は彼らがcdecl.orgのソースコードで構文エラーを参照していると仮定します... – Lundin

+0

cdecl.orgは静的キーワードを認識しません。なんて可哀想な。 – Lundin

答えて

2

短い答え:議論の下

は、関数ポインタの配列の良い例があります。これは、 "FUNCtion TABle"からの可能性の高いfunctabの名前についても説明します。

長い答え:Cでは、関数へのポインタを取得して変数に保存できます。このように使用される変数は、関数ポインタとして知られています。

例えば、以下funcptr変数がdo_stuffのエントリ・ポイントのアドレスが含まれます:あなたはすでにここftype_tあるfuncptrのタイプを、定義している場合にのみ動作します

int do_stuff(const char* x) { ...do stuff.. } 
... 
ftype_t funcptr = &do_stuff; 
... 
(*funcptr)("now"); // calls do_stuff() 

が。型定義は、この形式をとる必要があります。

typedef int (*ftype_t)(const char*); 

は英語で、これはftype_tは、唯一の引数としてconst char*を取り、intを返す関数の型として定義されていることを意味します。

あなたがこれだけのためにtypedefにしたくなかった場合は、以下の実行して同じことを達成している可能性:

int (*funcptr)(const char*) = &do_stuff; 

これは動作しますが、その構文は混乱しています。また、関数ポインタの配列を構築するようなことをしようとすると、かなり醜いことになります。これはまさにあなたのコードがするものです。以下に示すのは、

を理解する方がはるかに簡単である同等のコードは、次のとおりです。

typedef static const char*(*myfn_t)(void); 

const myfn_t functab[] = { &ram, &date }; 

(の&(アドレス)は、通常はオプションですが、お勧めします。)

4

functabは、const char*を返し、引数を受け付けない関数ポインタ(正確にはconstの関数ポインタの配列)の配列です。

その後、

... = { ram, date }; 

は、アレイの初期化子として機能括弧で囲まれた初期化子リストです。

+0

明確にするために、これはすべきではありません: 'functab'は*定数*関数ポインタの配列です...? – babon

3

これは、Cで関数ポインタの配列を定義する方法です。したがって、この配列を使用して関数ram()を呼び出す代わりに、(* functab[1])で呼び出すことができます。ここでfunctab関数ポインタの配列で、配列が機能ramdateへのポインタで初期化されます。 How can I use an array of function pointers?

関連する問題