【C言語講座】第4回 もしも○○なら××
閉じる
閉じる

新しい記事を投稿しました。シェアして読者に伝えましょう

×

【C言語講座】第4回 もしも○○なら××

2015-09-27 17:42
    0.今回扱う内容

    今回は一貫して「条件分岐」について扱います。
    ノベルゲームなんかで「ルート分岐」って出てきますよね?
    それの基礎の基礎に当たるのが今回の内容です。

    1.ifとelseの条件分岐 ~ もしAならBする。でなければCする。
    2.もっと複雑な条件分岐 ~ もしAなら、Bする。Aでなく、さらにCならDする。
    3.アルゴリズムとフローチャート ~ コードの手順を考えよう
    4.論理演算子いろいろ ~ もし、AかBなら、Cする。


    1.ifとelseの条件分岐 ~ もしAならBする。でなければCする。

    身近なプログラムというとどうしてもゲームになっちゃうので、またゲームの例を出します。
    上下左右のボタンを押すと、キャラクターが上下左右に動くようなゲーム(シューティングとか?)を想像してみましょう。

    こうしたゲームでは「もし上ボタンが押されていたら、キャラクターを上に動かす」、「もし下ボタンが押されていたら、キャラクターを下に動かす」……といった判断が常にされています。

    ほかのゲームでも、「もしAボタンが押されていたら、キャラクターをジャンブさせる」、「もしYボタンが押されていたら、必殺技を出す」。
    もっと原始的な例で言えば、(二人での)じゃんけんで「もし相手がパーで、自分がチョキなら、勝ち」。……しつこいですかね?

    今回はこうした「もしAだったら、Bする」という処理の方法を扱います。

    まずはコード例から。

    さあ、まずは順に読んでみましょう。

    最初は宣言から。「int a;」で「int型の変数『a』を用意」しています。

    次にprintfで「整数を入力:」という説明文を表示します。ただし、今回は最後に改行(\n)が入っていません。つまり、直後のscanfによる入力は「整数を入力:」と同じ行で行われます。まあ実行結果を見れば意味はわかると思います。

    scanfによる入力では「%d」(整数)の入力を受け付けて、入力された数字を変数「a」に入れています。

    ここからが新しい内容です。一行ずつ見ていきます。

    if (a == 0){

    if」という名前や今回のテーマから分かる通り、「もし~なら」を判断するのがこの文です。
    その「~」にあたる条件は、( )の中身です。つまり、この場合の条件は「a == 0」です。

    「a」は変数、「0」はただの数字ですが、「==」は初めての記号ですね。
    これは「比較演算子」と呼ばれるものの一つです。比較演算子は、その左右にある数を比較するための記号で、以下のような種類があります。

    • 「==」……左右の数は等しいか?
    • 「!=」……左右の数は異なるか?
    • 「<」……左より右の方が大きいか?
    • 「>」……左より右の方が小さいか?
    • 「<=」……左より右の方が大きい、または等しいか?
    • 「>=」……左より右の方が小さい、または等しいか?

    「代入」の説明の時、「『等しい』という意味の記号は『=』とは別にある」と言いました。それがこの「==」です。
    つまり、「a == 0」は「aと0は等しいか?」という意味(条件)になります。

    更に遡って、「if (a == 0){」は「もし、aと0が等しいなら」という意味になります。

    そして、「もしAならBする」の「Bする」の部分は、{ }の中に書くことになっています。

    C言語では{ }で囲まれた部分をまとまりとみなし、中身は見やすいように少し右に寄せるのでした(インデント)。
    というわけで、次の行にはインデントがかかっています。
    そして、その行ではprintfで「ゼロだよ」と表示し、改行しています。

    次に、}で「もし、aと0が等しいなら」のまとまりが閉じられた後で、「else」と書かれています。
    単語の意味から推測できるかもしれませんが、「そうでない場合は」という意味です。

    そして、else{ }の中ではprintfで「ゼロじゃないよ」と表示し、改行しています。

    つまり、まとめるとこのプログラムは、
    scanfで入力された数字(a)が

    • もし、aと0が等しいなら、「ゼロだよ」と表示(+改行)する。
    • そうでない場合は(aが0でないときは)、「ゼロじゃないよ」と表示(+改行)する。

    というプログラムです。こう書くと単純ですね。

    分岐ごとに実行結果を示します。


    ちなみに、ifやelseの中身(条件に当てはまった時に実行されるモノ)が1行で済む場合は、

    上のように、{ }を省略して書くことができます。人によってはこっちのほうが分かりやすいかも……?

    また、elseがいらない場合(「もしAならBする」だけの場合)、else以下は書かないで大丈夫です。


    2.もっと複雑な条件分岐 ~ もしAなら、Bする。Aでなく、さらにCならDする。

    タイトルの通りのちょっと複雑な分岐を作ってみましょう。まずはコード例。

    前章のプログラムより分岐が一つ増えました。変わったところを一つずつ見ていきます。

    else if (a > 0) {
    printf("プラスだよ\n")
    }

    「else」は「そうでない場合は」、「if」は「もしAならBする」でした。
    というわけで、「else if」だと、「そうでない場合で、さらに、もしAならBする」となります。
    つまり、この「else if」のまとまりは、「aが0でなくて、さらに、aが0より大きければ、printfで『プラスだよ』と表示し、改行する」という意味になります。

    この場合、一見すると、「aが0でなくて」という条件は無意味に思えます。この問題については次章で説明します。とりあえず次に進みましょう。

    else if (a > 0) {
    printf("プラスだよ\n")
    }

    これも先程と同様に、「aが0でなくて、さらに、aが0より大きくもなくて、さらに、aが0より小さければ、printfで『マイナスだよ』と表示し、改行する」という意味になります。
    色々と無意味な判断が入っているような気がします。

    とりあえず実行しましょう。



    つまりこれは、scanfで入力された数字(変数『a』の中身)が

    • 0なら「ゼロだよ」
    • 正なら「プラスだよ」
    • 負なら「マイナスだよ」

    と表示するプログラムです。


    3.アルゴリズムとフローチャート ~ コードの手順を考えよう

    前章のコードの手順を「フローチャート」と呼ばれる図に直すと、次のようになります。


    この図では、四角□が「処理」を、ひし形◇が「判断」を、角が丸い四角が「開始と終了」を表します。

    次に、これと同じ結果になるコード例と、そのフローチャートを幾つか示します。

    コード例1:

    コード例2:

    コード例3:

    例1では、最後の「else if」での判断を外して、無条件で「マイナスだよ」と表示するようにしました。ゼロでもプラスでもなかったら、判断するまでもなくマイナスですからね。
    ちなみに、if・else if・elseの中身は1行ずつなので、次のように書いても大丈夫です。

    例2では、「else if」ではなく、すべて「if」で判定することにしました。
    ただし、プログラミングにおいて、判断を行う回数が多いと、「遅いプログラム」になってしまいます。
    例2では、入力されたのが0だろうとプラスだろうとマイナスだろうと、必ず3回の判断を通ることになります。
    一方で、例1なら、入力されたのが0なら1回、0以外なら2回の判断だけを通ることになります。
    とはいえ、この講座では「動けば勝ち」なので、別にどちらで書いても問題はありません。

    例3のフローチャートは、例1のものと同一です。しかし、コードが変わっています。
    このコードのように、{ }で囲まれたまとまりの中に、さらに{ }で囲まれたまとまりを入れることを「入れ子ネスト)」と呼びます。

    また、フローチャートのように、実際にコードを書くわけではなく、正しい結果を導く処理や判断の実行順序だけを表現したもののことを「アルゴリズム」と呼びます。

    NHK Eテレの「ピタゴラスイッチ」で「アルゴリズム体操」というのがありました。
    せっかくniconicoのブロマガで記事を書いているので、ニコニコ大百科の記事から引用すると

    アルゴリズムというとコンピュータープログラミングを思い浮かべる人が多いのではないかと思うが、ここでいうアルゴリズムは「手順」といった意味合いである。すなわち、「手を横に、あら危ない、頭を下げればぶつかりません」に象徴されるように、各自がばらばらな動きをしていたら衝突が避けられないような環境でも、みんなが同じ規則・アルゴリズムに従えば障害を回避できるのである。

    ニコニコ大百科「アルゴリズムこうしん」より

    だそうです。また、年1~2回やっている「大人のピタゴラスイッチ」でも「アルゴリズム」という言葉が取り上げられ、例として「(電車が駅についた時に)車掌さんがドアを開けて、このボタンを押して、安全を確認して、……」というようなアルゴリズムが挙げられていました。

    無駄話が過ぎましたね。そろそろ次の章に進みましょう。

    なお、このプログラムの場合、変数「a」をint型(整数)に限定する必要は特にありません。
    もし余力がある人は、double型(実数)に書き直してみましょう。
    もし、全部「マイナスだよ」になったらscanfの変数文字列あたりを疑ってみましょう。


    4.論理演算子いろいろ ~ もし、AかBなら、Cする。

    今回はあと一章ばかりお付き合いください。

    ここでは、タイトル通り「論理演算子」というものを扱います。
    具体的には次の三つ。

    • 「&&」……「and(かつ)」の意味。「A && B」なら「Aでもあり、Bでもある」。
    • 「||」……「or(または)」の意味。「A || B」なら「Aであるか、Bである」。
    • 「!」……「not(ではない)」の意味。「! A」なら、「Aではない」。

    ちなみに、「&」はShift+6、「|」はShift+「\」(キーボード右上)で入力できます。

    ここで注意して欲しいのは、喫茶店で「コーヒーか紅茶」と言われたら普通「コーヒーと紅茶の両方」という選択は想定されていませんが、プログラミングでは「AまたはB」と言えば普通「AかB、またはその両方」を意味する点です。

    コード例を見ていきましょう。

    まずは読んでいきます。

    見慣れない箇所は「a > 0 && a < 10」です。
    これは「aが0より大きく、さらに10より小さい」を意味します。
    ここでaはint型(整数)なので、「aは1,2,3,4,5,6,7,8,9のいずれか」と読み替えられます。
    つまりは「aは1桁の整数」ということになります。

    結果は次の通り。


    次は、逆に「一桁の正の数ではないよ」と表示するコードを書いてみましょう。
    変える箇所は「if」の条件と、中身のprintfで表示する文字です。

    表示する文字は「一桁の正の数ではないよ」に変えるだけなので簡単です。
    問題は「if」の条件の方。「ではない」は「!」でしたから、

    if (!a > 0 && a < 10)

    とすれば良いのでしょうか? 答えは次の通り。

    ( )が付きました。「『aは0より大きい かつ aは10より小さい』ではない」ということですね。

    先ほどの「if (!a > 0 && a < 10)」だと、「!」は直後の「a」だけに係るので、「『aではない』は0より大きい かつ aは10より小さい」という意味不明なことになります。

    なお、「aは0より大きい かつ aは10より小さい」は「aは0より大きくない または aは10より小さくない」と書いても同じなので、

    if (!(a > 0) || !(a < 10))

    と書いても大丈夫です。あるいは、「aは0以下 または aは10以上」、つまり

    if (a <= 0 || a >= 10)

    と書いても同じことになります。まあ、どれ書いても「動けば勝ち」ですよ。

    また、論理演算子も「+ - * / %」のような普通の演算子と同様に、「A && B || C」のような複雑な計算では「(A && B) || C」のように括弧をつけてわかりやすくしましょう。


    お疲れ様でした。次回は、「繰り返し」について扱う予定です。


    広告
    コメントを書く
    コメントをするには、
    ログインして下さい。