2011-02-22 21 views
3

可能性の重複:
Must declare function prototype in C?Cで関数を宣言する必要はありますか?

私はCを学んだし、本の中で私は、コードのこのちらほらを読んでいるがvoid scalarMultiply(int nRows, int nCols, int matrix[nRows][nCols], int scalar);の声明を持っています。私はこの行を含めなくても、プログラムは動作するようですか?

int main(void) 
    { 

     void scalarMultiply(int nRows, int nCols, int matrix[nRows][nCols], int scalar); 
     void displayMatrix(int nRows, int nCols, int matrix[nRows][nCols]); 
    int sampleMatrix[3][5] = { 
     { 7, 16, 55, 13, 12}, 
     { 12, 10, 52, 0, 7 }, 
     { -2, 1, 2, 4, 9 } 

    }; 

    scalarMultiply(3, 5, sampleMatrix, 2); 


} void scalarMultiply(int nRows, int nCols, int matrix[nRows][nCols], int scalar){ 
     int row, column; 

     for (row = 0; row < nRows; ++row) 
      for (column = 0; column < nCols; ++column) 
       matrix[row][column] *= scalar; 

    } 
+0

お役立ち情報ありがとう。 – steve

+2

[Cの関数プロトタイプを宣言する必要がありますか?](http://stackoverflow.com/questions/2575153/must-declare-function-prototype-in​​-c)[私は特にAndreyTの答えをお勧めします] –

+1

Title C、question CはタグはC++であると言います。どうして? – GManNickG

答えて

0

定義する前に関数を呼び出す場合は、プロトタイプを宣言する必要があります。そうでなければ、いいえ。これは多くのCプログラムがmainと書かれていて、一番下に小さなヘルパー関数が書かれている理由です。コンパイル単位内の関数プロトタイプが本当に本当に必要なのは、相互再帰によるものです。

+0

@David:何を再考する?どこかわかりませんでしたか? – nmichaels

+0

@David:C++についてはわかりませんが、関数が宣言される前に関数が使用されていると、C99コンパイラはそれに不満を持ちます。 – nmichaels

1

関数を使用する前に宣言しないと、コンパイラは関数のシグネチャを推測しようとする可能性があり、これが機能する可能性があります。とにかく

機能推測コンパイラが実際の関数と異なっている場合は、非常に奇妙な結果を得ることができます。たとえば、あなたがscalarMultiply、それは、intに変換取得することはできませんし、この意志に最初のパラメータとしてlong longを渡す場合定義されていない動作が発生します。スタックを破壊する可能性が最も高い(関数は、意図した方法でパラメータを読み込みます)、すべてが爆発します。


ルック:

#include <stdio.h> 
int main() { 
    f((long long int) -1); 
    g(1, 1); 
    return 0; 
} 
void f(int a, int b) { 
    printf("%d, %d\n", a, b); 
} 
void g(long long int a) { 
    printf("%lld\n", a); 
} 

出力は次のようになります。

-1, -1 
4294967297 

奇妙な、ええと?

0

従来のCコンパイラでは、プロトタイプと関数の呼び出しは必要なく、呼び出しとそれ以降の宣言が競合しない限り、後で宣言することは機能します。これはC++には当てはまりません。

警告:私はしばらくのうちにCのみのモジュールを書いていないので、gccの最新バージョンが.cファイルの場合に何をするのか分かりません。

0

定義またはプロトタイプが使用できない関数呼び出しに遭遇したときのC89の必要な動作は、intを返し、呼び出しで指定した引数の数と型を持つと仮定することです。後でそれを暗黙的にキャストできない異なる引数型、または異なる数の引数で呼び出すと、コンパイラはコードを拒否します。

最終的に誤って一致する定義が見つかると、コンパイラまたはリンカーは不平を言います。プロトタイプを使用することで、コンパイラは、定義ではなく呼び出しで、別のモジュールから定義をリンクしようとするときにエラーを生成することができます。ですから、コンパイラが作業コードを書くのを手伝ってほしいと思ったら、それをしないでください!

C99およびC++では、定義がまだ表示されていない場合はプロトタイプが必要です。

+0

C99には宣言が必要ですが、プロトタイプは必要ありません。定義が要件を満たす。 –

+0

@R:それは私が "定義がまだ見えないかどうか"という意味でした。 – Clifford

+0

私の主張は、プロトタイプが必要ないということでした。非プロトタイプの宣言は許容されます。 –

関連する問題