2016-10-26 12 views
3

古いファイルの1つにコードがいくつか見えました。関数ポインタの宣言と関数の定義をまとめて

void (*const m_exec[N_EXECS])(void) = 
    { 
     #define PROCESS_DEF_TIMED(name) name, // defines macro for use in proclist.h 
     #define PROCESS_TIMED     // define switch for section in proclist.h 
     #include "proclist.h" 
     #undef PROCESS_TIMED     // undefine switch 
     #undef PROCESS_DEF_TIMED    // undefines macro 
    }; 

このコードの意味を理解できません。これは、宣言と関数の定義を一緒にした関数ポインタですか?しかし、以下のような同様の関数ポインタを宣言しようとすると、コンパイルエラーが発生する

void (*voidFptr)(void) = 
{ 
    printf("Hello\n"); 
} 

ここでも#defineとは何ですか?なぜこれが機能の中にあるのか分からない。

+2

'' proclist.h "'に含まれるリストから関数ポインタの配列を取り込みます。 –

+0

ファイルをプリプロセッサで実行し、前処理された出力を確認します。 –

+0

ヘッダーファイルを見ましたか?たぶんオリジナルの構文があなたのものと違うことに気付くかもしれません。プログラムコードでは、コメントや文字列リテラルでも、すべての文字が重要です。 – Olaf

答えて

7

この:

void (*const m_exec[N_EXECS])(void) 

はあなたが読んで、この困難を見つけることにだけではないC.内の関数ポインタの配列を宣言方法です。これは、長さがN_EXECSの配列を宣言します。配列の各要素は、引数を取らずにconst-voidへのポインタを返す関数です。

括弧で囲まれたブロックは、配列の初期化子の後に置かれます。たぶんproclist.hには関数ポインタ宣言の全リストがあり、これは基本的にそれらをこの配列に貼り付けています。 #includeの後に実際に何が起こっているのかを確認したい場合は、コンパイラの-Eフラグを使用できます。

gcc -E -Ipath/to/headers -Iother/path/to/headers main.c 

そして、それはあなたの#includeのすべてをプリプロセッサにそのファイルをプッシュし、評価の結果は、ソースコードの(おそらく巨大な)ダンプを与えるだろう。これはmain.cにあったのであれば、あなたが実行しますステートメント。

編集:あなたの最後の質問を逃した。

おそらく(これはproclist.hが表示されていないと思われます)、その定義内容がproclist.hの内容を変更します。それが含まれている場合たとえば、:

#ifdef PROCESS_TIMED 
&function1_timed, 
&function2_timed 
#else 
&function1, 
&function2 
#endif 

を次に#define PROCESS_TIMEDは、あなたのm_exec配列で終わったものを変更します。

+0

関数ポインタを宣言して関数を 'void(* voidFptr)(void)= { printf( "Hello \ n"); } ' – Rajesh

+0

関数を定義することによって、基本的には「関数ポインタを宣言しています。 void void(void){printf( "Hello \ n"); } 'ならば、' voidf'と '&voidf'は等価で有効な関数ポインタです。 –

関連する問題