ログイン
kid's world

関数を作る

引数も戻り値もない関数

関数の作り方については,ごく簡単に第2回で解説したが,ここで再度解説する。

はじめに,とても簡単な関数を作り,関数の作成と利用の感覚をつかんでみよう。いちばん簡単な関数は「引数をとらず,戻り値も返さない」という関数だ。

List 1では,そのような関数「foo」を作っている。今まで,#includeを行っている部分とmain関数の間には何も書いてこなかったが,List 1では,ここにfoo関数の定義(すなわちfoo関数はこのようなものであるということ)が書かれている。

List 1: 引数も戻り値もない関数

#include <stdio.h>

void foo()
{
  printf("foo\n");
}

main()
{
  foo();
}

すでにお気づきのことと思うが,この書き方はmain関数とほとんど変わるところがない。そもそもmain関数は,その名のとおり1つの立派な関数だからだ。書き方が変わらないのは何も不思議なことではない。

あえて違うところをいうならば,それはvoidというキーワードである。このキーワードは関数名である「foo」の左側に書かれているが,この部分には通常「戻り値の型」を書く。List 1では戻り値のない関数を作ろうとしているのだが,型を書く部分を省略してはならない。それができるのはmain関数のみである(注意:できるならばmain関数も型の指定は省略しないほうがよい。C++言語では,main関数でも関数の型を指定しなければならないことになっている)。「戻り値がない」ということを明確にするために,C言語では「void」というキーワードを使う。関数名の左側にこのキーワードを書くことによって,その関数は戻り値を返さない関数となるのである。

関数を定義しただけでは,その関数は利用されることはない。その関数を利用するためには,関数の呼び出しを行わなければならない。それを行っているのが,main関数の,

foo();

の部分である。引数のない関数を使ったことは今までなかったのでこの書き方は異様に映るかもしれないが,関数は「必ず関数名のあとにカッコがなければならない」ため,引数がなくてもこのように書くのである。ちなみに,Pascalのように,引数がない場合はカッコを省略できるプログラミング言語もある。

値を返す関数

次は,値を返す関数を作ってみよう。第8回では,ある範囲内の数値をキーボードから入力してもらうときに気をつけなければならないことを説明した。範囲外の値が入力されたときはwhile文を使って再入力をさせたり,文字が入力されたときは入力バッファに入っている項目を1つ破棄するなど,めんどうなことが多かったと思う。

数値を受け取るたびに,このようなめんどうなことを繰り返さなければならないのだろうか? そんなことはない。一度関数を作ってしまえば,毎回いちいち考えずに気軽に利用することができるようになるのである。これこそが,関数を使うメリットである。

そのような便利な関数を作る前に,簡単に値を返す関数の「作り方」と「使い方」について説明しよう。

まず使い方についてだが,これはすでにgetchar関数を使う際に解説したように,関数はプログラム中では「式」として扱われる。たとえば,float型を返すfbarという関数を作ったとすれば,次のように使うことができる。この文は,「fbarの返す値を20.0で割った値をfloat型変数fに代入する」という文となる。

f=fbar()/20.0;

次に,関数の作り方である。値を返すには,return文を使う。たとえば,常に3.14159という値を返すfbar関数を作りたければ,次のように定義する。

float fbar()
{
  return 3.14159;
}

このように,「return」の右側にその関数で返したい値を指定するだけでその値を返すことができる。もちろんここは式でよいので,変数や計算式,さらには別の関数を書いてもよい。

なお,return文は呼び出されるとただちにその関数の実行を終え,呼び出し元へと制御を戻す。したがって,値を返さない関数で「return;」と書けばその時点でその関数の実行は終わる。さらにいえば,以前に「main関数でexit関数を使ってプログラムを強制的に終了」したが,main関数の呼び出し元はOSであると考えれば,main関数の中で代わりにreturn文を呼び出してもプログラムを終了できることがわかるであろう。

以上が値を返す関数の基本である。では,List 2に1から12までの値のみの入力を受けつけてその値を返す関数,「getmonth」関数の作り方とその利用例を示そう。

List 2:getmonth関数とその利用例

#include <stdio.h>

int getmonth()
{
  int m;
  
  do {
    printf("何月ですか?\n");
    if (scanf("%d", &m)!=1)
      scanf("%*s");
   } while (m<1 || 12<m);
  
  return m;
}

main()
{
  printf("今年は残り%dか月です。\n", 13-getmonth());
}

getmonth関数では,1から12までの整数以外の入力を排除し,do while文を抜け出したときには必ず1から12の範囲の整数が変数mに入るようにしている。そしてreturn文でその変数の値を返している。

一方,main関数ではprintf関数の引数の中で直接getmonth関数を呼び出している。関数呼び出しは式として扱われるので,このような使い方ができることに注意しよう。13から入力された値を引いた値を計算して,今年は今回を含めてあと何か月あるのかを表示している。この例ではgetmonth関数を一度しか使っていないが,何度も使う場合を想像すればその便利さがわかるだろう。もし関数を作ることを知らなかったら,同じようなコードを何度も書かなければならなかったところなのだ。


関数に関する注意」へ進む

広告


©Toshio Koide 1996-2007.

目次

リンクについて

リンクは御自由にどうぞ。

メール

mail.gif

広告