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の関数宣言を用いるほうである。

maruyama@wakhok.ac.jp
1995年02月08日 (水) 18時57分57秒 JST