2012-02-04 22 views
6

スタンフォード大学のProgramming Abstractionsコースを聞いているうちに、次のようなコードが出てきます。パラメータとしての機能とパラメータとしての機能ポインタ

void plot(double start, double end, double (fn)(double)) { 
    double i; 
    for (i = start; i <= end; i += 1) 
     printf("fn(%f) = %f\n", i, fn(i)); 
} 

double plus1(double x) { 
    return x + 1; 
} 

int main(void) { 
    plot(1, 10, plus1); 
    return 0; 
} 

GCC、G ++を使用して自分のシステムでコードをコンパイルしました。彼らは両方とも完璧に走ります。

は、私が唯一の機能func2iのアドレスを与えるvoid func2(int *a)&iを通過させながら機能などvoid func1(int a)int i = 2を渡すと、その関数のことiの新しいコピーを作成することを知っています。

fnplotに渡すメカニズムは何ですか?また、パラメータとして関数ポインタを渡す方法とはどのように違いますか?

答えて

7

void foo(double fn(double))void foo(double (*fn)(double))の間には全く違いがありません。両方とも、関数へのポインタをパラメータとして取る関数を宣言します。

これは、void bar(double arr[10])void bar(double* arr)の間に違いがない方法と似ています。

+0

使用すると、配列に関する2番目の請求のための参照を持っていますか?特にC++の場合は? – krlmlr

+0

前者では 'fn'は暗黙のうちに関数へのポインタであり、後者の' fn'では明示的に関数へのポインタが宣言されています –

+3

@ user946850: '§8.3.5/ 5':...後各パラメータの型を決定すると、「Tの配列」または「Tを返す関数」のいずれかのパラメータが「Tへのポインタ」または「Tを返す関数へのポインタ」にそれぞれ調整される。 ... – Mankarse

0

私の間違い申し訳ありません。

void foo(int (fn)(int)){} 
void bar(int (*fn)(int)){} 

このようなコードの上にコンパイルします。

のgcc -S SAMPLE.C

あなたは何の違いがないことがわかります。 異なるコーディングスタイル。

あなたにもこのコードをコンパイルして実行してみてください可能性があります

#include <stdio.h> 
void foo(int (fn)(int)) 
{ 
    printf("foo: %x.\n",fn); 
} 
void bar(int (*fn)(int)) 
{ 
    printf("bar: %x.\n",fn); 
} 
int main(int argc) 
{ 
    foo(main); 
    bar(main); 
    return 0; 
} 
+0

もう一度私の質問をお読みください。私は、パラメータリスト内の関数ポインタと、パラメータリスト内の関数プロトタイプとの違いを尋ねました。 – MrOrdinaire

+0

私のせいです。私は新しい答えを書きました。 – for1096

関連する問題