12

declaration違いは、パラメーターの型がないことだと思いました...

なぜこれが機能するのですか:

int fuc();

int fuc(int i) {
  printf("%d", i);
  return 0;
}

しかし、これはコンパイルに失敗します:

int fuc();

int fuc(float f) {
  printf("%f", f);
  return 0;
}

メッセージ付き:

エラー: 'fuc' のタイプが競合しています。注: デフォルトの昇格を持つ引数の型は、空のパラメーター名リストの宣言と一致することはできません

4

3 に答える 3

26

宣言:

int f();

f...一部の識別子(この場合は )が関数に名前を付けることをコンパイラに伝え、関数の戻り値の型を伝えますが、関数が意図するパラメータの数または型を指定しませ受け取る。

プロトタイプ:

int f(int, char);

...それ以外は似ていますが、関数が受け取る予定のパラメーターの数/タイプも指定します。パラメータを取らない場合は、そのようなものを使用int f(void)して指定します (括弧を空のままにすることは宣言であるため)。新しいスタイルの関数定義:

int f(int a, char b) { 
    // do stuff here...
}

...プロトタイプとしても機能します。

スコープ内にプロトタイプがない場合、コンパイラは関数を呼び出す前にデフォルトの昇格を引数に適用します。これは、 anycharまたはshortit が に昇格しint、 anyfloatが に昇格したことを意味しdoubleます。したがって、(プロトタイプではなく) 関数を宣言する場合は、やパラメータを指定したくありません。そのようなものを呼び出すと、未定義の動作が発生します。デフォルトのフラグを使用すると、基本的にコードを正しく使用する方法がないため、コンパイラはコードを拒否する可能性があります。コードを受け入れるようにするコンパイラフラグのセットを見つけることができるかもしれませんが、とにかくそれを使用できないため、それはかなり無意味です...charshortfloat

于 2011-03-30T03:54:37.193 に答える
0

プロトタイプ= 前方宣言であるため、コンパイラに何をするかを伝える前に使用できます。ただし、パラメータはまだあります。

色んな意味で便利!

于 2011-03-30T03:38:12.277 に答える
0

この宣言 は、を受け取り、を返すint fuc(float);関数が存在することをコンパイラに伝えます。fucfloatint

定義 int fuc(float f) { /*...*/ }はコンパイラに実際の内容を伝え、宣言fucも提供します。

宣言と定義の違いは、サイズ 6 の青い帽子が存在すると言うことと、サイズ 6 の青い帽子を誰かに手渡すことの違いです。問題があります。

于 2011-03-30T03:53:41.833 に答える