Ruby言語ではメソッドを自分で定義して、 一連の処理をまとめて行なうことができた。それと同様C言語では 関数を自分で定義して利用することができる。
C言語の関数定義は以下の形式で行なう。
型 関数名(引数リスト) { ……定義本体…… }
関数定義で意識すべき鉄則は、
- 関数が受け取る引数の型
- 関数が結果として返す値の型
を明確に厳密に指定すること
である。
簡単な定義例をいくつか見てみよう。
二つの整数を受け取り、それらを足し算した結果を返す関数は以下の
ように定義する。関数名を add
とする。
int add(int x, int y) { return x+y; }
まずは、先の鉄則にしたがって、「受け取る変数の型」と「返す値の 型」を厳密に考慮する。「整数」どうしを足した結果は「整数」であるか ら、受け取る値も返す値もintにしよう。受け取る値の型宣言は引数 リスト で明記する。二つのint型変数を受け取るので引数リストは
add(int x, int y)
とする。受け取る2つの値をしまうために、変数 x, y
を
利用している。変数名は(他の変数と干渉しなければ)何でも良い。
引数リストに書いて、呼出し側からの値を受け取る変数のことを
仮引数 という。
つぎに、関数でした仕事(この場合足し算)の結果を返す、その型を明
記する。整数と整数の和は整数だから、これも int 型となる。関数が結
果として呼び主に返すのが int なので、関数宣言の先頭を int
とする。
int add(int x, int y)
そして定義本体で、実際に足し算をした結果を呼び主に返すときに使
うのが return
文である。
return x+y;
三つの数を x, y, z
とすると、三つ数の平均は、
(x+y+z)/3
である。3で割ると整数にならないことがあるの
で、結果を呼び主に返すときは浮動小数点数(floatかdouble)で返す。
したがって、関数定義は以下のように書ける(float型にする)。
float three_average(int x, int y, int z)
{
return (x+y+z)/3.0;
}
intどうしの演算から、浮動小数点数の結果を得るために
3.0
と書いていることに注意せよ。
関数定義では、必ずしも計算した結果を返さなくても良い。
たんに、一連の処理をまとめて行なうだけで、return
文なしで何も返さず終わっても良い。
単純な例を考えてみよう。たとえば、メッセージを出してユーザに 文字列を入れさせる手順は以下のようになる。
char line[100]; : : printf("あなたの名前は?: "); fgets(line, sizeof line, stdin); :
メッセージを出すためにpirntf
を使い、入力を読み込む
ためにfgets
を利用している。、たった二つの手順だがこれ
を関数にまとめてみよう。printf, fgets
に与えている引数
は以下のようになる。
printf
への引数
メッセージとなる文字列
- その都度違う
fgets
への引数
stdin
これをふまえて、「画面にメッセージを出し、決まったchar型配列に 文字列を読み込んでもらう」は以下のように書ける。
void query(char* mesg, char* buf, int len)
{
printf("%s", mesg); /* 引数として受け取ったメッセージを表示 */
fgets(buf, len, stdin); /* 標準入力からの読み込み */
/* 註: 文字列を引数として受け取るときは char* 型として受け取る */
}
このように、なんらかの仕事はするものの、呼び主にとくに値を
返さない関数もありうる。値を返さないこと自体にも型があり、
それを void
型 という。
この関数を、main
関数から使う場合には、以下のよう
にする。
int main() { char line[100]; query("あなたの名前は?: ", line, sizeof line) }
関数の引数に、文字列(つまりchar型配列)を与える場合、
受け取り側の仮引数の型は、char*
型とする。
「char*
」のように *
印の付いたものを
「ポインタ」という。ポインタとは「値ではなくアドレスを持つ変数」
のことで次週以降に解説する。
関数を定義するときは、
型 関数名(引数リスト) { ……定義本体…… }
という形式で行なう。型 は、関数が return で返す 値の型名を書く。char, int, long, float, double などのほか、 何も返さない型として、void などが良く利用される。