WisdomSoft - for your serial experiences.

4.2 パラメータと戻り値

関数は呼び出し元から処理に利用するための値を受け取ったり、処理結果となる値を呼び出し元に戻したりできます。

4.2.1 関数に値を渡す

これまで、一部の標準関数を使用してきました。その全ては、必ず括弧 ( ) の中に何らかの値を指定していたはずです。例えば、printf() 関数では、文字列を画面に表示させるのに文字列定数を ( ) の中に指定していました。

このように、関数に何らかの情報を渡すことができます。こうすることで、動的にデータを処理できる実用的な関数を実装することが可能になるでしょう。

関数に渡される情報のことを引数と呼びます。引数の型は任意で指定することができます。引数を呼び出し元から受け取るには、渡された値を保存する変数が必要です。引数リストで引数を受け取るための変数をパラメータと呼びます。簡単にいうと、関数を呼び出す側が、関数に渡す値のことを引数と呼び、関数本体が、何らかのデータを受け取るためにあらかじめ確保する変数をパラメータと呼ぶのです。

引数を受け取るには、関数定義の括弧 ( ) の中に、受け取る値の型と識別子を指定します。複数のパラメータを指定したい場合はカンマ , で区切ります。例えば、次の関数は int 型の値と float 型の値を受け取る関数です。

void Function( int iValue , float fValue) { ...

当然、この関数を呼び出すときは、パラメータで指定されている情報を渡す必要があります。この関数を呼び出すには、例えば Function(10 , 0.5F) というように、パラメータ型と互換性のある式を引数として指定しなければなりません。

コード1
#include <stdio.h>

void Function(int iValue , float fValue) {
	printf("iValue = %d : fValue = %g\n" , iValue , fValue);
}

int main() {
	Function(10 , 3.14F);
	Function(100 , 1000);
	return 0;
}
実行結果
コード1 実行結果

コード1で注目してほしいのは Function(100 , 1000) という行です。ここでは、float 型のパラメータに対して 1000 という int 型の引数を渡しています。通常、型に互換性のない引数を渡した場合、関数は値を受け取ることができないためエラーとなりますが、代入変換と同様に引数への値渡しでも黙的な型変換が機能します。

iValue や fValue のようなパラメータ変数は、パラメータを宣言している関数内でのみ使用することができます。main() 関数から iValue や fValue を使うことはできません。

4.2.2 関数の結果を返す

関数は、呼び出し元に関数の結果などを通知するために値を返すことができます。これを戻り値と呼びます。関数が与えられた数値を基に何らかの計算を行うのであれば、戻り値としてその結果を返すことができますし、関数が何らかの機能を提供するのであれば、成功又は失敗などの情報を戻りちとして返すことができます。

関数の呼び出し元は、戻り値を取得して何らかの変数などに保存することもできますし、戻り値を無視することもできます。戻り値を無視した場合は、関数が返した値は保存されずに破棄されます。

コード2
#include <stdio.h>

int Triangle(int iBase , int iHeight) {
	return iBase * iHeight / 2;
}

int main() {
	int iBase , iHeight , iArea;
	printf("三角形の底辺と高さを入力してください>");
	scanf("%d %d" , &iBase , &iHeight);

	iArea = Triangle(iBase , iHeight);
	printf("三角形の面積 = %d\n" , iArea);
	return 0;
}
実行結果
コード2 実行結果

このプログラムの Triangle() 関数は、三角形の底辺 iBase と高さ iHeight を受け取り、面積を返す機能を提供しています。このように、何らかの機能や計算を関数としてまとめれば、関数を呼び出すだけで何度でもその機能を再利用することができるようになるのです。

コード2は、iBase と iHeight という識別子の int 型変数が Triangle() 関数と main() 関数の二ヶ所で定義されています。同一の関数内で識別子が衝突した場合はコンパイルエラーが発生しますが、この場合は関数が異なるので問題ないのです。Triangle() のパラメータである iBase と main() の iBase は同じ名前ですが、まったく異なる変数なのです。

C 言語では、関数の戻り値は省略することができます。C++ 言語としてコンパイルした場合はエラーになります。C 言語では型が省略された場合はデフォルトとして int 型であると解釈します。そのため、戻り値方を省略した場合は int 型の戻り値を持つと認識されます。しかしながら、戻り値を省略した誤解を生むような分かりにくい書き方は推奨されません。関数の目的をはっきりさせるためにも、戻り値は明確に記述するべきです。

コード3
#include <stdio.h>

int main() {
	return Function();
}

Function() {
	printf("Function()\n");
	return 0;
}
実行結果
コード3 実行結果

このプログラムは、main() 関数で Function() 関数を呼び出しています。この時点で、関数はまだ定義されていないので、コンパイラはデフォルトの関数 int Function() という型としてこの関数を認識します。その後に Function() 関数が戻り値を省略して定義されています。この関数は戻り値を省略しているため、戻り値はデフォルトの int として認識されます。デフォルトの関数と同じ型なので、プログラムは正常にコンパイルされます。

繰り返しになりますが、現在では型の省略は推奨されません。これは古い文法との互換性のために残されているものです。新しく記述するコードであれば、型は明示的に記述するべきです。