C/C++

C言語 プロトタイプ宣言とは?なぜ必要か?

C/C++

はじめに

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の関数で使用する関数をあとから、定義してもコンパイルが可能になる。これは、マシン語は、コードの頭から読み込むためです。

また以下のようなメリットが推定されますね

  • コーディング順序を意識しなくてよくなる
  • 可読性があがる

コメント

タイトルとURLをコピーしました