Code029: Cプログラミング 〜 違いの分かるプログラム!? if...else 〜

この記事は2002年に書かれたものです。


■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
【 Webプログラミング Code Sample 】                          Since2001/11/23

                        Code029: Cプログラミング
               〜 違いの分かるプログラム!? if...else 〜

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                                                    Produced by ichikoro.com

           ▼毎週月曜日と金曜日に配信しています。
           ▼等幅フォントでご覧いただくとキレイに見えます。
           ▼登録・解除はこちらから可能です。
               < http://www.ichikoro.com/webp/ >
                  ※バックナンバーへのリンクもあります。
                  ※お友達にもぜひお勧めください(^^)/

─【Contents】───────────────────────────────
    01.Review ................... 前回のおさらい
    02.Guide .................... 選択構造:ifとelse
    03.Guide .................... 選択構造:ifのネスト
    04.Guide .................... 選択構造:else if
    05.Guide .................... 選択構造:ifのまとめ
    06.Guide .................... 選択構造:whileと組み合わせて使ってみよう
    07.Question ................. 今週の問題
    08.From Editor .............. 編集後記


                   【 Webプログラミングは毎週2本立て! 】

             ・月曜日版はWebの実際の活用方法などを特集します。
             ・金曜日版はHTMLやCGIなど一つの分野について最初から
              解説する講座になっています。現在はC言語入門です。


こんにちは、編集者の勝部です。

先日引越し通知を知人に出して以来、衝撃的な出来事が続いて...という話は冒頭
からこゆぎるので、編集後記でするとして、

前回、送信する直前に「今日はAprilFoolじゃないか!」ということに気がつき、
必死にネタ探し。最初は「大阪に引っ越しました」というタイトルで文面は全部
大阪っぽくいこうと思ったのですが、そのとき同時にみつけた「コロ助語変換」
にもう、メロメロ(笑)

というわけで、いつもあのようなメルマガではないので誤解の無い様>2回目の方

しかし夜な夜な、大の大人がコロ助語を必死に校正している姿は何とも哀れで
す。背中が泣いてます。汚れちまった悲しみにってもんです(誤)

【前回参考にしたサイト】
  ・さくらさくらWORLD
    http://www.geocities.co.jp/Hollywood/4078/
        知る人ぞ知る、超有名な顔文字サイト。昔から愛用させていただいてお
        ります。“顔”や“汗”の変換効率が激悪になってもいいなら、顔文字
        辞書は即インストール! もちろんコロ助語変換も。


ではでは今週もいってみましょう!


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  01.Review  「前回のおさらい」
──────────────────────────────────────

前回は、「暗黙の型変換」について解説しました。


>    (1)C言語の変数には「型」という考え方がある
>    (2)型は、それぞれ扱う物が違い、扱える大きさも異なる
>        short    2byte   主に整数を扱う。
>        int      4byte   主に整数を扱う標準的な型。環境によって大きさが異なる。
>       long     4byte   shortより大きな整数を扱う。
>        char     1byte   主に文字を扱う。
>        float    4byte   小数点を扱うときに使用。
>        double   8byte   floatより桁数の多い小数点を扱うときに使用。
>
>    (3)違う型同士で代入をすると「暗黙の型変換」が行われる
>    (4)「暗黙の型変換」では、代入する先の変数の型に変換される
>        例:
>            int    = short  (intに変換)
>            int    = long   (intに変換)
>            int    = double (intに変換)
>            long   = short  (longに変換)
>            long   = int    (longに変換)
>            double = int    (doubleに変換)
>
>    (5)代入する先の型が扱える大きさよりも、代入する値が小さい場合は問題は起こらない。
>        例:
>            int    = short  (intに変換)     OK
>            long   = short  (longに変換)    OK
>            long   = int    (longに変換)    OK
>
>    (6)代入する先の型が扱える大きさよりも、代入する値が大きい場合は問題が起こる。
>        例:
>            short  = int    (shortに変換)   NG
>            int    = long   (intに変換)     NG


さてさて、今回は予告どおり、選択構造について解説したいと思います。

    ・Code27(前回)
      http://www.ichikoro.com/webp/back_list/?cd=00027



━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  02.Guide  「選択構造:ifとelse」
──────────────────────────────────────

みなさん順次構造と反復構造は、これまで解説したとおり、ご理解されていると思い
ます。残すところ選択構造だけです。さて、選択構造とはなんでしょうか?


そんなに難しい話ではなく、例えば

    もし、AがBより大きいなら、“Aが大きい”と表示
    もし、そうでないのなら、“Bが大きい”と表示

といったような処理を実現する物が、選択構造です。では上の文章を早速、C言語に
直してみましょう。a と b の変数の値を変えて、実行してみてください。

    #include<stdio.h>

    int main(void)
    {
        int a = 100;
        int b = 500;

        if( a > b ){                /* AがBより大きいなら */
            printf("Aが大きい");    /* Aが大きいと表示 */
        }
        else{                       /* そうでないのなら */
            printf("Bが大きい");    /* Bが大きいと表示 */
        }

        return(0);
    }

    ■実行例
        C:\>bcc32 if_sample.c
        Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
        if_sample.c:
        Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

        C:\>if_sample
        Bが大きい

whileとよく似ており、

    ifの横にある括弧が“真”の時、'{' から '}' までの処理を実行する

という物です。
今回はこれにおまけがついています。

    ifが偽の場合、elseの'{' から '}' までの処理を実行する

という物です。
このelseはつけてもつけなくてもOKですので、

    #include<stdio.h>

    int main(void)
    {
        int a = 100;
        int b = 500;

        if( a > b ){                /* AがBより大きいなら */
            printf("Aが大きい");    /* Aが大きいと表示 */
        }

        return(0);
    }

というプログラムでもOKです。
ただし、

    #include<stdio.h>

    int main(void)
    {
        int a = 100;
        int b = 500;

        else{                       /* そうでないのなら */
            printf("Bが大きい");    /* Bが大きいと表示 */
        }

        return(0);
    }

という物はNGです。
試しにコンパイルしてみると、

    C:\>bcc32 if_sample.c
    Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
    if_sample.c:
    エラー E2054 if_sample.c 8: else の位置が誤っている(関数 main )
    警告 W8004 if_sample.c 13: 'b' に代入した値は使われていない(関数 main )
    警告 W8004 if_sample.c 13: 'a' に代入した値は使われていない(関数 main )
    *** 1 errors in Compile ***

という具合になりました。
冷静に考えれば、そりゃそうです(^^;

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  03.Guide  「選択構造:ifのネスト」
──────────────────────────────────────

さて、上では

>    もし、AがBより大きいなら、“Aが大きい”と表示
>    もし、そうでないのなら、“Bが大きい”と表示

という例でしたが、これが

    もし、AがBより大きいなら、“Aが大きい”と表示
    もし、AとBが同じなら、“AとBは同じ”と表示
    もし、そうでないのなら、“Bが大きい”と表示

という場合だったらどうなるでしょうか?
例えば、こんなソースが考えられます。

    #include<stdio.h>

    int main(void)
    {
        int a = 100;
        int b = 500;

        if( a > b ){                /* AがBより大きいなら */
            printf("Aが大きい");    /* Aが大きいと表示 */
        }
        if( a == b ){               /* AとBが同じなら */
            printf("AとBは同じ");   /* AとBは同じと表示 */
        }
        if( a < b ){                /* BがAより大きいなら */
            printf("Bが大きい");    /* Bが大きいと表示 */
        }

        return(0);
    }

こんなソースでもOKです。

    #include<stdio.h>

    int main(void)
    {
        int a = 100;
        int b = 500;

        /* AがBより大きいなら */
        if( a > b ){
            printf("Aが大きい");    /* Aが大きいと表示 */
        }
        else{                       /* そうでないなら */

            /* BがAより大きいなら */
            if( a < b ){
                printf("Bが大きい");    /* Bが大きいと表示 */
            }
            /* それ以外なら(つまりAとBが同じなら) */
            else{
                printf("AとBは同じ");  /* AとBは同じと表示 */
            }

        }

        return(0);
    }

そう、ifの中にifを入れることが可能です。
このような物を「入れ子(いれご)」または、「ネスト」と呼びます。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  04.Guide  「選択構造:else if」
──────────────────────────────────────

ただ、上記の問題を実現する方法はもう一つ考えられます。

    #include<stdio.h>

    int main(void)
    {
        int a = 100;
        int b = 500;

        if( a > b ){                /* AがBより大きいなら */
            printf("Aが大きい");    /* Aが大きいと表示 */
        }
        else if( a == b ){          /* AとBが同じなら */
            printf("AとBは同じ");   /* AとBは同じと表示 */
        }
        else{                       /* そうでないなら(つまりBがAより大きい) */
            printf("Bが大きい");    /* Bが大きいと表示 */
        }

        return(0);
    }

ここで注目するのは、すでにお気づきの通り、

>        else if( a == b ){          /* AとBが同じなら */

この部分ですね。
これは、上部にあるifが偽の場合で、尚且つその横にある括弧の中身が真の場合に
'{' から '}' までの処理を実行します。


ちなみに、else ifは複数記述することが可能です。
例えばこんな感じです。

    #include<stdio.h>

    int main(void)
    {
        int a = 200;

        if( a > 500 ){
            printf("Aは500より大きい");
        }
        else if( a > 400 ){
            printf("Aは400より大きい");
        }
        else if( a > 300 ){
            printf("Aは300より大きい");
        }
        else if( a > 200 ){
            printf("Aは200より大きい");
        }
        else if( a > 100 ){
            printf("Aは100より大きい");
        }
        else{
            printf("範疇外");
        }

        return(0);
    }


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  05.Guide  「選択構造:ifのまとめ」
──────────────────────────────────────

これでifの構文については、全て出揃いました。
さて、ここまでをチョコッと整理してみましょう。

    STEP 1. ifの横にある括弧が“真”の時、'{' から '}' までの処理を実行する。
            (省略不可)

    STEP 2. ifが偽の場合で、尚且つ else if の横にある括弧が“真”の時、'{' 
            から '}' までの処理を実行する。
            (省略可)(複数の記述が可)

    STEP 3. ifが偽の場合、elseの'{' から '}' までの処理を実行する。
            (省略可)

if文は一カ所が実行されると、例えば一番上のifが実行された場合、下のelse ifと
elseは飛ばされます。もちろんelse ifが真の場合、他のものは実行されません。と
いうことから、実行される確率の高い物をなるべく上にもって来た方が効率がいい
プログラムとなります。


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  06.Guide  「選択構造:whileと組み合わせて使ってみよう」
──────────────────────────────────────

以下の問題を解いてみましょう。

    Q. 1から100までの数のうち、3で割り切れる数を全て挙げなさい。
    A. 下記のようになります。

        #include<stdio.h>

        int main(void)
        {
            int i;

            i = 1;
            while( i<=100 ){
                if( (i%3) == 0 ){
                    printf("%d ", i);
                }

                i = i + 1;
            }

            return(0);
        }

    ■実行例
        C:\>bcc32 if_sample.c
        Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
        if_sample.c:
        Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
        
        C:\>if_sample
        3 6 9 12 15 18 21 24 27 30 33 36 39 42 45 48 51 54 57 60 63 66 69 72 75 78 81 84
         87 90 93 96 99


ちなみに、% は剰余算を行う演算子です。剰余算とは割り算の余りを算出するものです。
つまり、

    「3で割り切れる」

というのは、

    「3で割った時に、余りが0」

という数のことを指します。
OKでしょか?あえてコメントはつけませんでしたが、理解できましたか?


上のプログラムを理解したら、早速今週の問題に取り掛かりましょう。
今回はちょっと難しいぞ!


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  07.Question  「今週の問題」
──────────────────────────────────────

    Q. 2 〜 1000 までの素数を求めるプログラムを作成せよ

    ■実行例
        C:\>bcc32 sample.c
        Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
        sample.c:
        Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland
        
        C:\>sample
          2   3   5   7  11  13  17  19  23  29  31  37  41  43  47  53  59  61  67  71
         73  79  83  89  97 101 103 107 109 113 127 131 137 139 149 151 157 163 167 173
        179 181 191 193 197 199 211 223 227 229 233 239 241 251 257 263 269 271 277 281
        283 293 307 311 313 317 331 337 347 349 353 359 367 373 379 383 389 397 401 409
        419 421 431 433 439 443 449 457 461 463 467 479 487 491 499 503 509 521 523 541
        547 557 563 569 571 577 587 593 599 601 607 613 617 619 631 641 643 647 653 659
        661 673 677 683 691 701 709 719 727 733 739 743 751 757 761 769 773 787 797 809
        811 821 823 827 829 839 853 857 859 863 877 881 883 887 907 911 919 929 937 941
        947 953 967 971 977 983 991 997

素数とは、

    「n以下の整数で割り切れるかどうかを計算し、一つも割り切れない数」

という数字のことです。
ちなみに、この問題はプログラミングの登竜門的な存在です。その手の勉強をする
と、必ず現れます。プログラマーを目指している方は、ぜひ解いてみてください。



━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                           編    集    後    記
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

先日引越し通知を知人に出して以来、衝撃的な出来事が続いています。
旧友や高校時代の先輩から連絡が絶えず(うれしいことです)、昔を懐かしんでいたと
ころに一通のメールが。

高一の夏休み。ずっと部活で学校に行っていたのですが、その時出合った違う学校の
一つ上の先輩。ほとんど一目ぼれでした(笑) その後色々あり、結局ふられちゃいまし
たが、卒業するまで険悪な時もありましたけが、仲良くしてもらってました。

4年ぶり(かな?)に受け取ったメールには「結婚したよ」の文字が。頭が真っ白にな
るとはこういうことをいうのでしょうか。しばらくボーとメールを見つめた後、そう
いえば色々あったなぁと思い出しながら、キーボードに向かいました。

何だか淋しい気持ちになり、恥ずかしながらチョコッと涙ぐんでいましたが、その文
面から幸せそうな様子が伝わってきて、何だかうれしかったです。そして「おめでと
うございます」と一言そえ、送信ボタンを押したのでした。また一つ、人生の区切り
目を感じました。ただこんなに穏やかな気持ちで、人を祝福するのは初めてです。


こうして生きてると思いもよらないことが次から次へと。もちろんつらい事もたくさ
んあるし、時々後ろを振り返ったり、これで良かったのかと迷うことも多いのですが、
専門学校を退学することを決めたのは、

    「大切な人の前で、胸がはっていられるように」

そのために今自分が納得できることをしているか、ということでした。結局納得が行
かなくて、その時はやめようと決断しました。冷静になるとコッパズカシイこと考え
てたと思いますが、あの時は真剣に生きていたんだと思います。

その時に大切だと思っていた人とは、やはり色々あり、ここ数年連絡を取っていませ
んが、今でも感謝の気持ちで一杯です。今度会うことがあったなら、ありがとうとい
いたいです。

ここしばらく、すっかり忘れていた、そんなことを思い出していました。


■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

                   【 Webプログラミング Code Sample 】

                    発  行 : ichikoro.com
                発行責任者 : 勝部 麻季人
                              < mailto:katsube@ichikoro.com >
                  発行部数 : 1882部(前回)
                 Webサイト : < http://www.ichikoro.com/webp/ >
            お問い合わせ先 : < mailto:mm-webp@ichikoro.com >

                            Powerd by まぐまぐ
    All Right Reserved, CopyRight(C) 2001 Webプログラミング Code Sample
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


コメント

コメントを入力. Wiki文法が有効です:
Y J P T J