はじめに
C言語を学んでいて、プロトタイプ宣言とはなぜ必要か?と思った方はいらっしゃいませんか?
そこで、プロトタイプ宣言のとは何かを実例を用いて説明します。
コード
平均値を求めるプログラムを例に説明します。
以下のコードがプロトタイプ宣言といいます。
double avg(double, double);
#include <stdio.h>
// 関数avgのプロトタイプ宣言
double avg(double, double);
int main(int argc, char** argv) {
double d1, d2, d3;
double a = 1.2, b = 3.4, c = 2.7;
// 同じ計算を3回
d1 = avg(a, b);
d2 = avg(4.1, 5.7);
d3 = avg(c, 2.8);
printf("d1 = %f,d2 = %f,d3 = %f\n", d1, d2, d3);
return 0;
}
// 平均値を求める関数
double avg(double m, double n) {
// 引数m,n rに平均値
double r = (m + n) / 2.0;
return r;
}
出力結果
d1 = 2.300000,d2 = 4.900000,d3 = 2.750000
プロトタイプ宣言とは?
プロトタイプ宣言とは、後に呼び出す関数を最初に宣言しておくことを指します。
プロトタイプ宣言は以下の書式で行います。
- 戻り値の型 関数の名前(引数の型、引数の型、….)
プロトタイプ宣言の必要性とは?
では、実際に上のコードからプロトタイプ宣言を消去して、コンパイルしてみます。
#include <stdio.h>
// 関数avgのプロトタイプ宣言
int main(int argc, char** argv) {
double d1, d2, d3;
double a = 1.2, b = 3.4, c = 2.7;
// 同じ計算を3回
d1 = avg(a, b);
d2 = avg(4.1, 5.7);
d3 = avg(c, 2.8);
printf("d1 = %f,d2 = %f,d3 = %f\n", d1, d2, d3);
return 0;
}
// 平均値を求める関数
double avg(double m, double n) {
// 引数m,n rに平均値
double r = (m + n) / 2.0;
return r;
}
コンパイル結果
以下のような警告が出ました。
main.c:8:7:警告:関数 'avg'の暗黙の宣言はC99では無効です[-Wimplicit-function-declaration]
main.c:8:7: warning: implicit declaration of function ‘avg’ is invalid in C99 [-Wimplicit-function-declaration]
d1 = avg(a, b);
^
main.c:16:8: error: conflicting types for ‘avg’
double avg(double m, double n) {
^
main.c:8:7: note: previous implicit declaration is here
d1 = avg(a, b);
コンパイルできなかったです。
解説
つまり、プロトタイプ宣言をしない。avgという関数がないよ・・・となってしまいコンパイルができないです。
これは、avgという関数は、mainの関数よりもあとに出てきているからですね。
ということは、avgという関数をmainより前にもってくれば、コンパイルできるはず。
試してみましょう。
コード2
#include <stdio.h>
// 関数avgのプロトタイプ宣言
// 平均値を求める関数
double avg(double m, double n) {
// 引数m,n rに平均値
double r = (m + n) / 2.0;
return r;
}
int main(int argc, char** argv) {
double d1, d2, d3;
double a = 1.2, b = 3.4, c = 2.7;
// 同じ計算を3回
d1 = avg(a, b);
d2 = avg(4.1, 5.7);
d3 = avg(c, 2.8);
printf("d1 = %f,d2 = %f,d3 = %f\n", d1, d2, d3);
return 0;
}
出力結果
d1 = 2.300000,d2 = 4.900000,d3 = 2.750000
正しく出力されました。
まとめ
プロトタイプ宣言をすると、mainの関数で使用する関数をあとから、定義してもコンパイルが可能になる。これは、マシン語は、コードの頭から読み込むためです。
また以下のようなメリットが推定されますね
- コーディング順序を意識しなくてよくなる
- 可読性があがる



コメント