関数

概要
これまでのプログラムでは, main関数 の中にプログラムをすべて書いてきた.しかし,例えば入力されたデータの平均と分散を計算するプログラムを考えたとき,平均や分散を計算するコードは, ほかのプログラムでも再利用できる だろう.ここではその実現方法のひとつである 関数 について説明する.
目次

関数定義・関数呼び出し

関数とは,ある入力が与えられたときに適切な処理をほどこして出力するコードのことである.例えば実数値の入力に対してそれを n 乗した結果を返す関数 power(x,n) を定義すれば,その関数は何度でも使うことができる.

関数は,次の要素からなる:

  • 関数名: 関数の名前. if などの 予約語 と同じにしてはならない.
  • 引数: 関数に入力される変数.複数でもよい.何も入力しない場合は void を使う.
  • 戻り値: 関数が返す関数.何も返さない場合は void を使う.
  • 本体: 入力に対して適当な処理を施し,必要に応じて return で値を返す処理を書く.

関数の定義は,

length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1360.
length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1370.
  戻り値の型  関数名(仮引数リスト)
  {
    本体;
  }
  // 例:
  double power (double x, int n)  // x, n: 引数
  {
    double ret=x;
    for (int i=1; i<n; ++i)
      ret*=x;
    return ret;  // ret を返す.
  }

のように書く.定義した関数を使うには,式中で :

length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1360.
length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1370.
  関数名(実引数リスト)
  // 例:
  x=power(2.5,3)+10.0;

と書く.

例:二つの整数の大きい方の値を返す関数 :

length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1360.
length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1370.
  #include <stdio.h>
  #include <stdlib.h>
  #include <iostream>
  using namespace std;
  // 関数定義 (xとyのうち大きい方を返す)
  int maxof(int x, int y)
  {
    if(x > y)  return x;
    else       return y;
  }
  int main(int argc, char**argv)
  {
    int na, nb;
    cout<<"2つの整数をスペースで区切って入力してください (例: 10 20)"<<endl;
    cout<<">> ";
    cin>>na>>nb;
    cout<<"大きい方の値は"<<maxof(na, nb)<<"です"<<endl;
    return 0;
  }

上の例では, maxof 関数に int 型の na と nb を引き渡し,大きい方の値をint型で返すように定義している.また,関数内でほかの関数を呼び出すことも可能である.

ヒント

 関数内で,引数として与えられた変数の値を変えても,もとの引数の値は変化しない.これは,関数呼び出し時に値が ''コピーされる'' からである.

コマンドライン引数

プログラムに外部から値を与えたい場合には, **コマンドライン引数** を使う. Unix/Linux ではコマンドラインで ::

 cp hoge.cpp hehehe.cpp

などのようにコマンドを実行するが,これは cp がプログラム, hoge.cpp hehehe.cpp がコマンドライン引数である.同様にして自分が作ったプログラムにも引数を与えられ,その結果は, main 関数の引数としてプログラムに取り込まれる.

main関数のフォーマット:

length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1360.
length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1370.
  int main(int argc, char *argv[])
    int argc: 引数の総個数(プログラム名も含む)
    char *argv[]: 引数の文字列を指すポインタの配列(配列,ポインタは次章で詳しく説明)

例:以下のソースをコンパイルしてできたプログラム a.out にコマンドライン引数 apple, orange, banana を与える:

length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1360.
length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1370.
  #include <iostream>
  using namespace std;
  int main(int argc, char**argv)
  {
    int i;
    cout<<"コマンドライン引数の総個数: "<<argc<<" 個"<<endl;
    for (i = 0; i < argc; ++i)
      cout<<i<<"番目の引数: "<<argv[i]<<endl;
    return 0;
  }

実行方法

 % ./a.out apple orange banana

実行結果

 コマンドライン引数の総個数: 4 個
 0番目の引数: ./a.out
 1番目の引数: apple
 2番目の引数: orange
 3番目の引数: banana

再帰

ある事象を定義する際,その定義に自分自身を含んでいることを 再帰的である と言う.プログラミングでは,ある関数Aが自分自身である関数Aを繰り返し呼び出して,呼び出した順に処理が行われて再び帰ってくるような処理を再帰と呼ぶ.

  • 例:4の階乗
    n の階乗を求める手続きを factorial~(n) とすると,
4! = \textit{factorial}~(4)
= 4 \times \textit{factorial}~(3)
= 4 \times 3 \times \textit{factorial}~(2)
= 4 \times 3 \times 2 \times \textit{factorial}~(1)
= 4 \times 3 \times 2 \times 1 \times \textit{factorial}~(0)

となる.これを実装すると,次のようになる.

例:階乗を計算する関数

length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1360.
length() used on @lines (did you mean "scalar(@lines)"?) at /usr/bin/code2html line 1370.
  #include <iostream>
  using namespace std;
  //  階乗を返す
  int factorial(int n)
  {
    int sum;
    if(n > 0)
      sum = n * factorial(n - 1);
    else
      sum = 1;
    return sum;
  }
  int main(int argc, char**argv)
  {
    int num;
    cout<<"整数を入力してください: ";
    cin>>num;
    cout<<num<<" の階乗は "<<factorial(num)<<" です"<<endl;
    return 0;
  }

結果

 整数を入力してください: 10
 10 の階乗は 3628800 です

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-08-30 (木) 07:17:04 (75d)