これから数回に分けて,単純なはずなのにバグの多いプログラムから,バグを一つ一つ見つけて取り除き,正しく動くまでの流れをお見せしたいと思います.
俎上にのせるのは,二つの整数が互いに素かどうかを判定するCのプログラムです.
#include <stdio.h> #define relatively_prime(a, b) (gcd((a), (b)) == 1) int gcd(int a, int b); int main(void) { int x = 180, y = 120; int flag_rp = relativelyprime(x, y); if (frag_rp) { printf("%d and %d are relatively prime.\n", x, y); } else { printf("%d and %d are not relatively prime.\n", x, y); } return 0; } int gdc(int a, int b) { int r = a % b if (r == 0) { return a; } return gcd(b, r); }
プログラムではmainのほかに,最大公約数(greatest common divisor, GCD)を求める関数gcdと,互いに素(relatively prime)かどうかを判定する関数形式マクロrelatively_primeを定義しています.もう少し言うと,関数gcdでは,「aとbの最大公約数は,bと"aをbで割った余り"の最大公約数に等しい」ことを利用して,再帰を使って*1,最大公約数を求めています.そして,relatively_prime では,「互いに素 = 最大公約数が1」である事実を,Cの構文に注意して素直にマクロにしたというものです.
バグの原因とその除去方法については,次回以降ということで.
*1:過去に当日記で書いたことがありますが,いつものようにそれをリンクすると,バグ発見の面白さが減ってしまいますので,リンクしていません.