main関数の中にいくつもの処理を連続して書くと、プログラムが長くなり、 見にくく修正作業も難しくなる傾向にあります。 また数字だけ異なり全く同じ処理を繰り返す場合に、 プログラミングではよくあります。 ここで学習する関数は、 基本的な処理のひとまとまりを指し、先述のような状況に対して利用されること がよくあります。また、この関数を使いこなすことで、 複雑で多様な処理が実現できることになります。
まずはとにかく関数がどういうものか見てみましょう。下記の例1では、 5つの数字の最大値を探す関数、max_returnが定義され、 実際に利用されています。 関数2の演習のページの課題1のプログラムの 一部を改変したものです。
例1:関数の見本(関数を使用前に定義)
#include <stdio.h> /* 関数の定義 */ int max_return(int a, int b, int c, int d, int e) { int max; max = a; if(max < b) max = b; if(max < c) max = c; if(max < d) max = d; if(max < e) max = e; return max; } int main(void) { int d0, d1, d2, d3, d4; int max; d0 = 2; d1 = 3; d2 = -1; d3 = 8; d4 = 5; /* 関数の呼び出し */ max = max_return(d0, d1, d2, d3, d4); printf("最大値 = %d\n", max); d0 = 3; d1 = -2; d2 = 5; d3 = -6; d4 = 0; /* 関数の呼び出し */ max = max_return(d0, d1, d2, d3, d4); printf("最大値 = %d\n", max); return (0); }
上記のプログラムでは、int型の5つの変数d0, d1, d2, d3, d4の中の最大値を 求める作業を2回行っています。 関数max_returnが呼び出され、関数で処理がされ、その結果で ある最大値がmaxに代入される、という流れになっています。
上記の例1と同じ内容を実現するのに、関数を使わずに、 処理のすべてをmain関数に記述すると下記の 例1-2のようになります。比較する数字が違うだけで 最大値を求めるという同じ処理をしています。 同じ記述を書かなくてはならず、非効率的である ことがよくわかると思い ます。
例1-2:例1の処理を関数を使用しないで実現する場合
#include <stdio.h> int main(void) { int d0, d1, d2, d3, d4; int max; d0 = 2; d1 = 3; d2 = -1; d3 = 8; d4 = 5; /* 関数を使わない処理 */ max = d0; if(max < d1) max = d1; if(max < d2) max = d2; if(max < d3) max = d3; if(max < d4) max = d4; printf("最大値 = %d\n", max); d0 = 3; d1 = -2; d2 = 5; d3 = -6; d4 = 0; /* 関数を使わない処理 */ max = d0; if(max < d1) max = d1; if(max < d2) max = d2; if(max < d3) max = d3; if(max < d4) max = d4; printf("最大値 = %d\n", max); return (0); }
上記の例で関数の使い方が紹介されましたが、関数を使うには一定の規則に従っ て定義する必要があります。下記では、「定義する位置」と「関数の型」の 2項目について説明しています。
関数を定義するにあたり、記述する場所を選べます。 関数を使用する場所の前に定義する方法と、 使用する場所の後に定義する方法と2通りあります。 前者に相当するのが例1で、後者に相当するのが下記に示す例2です。 後者の場合、プロトタイプ宣言が必要になります。
プロトタイプ宣言は、関数の定義の1行目と全く同じ記述で問題ありませんが、 セミコロンをつけるのを忘れないようにしましょう。
例2:関数の見本(関数を使用後に定義)
#include <stdio.h> /* プロトタイプ宣言 */ int max_return(int a, int b, int c, int d, int e); int main(void) { int d0, d1, d2, d3, d4; int max; d0 = 2; d1 = 3; d2 = -1; d3 = 8; d4 = 5; /* 関数の呼び出し */ max = max_return(d0, d1, d2, d3, d4); printf("最大値 = %d\n", max); d0 = 3; d1 = -2; d2 = 5; d3 = -6; d4 = 0; /* 関数の呼び出し */ max = max_return(d0, d1, d2, d3, d4); printf("最大値 = %d\n", max); return (0); } /* 関数の定義 */ int max_return(int a, int b, int c, int d, int e) { int max; max = a; if(max < b) max = b; if(max < c) max = c; if(max < d) max = d; if(max < e) max = e; return max; }
「関数の型」とありますが、変数に「int」や「double」などの型があるように、 関数にも「int」や「double」などの型があります。例えば、上記の 例1の「max_return」という関数も、
のように「int」型の関数であると明記されています。
関数を定義する際に、関数の型も定義しなくてはなりませんが、 関数の中に記述されたreturnで返される値の型に一致させ ます。上記の例1では、
と、「max」という変数の値が返されていることがわかります。では、この変数 「max」の型は何かと調べてみると、関数の定義の初めの部分で、
のように、int型であると宣言されています。したがって、関数「max_return」 の型もint型になる、というわけです。
一方、returnで返さない場合には、void型を指定します。 下記にはvoid型の関数の見本を示してあります。 関数1の演習のページの課題3のプログラムです。
/* BMI (Body Mass Index) の計算方法:関数の利用 */ #include <stdio.h> void bmi_cal(double h, double w) { /* BMI = 体重(kg) / 身長(m) / 身長(m) */ printf("身長%5.2f m、体重%6.2f kgの人のBMI = %6.2f\n", h, w, w/h/h); } void std_weight(double h) { /* 標準体重(kg) = 身長(m) * 身長(m) * 22 */ printf("身長%5.2f mの人の標準体重 = %6.2f kg\n", h, h*h*22); } int main(void) { double height, weight; printf("身長(m)と体重(kg)を入力してください "); scanf("%lf%lf", &height, &weight); /* BMIの計算 */ bmi_cal(height, weight); /* 標準体重の計算 */ std_weight(***********); return (0); }