FizzBuzzループ版

1個の判定を、N個へ広げる

第3章で FizzBuzz の判定を書きました。あのときは 1 つの数について、3 の倍数なら Fizz、5 の倍数なら Buzz、両方なら FizzBuzz、それ以外は数そのもの、と分けるところまででした。

判定そのものは完成しているので、あとは繰り返すだけです。この「1 つぶんを完成させてから、ループで包む」という進め方は、この先どんな課題でも使える組み立て方です。いきなり全体を書こうとせず、まず 1 件を正しく動かしてから回数を増やします。

for (i = 1; i <= n; i++) { /* ここに第3章で書いた判定をそのまま入れる */ }

判定の順番だけは動かせない

ループにしても、判定の順番に関する注意はそのまま残ります。

if (i % 15 == 0) { printf("FizzBuzz\n"); } else if (i % 3 == 0) { printf("Fizz\n"); } else if (i % 5 == 0) { printf("Buzz\n"); } else { printf("%d\n", i); }

15 の判定を最初に置くのは、15 が 3 の倍数でも 5 の倍数でもあるからです。i % 3 を先に確かめてしまうと、15 が Fizz として処理されて終わってしまい、FizzBuzz が一度も出ません。else if は上から順に確かめて、最初に真になったところで止まる仕組みなので、条件の厳しいものから先に並べる のが鉄則です。

この間違いは 1 から 5 までを試すだけでは見つかりません。少なくとも 15 まで動かして初めて表に出ます。テストする範囲を意識するのも練習のうちです。

回数を外から決める

この課題では、どこまで数えるかを scanf で読み込みます。定番の FizzBuzz は 1 から 100 までですが、上限を変数にしておけば、動作を確かめたいときは 15、本番は 100、と使い分けられます。数を直接コードに書き込まず変数にしておく、という習慣は、成績管理CLI で人数を扱うときにもそのまま効いてきます。

数として出すか、文字として出すか

もうひとつ見落としやすいのが、else の中の書き方です。Fizz や Buzz は決まった文字列なので printf("Fizz\n") でそのまま出せますが、それ以外の回に出したいのは i の中身、つまり毎回変わる数です。ここで printf("i\n") と書いてしまうと、画面には i という 1 文字が並びます。値を出したいのだから printf("%d\n", i) と書式指定を使います。第2章でやったことですが、文字列と値の区別はここでも同じです。

ちなみに FizzBuzz は、採用面接の入り口でよく使われてきた問題です。難しいからではなく、条件の順番と繰り返しを両方きちんと組み立てられるかが、短いコードにそのまま出るからです。第3章の判定と第4章のループがつながったことを確かめる題材として、ちょうどよい大きさになっています。

では、上限を読み込んで、1 からその数までの FizzBuzz を出してみましょう。

要件

  1. 最初に scanf で上限 N を読み込む
  2. 1 から N まで for で回す
  3. 15 の倍数の判定を先に書く
  4. どれにも当てはまらない数は、その数を10進数で表示する

入出力例

main(15) → "1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz" main(5) → "1 2 Fizz 4 Buzz"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.c
学習モード

メモ

FizzBuzzループ版

⌘S で保存