C言語でmain
関数から別の関数を呼ぶ場合を考えよう。
以下は、二つの整数(int)の平均値を求めるつもりのプログラムである。
#include <stdio.h>
int main()
{
int a = 5;
int b = 4;
printf("%d と %d の平均は %f です\n", a, b, average_int(a, b));
}
float average_int(int x, int y)
{
float m;
m = (x+y)/2.0;
return m;
}
このプログラム ave1.c
を保存しコンパイルしてみよう。
gcc -o ave1 ave1.c
ave1.c:11: warning: type mismatch with previous implicit declaration
ave1.c:7: warning: previous implicit declaration of `average_int'
ave1.c:11: warning: `average_int' was previously implicitly declared to return `int'
なにやら怪しいメッセージが出るはずだが、これらは全て warning(警告)なので、コンパイルが完了し実行ファイルはできている。 ところが実行すると結果がおかしい。
./ave1
5 と 4 の平均は 0.000000 です
警告メッセージをちゃんと読むとこの間違いの原因が分かる。
ave1.c:11: warning: `average_int' was previously implicitly declared to return `int'
average_intはそれ以前に int 型を返すものとして暗黙に宣言されて いる
これは、main
関数の中で何の前ぶれもなく
average_int
を使うと、
特にことわりがなければ結果はint
だな
という前提の元でコンパイルが進む。ところが実際は、
average_int
関数が返すのは float
型なので
main
関数で思っているのとは食い違いが生じて正しい結果が得られない。
これを直すには、
main
関数の中で average_int
を呼ぶ前に、
average_int
はfloat
型であると宣言する
average_int
関数を main
関数より先に定義
する
のいずれかの方法を取ると良い。
1番は、以下のようにする。
#include <stdio.h>
int main()
{
float average_int(int, int);
int a = 5;
int b = 4;
printf("%d と %d の平均は %f です\n", a, b, average_int(a, b));
}
float average_int(int x, int y)
{
float m;
m = (x+y)/2.0;
return m;
}
追加した部分
float average_int(int, int);
は、「average_int
は、二つの引数として
int
と int
を取り、結果として
float
を返す」という宣言である。
このように、あとで利用する関数について、その引数の個数と型、 返す結果の型を宣言するものを、関数のプロトタイプ宣言という。 引数の部分には型だけ書いて、実際の変数名は書かなくて良いことに注意する。
C言語プログラミングでは、一つのファイルには全ての関数定義を書かない ことの方が多いので、プロトタイプ宣言は重要である。
もしプログラムを一つのソースファイルで書く場合は、 2番の方法で書いても良い。その場合は以下のようになる。
#include <stdio.h>
float avarage_int(int x, int y)
{
float m;
m = (x+y)/2.0;
return m;
}
int main()
{
int a = 5;
int b = 4;
printf("%d と %d の平均は %f です\n", a, b, avarage_int(a, b));
}