0

重複の可能性:
なぜこれらすべてのクレイジーな関数ポインター定義がすべて機能するのですか? 本当に何が起こっているのですか?

コードで理由を説明していただければ幸いです

void f(int& i)
{
  i++;
}

void g(void (passed_f)(int&),int& a)   //`passed_f` equivalent to `*passed_f`
{
  passed_f(a);
}

int main()
{
  int n=0;
  g(f,n);                              //`f` is equivalent to `&f`
}

エラーを生成せず、まったく同じ結果1. 関数へのポインターを受け入れるか、関数自体を受け入れるかは問題ではないようgです... また、[c]-tag が適切であると思います。

4

2 に答える 2

2

関数ポインターは C では特別です。

  • 関数の名前、たとえばf関数指定子&fは関数ポインタです。
  • 関数ポインターを間接的に指定すると、関数指定子に評価されます。
  • 関数指定子を間接的に指定すると、関数指定子自体に評価されます。
  • fしたがって、関数ポインタをf()(*f)()(**f)()などとして呼び出すことができます。

関数名をほとんどすべての目的でのポインターと考えると、これはある程度理にかなっています。このバージョンの Hello World をコンパイルしてみてください。

int main()
{
    // try replacing * with & or adding more *s
    (*printf)("Hello, world!\n");
    return 0;
}

C 標準では、これは段落 6.3.2.1 でカバーされています。C++ 標準については不明です。

于 2012-04-19T19:43:49.557 に答える
2

passed_fは実際に と同等*passed_fであり、コンパイラは両方から同じ出力を作成します。違いは単なる慣用​​句です。関数へのポインターがあることをより明確に表現し、この表記法は他の型に使用されるポインター表記法とより一貫しているため、後者の形式を好む人もいます。

于 2012-04-19T19:35:38.663 に答える