わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

再帰で最大公約数

ちょっと昔話を.
ユークリッドの互除法を使って,最大公約数を求めるプログラムを,ある学生が書いていました.しかし期待する出力になりません.
コードを再現すると…

int gcd(int a, int b)
{
  int r = a % b;

  if (r == 0) {
    return b;
  }

  gcd(b, r);
}

再帰を使っています.末尾再帰,テールリカージョンですね*1
さて,文法的にsyntactically,おかしなところはすぐに分かります.関数gcdの戻り値の型がintなのに,最後の(再帰呼び出しの)「gcd(b, r);」という文では,値を返さないのです.ここを「return gcd(b, r);」とすれば,うまく動きます.
以下フィクション.
学生「でも,『return b;』を実行するときのbが,最大公約数ですよね?」
先生「その最大公約数の値が,再帰呼び出しから戻っていく過程で,継承されないんですよ.『return gcd(b, r);』と書くことで,継承されるんです」

*1:末尾再帰は,反復に置き換えることで,容易にその再帰を除去できるものです.