関数とは
C言語における関数とは意味や内容がまとまっている処理をひとつにまとめ、繰り返し使えるようにしたものです。
関数を定義することにより、プログラムの可読性や保守性を高くすることができます。つまり、読みやすくて、わかりやすく、修正が容易で、応用の効くプログラムを作成することができるということです。
関数には2種類あります。戻り値があるものとないものです。戻り値は「もどりち」と読みます。返り値(かえりち)、リターン値(りたーんち)とも呼ばれ、関数が返す値のことです。C言語では戻り値があるものもないものも関数と呼んで仕様上の区別はありませんが、他のプログラミング言語では2つを区別するものもあります。例えばPascalでは、戻り値があるものを関数、ないものを手続きと呼んで区別します。
関数の定義
リターン型 関数名(もしあれば、引数の宣言)
{
ローカル変数等の宣言
プログラム文
もし必要なら、リターン文
}
リターン型とは、関数の戻り値の型です。関数の返す値がint型ならリターン型にintと書きます。double型ならdoubleと書きます。戻り値がない場合はvoidとなります。
関数名は、関数の名称です。命名のルールは変数の命名ルールと同じです。関数の処理内容を適確に表す名称をつけるとよいでしょう。
関数名の後の括弧の中で引数の宣言を行ないます。引数の型とこの関数内で使用する名称を指定します。
実際の関数の処理は{}の中に記述します。関数の終わりの}の後には;(セミコロン)は不要です。初心者は間違えやすいので気をつけましょう。
戻り値を指定して関数を終了するにはreturn文を使います。returnの後に続けて式を書くことによって戻り値を返すことができます。
戻り値を返さない場合は、return文を書く必要はありません。関数の終わりに達すれば処理は終了し、制御がコール元に移ります。ただし、関数の終わりに達する前に処理を終了したい場合は、return文を使います。
関数の具体例
関数の具体例として、閏年判定プログラムを書いてみます。
<leapyear.c 閏年判定プログラム>
/*
leapyear.c
閏年判定プログラム
*/
/* インクルードヘッダ */
#include <stdio.h>
#include <stdlib.h>
/* プロトタイプ宣言 */
int isLeapYear(int y);
/*
メイン
*/
int main(int argc, char *argv[])
{
int year = 0;
/* 引数のチェック */
if (argc < 2) {
/* 引数が指定されていない場合は */
/* 使用方法を表示して処理終了 */
printf("Usage: %s <year>¥n", argv[0]);
return 0;
}
/* 第一引数を西暦年として取得,atoi()でintに変換 */
year = atoi(argv[1]);
/* 年を出力 */
printf("西暦%d年は", year);
/* もし年が閏年なら */
if (isLeapYear(year)) {
/* '閏年です'と出力 */
printf("%s¥n", "閏年です。");
} else {
/* そうでなければ */
/* '閏年ではありません'と出力 */
printf("%s¥n", "閏年ではありません。");
}
return 0;
}
/*
閏年判定
isLeapYear
<概要>
指定された西暦年が閏年かどうかを判定する。
<戻り値>
1:閏年
0:閏年ではない
<引数>
int y:(i)西暦年
*/
int isLeapYear(int y)
{
int r = 0;
/* 西暦年が4で割り切れ,かつ100で割り切れない年は閏年 */
/* または400で割り切れる年は閏年 */
if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0) {
r = 1;
} else {
r = 0;
}
return r;
}
プログラムをコンパイルし、コマンドラインから閏年の判定を行いたい年を引数として指定して、プログラムを実行すると指定した年が閏年かどうかを表示してくれます。
/* プロトタイプ宣言 */
int isLeapYear(int y);
この部分はプロトタイプ宣言です。isLeapYear()の定義とリターン型や引数の型が一致してなければいけません。引数名は省略しても、定義と異なっていても大丈夫ですが、メンテナンス性を考えると、定義と揃えておく方がよいでしょう。
プロトタイプ宣言により、コンパイラは関数のリターン型や引数の型を知ることができます。これにより、プログラムの中で関数の使い方が間違っている箇所があった場合、コンパイルエラーを出すことが可能になります。
プロトタイプ宣言の末尾にはセミコロンが必要です。初心者の方は間違いやすいので気をつけましょう。
/*
閏年判定
isLeapYear
<概要>
指定された西暦年が閏年かどうかを判定する。
<戻り値>
1:閏年
0:閏年ではない
<引数>
int y:(i)西暦年
*/
この部分は、関数の内容を書いたコメントです。プログラムを読まなくても関数をすぐ使用できるように、概要、使用方法、注意点等を書いておくとよいでしょう。自分で書いた関数でも時が経つと内容を忘れてしまいます。プログラムは貴重な財産ですので、きちんと管理しておくと後々役に立つことがあるでしょう。