(8)[C] factorial関数の種々の定義

右から計算していく戦略

左からではなく右から計算をしていくことも可能である,前回とほぼ同一の構文をつかって以下のように書ける,

int factorial2 (int x) {
  int s = 1;
  int i = 1;
  while (x >= i) {
    s = i * s;
    i = i + 1;
  }
  return s;
}

(x >= i)はiがxより小さいか等しい時真となるので,この繰り返しで,1からxまでこの順番に掛け合わせる計算が実行される,

for構文を使った例,

while構文は,カッコの条件が真である間繰り返す構文であるが,factorialのようにある数字が順番に変化していくような繰り返しは,以下のようにfor文を使って書くことができる,

int factorial3 (int x) {
  int s;
  for (s = 1; x > 0; x= x - 1) {
    s = s * x;
  }
  return s;
}

変数sに初期値の指定がないので初期値は不定である,最初に必ず初期化して使用する必要がある,for文は以下の動作をする繰り返し構文である,

  1. 繰り返しの最初にs = 1;を一回だけ実行する,
  2. 条件x > 0 が真である間,それに続くブロック(実行文のまとまり)を繰り返し実行する,この例ではs = s * xを実行する,
  3. 各繰り返し実行の最後にx = x + 1を実行する,

for文は一般に以下の構造をもつ,

for(初期設定式 ; 継続条件式 ; 再設定式) 文

  • 初期設定式と再設定式は代入式をコンマで並べたものである,順次式とよばれる,
  • 継続条件式は整数を値とする式である,

演算子の利用

上記の関数は,xの値を1減ずる演算子x--を使って以下のようにも書ける,

int factorial4 (int x) {
  int s;
  for (s = 1; x > 0; x--) {
    s = s * x;
  }
  return s;
}

右から行う計算はiに1加える演算子i++を使って以下のように書ける,

int factorial5 (int x) {
  int s;
  int i;
  for (s = 1, i = 1; x >= i; i++) {
    s = i * s;
  }
  return s;
}

この例では,初期設定式は二つの代入式からなる順次式となっている,これら2つの代入は左から順に実行される,以下のように書いてもよい,

int factorial6 (int x) {
  int s = 1
  int i = 1;
  for (; x >= i; i++) {
    s = i * s;
  }
  return s;
}

この場合,初期化の処理は空文であり何もしない,i++は式であり,1加算される前のiの値を返す,そこで,以下の様に書いても同一の結果が得られる,

int factorial7 (int x) {
  int s = 1
  int i = 1;
  for (; x >= i;) {
    s = i++ * s;
  }
  return s;
}

加算演算子を変数の前に置き++iと書くと,この式の値は,iに1加算した後のiの値となる,この式を使って上記関数を書き直すと以下のようになる,

int factorial8 (int x) {
  int s = 1
  int i = 0;
  for (; x > i;) {
    s = ++i * s;
  }
  return s;
}

iの初期値が0,条件判定はx > iに変更されている点に注意,

再帰関数を使った定義

上記のいずれも,Cの特徴を生かした効率よいプログラムである,しかし,Cでも再帰関数を使った以下のような定義も可能である,

int factorial9 (int x) {
  if (x == 0) {return 1;}
  else {return (x * factorial9(x - 1));}
}

この再帰関数の扱いは,ML言語の基本である,そこで,階乗の計算を例に,MLの関数定義を学ぼう,


[ トップ | 目次 | 前ページ | 次ページ ]