Previous: 関数の定義
Up: 関数を作る II
Next: 返り値または引数を持たない関数
Previous Page: 関数の定義
Next Page: 返り値または引数を持たない関数
最初に述べたように、関数を作ったときに、積極的にコンパイラにその関数の 型や引数を教えてやれば、コンパイラはもし間違った関数の呼び出しをしたときに ちゃんとその旨を知らせてくれる。 このようにコンパイラに関数の仕様を知らせるために、関数の仕様を教えることを 関数の宣言という。関数の宣言は、ファイルの先頭、#include 文の後に 書いておくと良い。
関数の宣言は以下の書式で行う。
[関数の型] 関数名( 引数の型 [,...]);
例 test1(); char itoc(int); float rmap1(int); float test(int, char);
勿論、関数の型(返り値の型)を省略すると整数型と解釈される。 特に、宣言は文なので、最後にセミコロン ; をつけることを忘れないように しなければならない。(この点で、関数の定義とは違う点に注意しよう。)
また、引数の型のみを記述しても良いが、引数を次のように書いても良い。分かり やすさから言えば、引数の変数も書いておく方が良いだろう。但し、その引数の変数名 は、完全なダミーで、まったく意味を持たない。
例 test1(); char itoc(int num); float rmap1(int a); float test(int i, char c);
さてここで、関数の宣言がない場合の事を考えてみよう。関数の宣言がなく、 関数が使用される以前に関数が定義されている場合は、何の問題もない。 つまり、関数の定義でもって、関数の宣言となる。実は、前の章で、我々が関数の 宣言なしで関数を定義しても大丈夫だったのは、このためである。では、逆に、 関数が宣言、定義される前に、関数が使用されたらどうなるのであろうか。 コンパイラは、その関数がどこか別のところ(例えば、標準ライブラリ)にある と考えてしまう。すると、後から関数の宣言や定義を行っても、それは、既に あると考えられているので、2重に宣言・定義されていると見なされ、エラーに なる。
コンパイルエラーになる例 #include <stdio.h> main() { test1(2,3); }test1(int i, int j){ printf("%d %d", i, j); }
具体的なエラーメッセージは、今の場合、7行目の関数の定義がおかしいと思われて、
"test.c", line 7: identifier redeclared: test1というエラーが出る。このエラーの意味は、test1 が2重に宣言されているという意味 である。
このエラーを回避するには、次のように関数を宣言しておくか、
コンパイルエラーにならない例1 #include <stdio.h>test1(int i, int j); /* 関数宣言 */
main() { test1(2,3); }
test1(int i, int j){ printf("%d %d", i, j); }
次の例のように、関数が使用される前に、定義すれば良い。
コンパイルエラーにならない例2 #include <stdio.h>test1(int i, int j){ printf("%d %d", i, j); }
main() { test1(2,3); }
勿論、望ましいのは、例1の関数宣言を用いるほうである。