情報科学演習
2013.11.06

Back to index page



  1. 本日の作業内容

  2. メンター学習室の開設時間について

    今週は変則的な時間割なので,メンター学習室は明日の木曜日,11/7(木)の18:00-19:00に開設します.場所は同じくこの720教室です.

  3. 前回の小テストについて

    小テストは時間のプレッシャーがかかるので宿題よりもエラーが多くなりますが,今回もたくさん出ました.今後は注意しましょう.

    b1302 b1327 b1336 b1340 b1343 b1364 b1366
    b1078 b1208

    それと,やはり解答用紙を使用していない人がいました.注意しましょう.

    b1254

    以下は問題のある解答の一例です.

            printf("Two numbers: 1 and 1\n");
    

    そこに入る数字は乱数によって作ったもの,ということくらいは推測できませんか?

        if(num1==num2);
            printf("same\n");
        if(num1!=num2);
            printf("different\n");
    

    授業でも説明しましたが,セミコロン( ; )はそれが「文」の終わりということです.ですので,if の行につけてしまうと,そこで if 文は終わりとなって次の処理はもう関係なくなります.

        if(a > b)
    
        printf("different\n\n");
    
        if(a < b)
    
        printf("different\n\n");
    

    ちゃんと予習をしていれば等しくないときの演算子 != くらいは知っていたはずですね.予習をきちんとしましょう.特に,テストのときは.

            printf("Two numbers: %d and %d\n"),a ,b ;
            if( a=b )
    

    ありがちと言っていた比較演算子の == と代入の = の間違いです.たぶんこれからも出てきます.

            printf("Two numbers: num and num2",num ,num2);
    
            if(num==num2)
                    printf("same:%d\n\n");
    

    最後の printf の引数の中に %d が何故か入っています.なんででしょう?

            if(a == b)
                    printf("Two numbers: %d and %d\nsame\n", a, b);
            if(a != b)
                    printf("Two numbers: %d and %d\ndifferent\n", a, b);
    

    上の例は処理自体は間違っているとまでは言えないのですが,冗長です.if の結果に関係無く必ず表示するものは外に出して,1回で済ませましょう.

            int num num';
    

    うっかりミスでしょうか?でもこれでエラーになって採点されなくなるのですから,気をつけましょう.

            
        if(num1 == num2)
            printf("Two number: %d and %d\n" , num1 , num2);
        if(num1 == num2)
            printf("same");
        if(num1 != num2)
            printf("Two number: %d and %d\n" , num1 , num2);
        if(num1 != num2)
            printf("different");
    

    やたらと冗長な処理ですが,もっと簡潔になりますので,じっくり推敲しましょう.

            if(num = num1)
                    printf("same\n");
            if(num != num1)
                    printf("different\n");
    

    これは結構考えさせられる処理です.最初の if 文は中の式が代入になってしまっていて,その段階で変数 num num1 の値は等しくなります.そして,値が1であれば真となるので,same の表示が実行されます.一方,両者とも値が0になったばあいは偽になってしまうので以後の表示はありません.処理の流れを理解するにはいい間違い方かもしれませんが,間違わないのが一番です.

    次からは全て乱数の間違いです.

            int num1 = rand() % 1 + 0,num2 = rand() % 1 + 0;
    

    何故+0が必要なのでしょうか?無駄な演算はプログラムを重くするだけです.止めましょう.

            num = rand() % 1 + 1;
            num2 = rand() % 1 + 1;
    

    これでは1しか出ません.

            a = rand() % 2 + 8;
    

    ???????????????

            num1 = ("%d\n" rand() 1 + 1);
    

    %d は何でしょう?

            int num1 = rand() % 2 + 1;
     

    当り前ですが,これでは出る数は1か2です.

                num1 = rand() % 2 + -1 , num2 = rand() % 2 + -1;
    

    なんでー1?これでは出る数はー1か0です.

    これ以下はインデントの間違いです.過年度生にも多く見られたのが残念です.

    /*      この行以降に解答のプログラムを書くこと        */
    
            #include <stdio.h>
    
            main()
            {
    

    何故全部の行を字下げする?

        if(nama == namb)
        printf("same\n\n");
    

    if 文では処理は字下げします.

    #include <time.h>
    
    main()
    {
        srand((unsigned) time(NULL));
    
            int a = rand() % 2, b = rand() % 2;
    

    揃っていないですね.

            return(0);
            }
    

    最後の閉じ括弧まで油断せずに.

    return(0);
    }
    

    これは毎年よく見られます.その上とも共通しますが,閉じ中括弧の直上に何かが来ることはありません.

  4. 宿題について

    今回はコンパイルエラーは1件だけでした.プログラム中に日本語文字が混ざるというエラーでした.以後は注意してください.

    b1279

    また,解答用紙を使用していないものも1件ありました.こちらも以後注意してください.

    b1369

    以下は例によって問題のあるプログラムの一例です.参考にしてください.

            int num1 = num%2;
            int num2 = num%3;
            int num3 = num%5;
            int num4 = num%7;
            if(num1 == 0)
                    printf("2 ");
            if(num2 == 0)
                    printf("3 ");
            if(num3 == 0)
                    printf("5 ");
            if(num4 == 0)
                    printf("7 ");
    

    わざわざ変数を置く必要はありません.if の条件式のところに演算が入っても構いません.

        if(num2==0||num3==0||num4==0||num5==0)
            printf("Obtained number: %d\n", num1);
        if(num2==0 && num3==0 && num4==0 && num5==0)
            printf("%d has following measure(s): 2 3 5 7\n", num1);
        else if(num2==0 && num3==0 && num4==0)
                    printf("%d has following measure(s): 2 3 5\n", num1);
            else if(num2==0 && num3==0 && num5==0)
                                    printf("%d has following measure(s): 2 3 7\n", num1);
                            else if(num2==0 && num4==0 && num5==0)
                                            printf("%d has following measure(s): 2 5 7\n", num1);
                                    else if(num3==0 && num4==0 && num5==0)
                                            printf("%d has following measure(s): 3 5 7\n",num1);
                                    else if(num2==0 && num3==0)
                                                    printf("%d has following measure(s): 2 3 \n", num1);
                                            else if(num2==0 && num4==0)
                                                                    printf("%d has following measure(s): 2 5\n", num1);
                                                            else if(num2==0 && num5==0)
                                                                            printf("%d has following measure(s): 2 7\n", num1);
                                                                    else if(num3==0
    && num4==0)
                                                                            printf("%d has following measure(s): 3 5\n", num1);
                                                                    else if(num3==0
    && num5==0)
    
    printf("%d has following measure(s): 3 7\n", num1);
                                                                            else if(num4==0 && num5==0)
    
            printf("%d has following measure(s): 5 7\n", num1);
    
            else if(num2==0)
    
                            printf("%d has following measure(s): 2\n", num1);
    
    
                    else if(num3==0)
    
                            printf("%d has following measure(s): 3\n" ,num1);
    
                    else if(num4==0)
    
                                    printf("%d has following measure(s): 5 \n", num1);
    
                            else if(num5==0)
    
                                                    printf("%d has following measure(s): 7\n", num1);
    

    大作ですね.揶揄するのもよくは無いと思いますが,さすがにこんな処理は課題には出しません.ご苦労さまです.

        if(num2+num3+num4+num5==0)
        printf("%d has following measure(s): 2 3 5 7\n" , num1);
        else if(num2+num3+num4==0)
        printf("%d has following measure(s): 2 3 5 \n" , num1);
        else if(num2+num3+num5==0)
        printf("%d has following measure(s): 2 3 7\n" , num1);
        else if(num2+num4+num5==0)
        printf("%d has following measure(s): 2 5 7\n" , num1);
        else if(num3+num4+num5==0)
        printf("%d has following measure(s): 3 5 7\n" , num1);
        else if(num2+num3==0)
        printf("%d has following measure(s): 2 3\n" , num1);
        else if(num2+num4==0)
        printf("%d has following measure(s): 2 5\n" , num1);
        else if(num2+num5==0)
        printf("%d has following measure(s): 2 7\n" , num1);
        else if(num3+num4==0)
        printf("%d has following measure(s): 3 5\n" , num1);
        else if(num3+num5==0)
        printf("%d has following measure(s): 3 7\n" , num1);
        else if(num4+num5==0)
        printf("%d has following measure(s): 5 7\n" , num1);
        else if(num2==0)
        printf("%d has following measure(s): 2\n" , num1);
        else if(num3==0)
        printf("%d has following measure(s): 3\n" , num1);
        else if(num4==0)
        printf("%d has following measure(s): 5\n" , num1);
        else if(num5==0)
        printf("%d has following measure(s): 7\n" , num1);
    

    これも同様ですね.さらにインデントもおかしいですし.このように人間が手作業で苦労して行うことはプログラミングの意味が無いので,絶対にやっちゃだめ!な処理です.

            if(num % 2 == 0){
                    printf("2 ");
                    if(num % 3 == 0)
                            printf("3 ");
                            if(num % 5 == 0)
                                    printf("5 ");
                                    if(num % 7 == 0)
                                            printf("7 ");
            }
            else if(num % 3 == 0){
                    printf("3 ");
                    if(num % 5 == 0)
                            printf("5 ");
                            if(num % 7 == 0)
                                    printf("7 ");
            }
            else if(num % 5 == 0){
                    printf("5 ");
                    if(num % 7 == 0)
                            printf("7 ");
            }
            else if(num % 7 == 0)
                    printf("7 ");
    

    これも同じ.とりあえず,else を使う必要が無いのに使ってしまったという悪い例ですね.

    Obtained number: 18
    18 has following measure(s):23
    

    約数が23になっていますね.何人かこのような表示のミスがありました.

            num=rand()% 100+1 ;
    

    スペースを空ける空けないが統一されていないので,見苦しい書き方になっています.なるべく以下のようにきちんと書くようにしましょう.

    num = rand() % 100 + 1;

            if(a%2==0){printf(" 2");}
            if(a%3==0){printf(" 3");}
            if(a%5==0){printf(" 5");}
            if(a%7==0){printf(" 7");}
    

    間違いでは無いのですが,このような書き方は推奨していません.あまりコンパクトにすると見づらくなります.

        num = rand() % 90 + 10;
    
        num1 = rand() %101;
    
            a=rand()%100;
    

    上記は乱数の発生が間違っている例です.早く乱数に慣れてください.また,分からなければ聞いてください.

            printf("80 has following measure(s):");
    

    必ず80の約数を求めることになってしまっています.

    以下はまたインデントのおかしい例を集めたものです.

            printf("%d has following measure(s): ",a);
                    if(a % 2==0)
                            printf("2");
    

    なぜ,2行目の if が下がるのか?

        if(num1%2==0)
        printf(" 2 ");
            if(num1%3==0)
            printf(" 3 ");
    

    if 文では処理の部分が下がるので,同じレベルの if は同じ位置にないといけません.

        printf(" has following measure(s):");
    
            if(num%2==0)
                printf("%d" ,2);
            if(num%3==0)
                printf("%d" ,3);
        if(num%5==0)
                printf("%d" ,5);
        if(num%7==0)
                printf("%d" ,7);
            printf("\n\n");
            printf("-----------------------------------------------\n");
            return(0);
    

    自由気ままですね.自分勝手過ぎます.

    /*      この行以降に解答のプログラムを書くこと        */
    
            #include <stdio.h>
            #include <stdlib.h>
            #include <time.h>
    
    main()
    {
    

    前回もこれについては指摘したのですが,ヘッダのインクルード部分は字下げしません.

    return(0);
    }
    

    これも前回説明しました.閉じ括弧 } の真上に何かが来ることはありません.

            if(a%2==0)
                    printf(" 2");
             if(a%3==0)
                    printf(" 3");
              if(a%5==0)
                    printf(" 5");
               if(a%7==0)
                    printf(" 7");
    

    勝手なルールを作らないで下さい.

            if(a % 2 == 0){
            printf("2 ");
                                            }
            if(a % 3 == 0){
            printf("3 ");
                                            }
            if(a % 5 == 0){
            printf("5 ");
                                            }
            if(a % 7 == 0){
            printf("7 ");
                                            }
    

    処理の部分が下がっていないのと,変な位置に閉じ括弧を置いています.止めましょう.

  5. 前回の復習

    if 文の基本について学習しました.条 件式に関する重要な概念に真偽の判定がありますので,以下に説明しておきます.

    教科書のp.24にあるように if 文の基本は図1のようになります.

        if(式){    
            文 ;    
        }
    
    

    図1 if 文の構成

    ここで,式の値が「真」か「偽」かによって処理の流れが変わるのが if 文の基本動作ですが,式の値が真もしくは偽とはどういう意味なのか について考えましょう.

    教科書では関係演算子や等価演算子のような「比較演算子」の使用が最初から行 われていますので,括弧の中には比較する式が入るものと思いがちですが,そこ には値さえあれば,何でも動作します.ですので,等価演算子 == の 代わりに間違って代入記号の = を使用してもエラーなく動作します. (処理は間違ってしまいますが.)

    以下のプログラムで,値の真と偽について考えてみましょう.

    #include <stdio.h>
    #include <stdlib.h>
    
    #include <time.h>
    
    main()
    {
        srand((unsigned) time(NULL));
    
        int num = rand() % 3 - 1;
        printf("%d\n", num);
    
        if(num)
            printf("True\n");
    
        return(0);
    }
    

  6. if ~ else

    今回は,もし〜ならば,という条件式にさらに「そうでないならば」という else の処理を追加したプログラムを学習します.実習課題に沿って学習し ていきましょう.

    else を使用するのは重要です.発生した状態に対して,必ず何かの処理を行なう必要がある場合には必ず最後に else を入れるようにしましょう.処理の洩れを防止するのに役立ちます.一方,必ず何かの処理をする訳では無いときには,else を入れないようにしましょう.

    	if(hoge)
    		hogehoge;
    	else
    		hogehogehoge;
    		


    上のようであれば,hogehoge hogehogehoge のどちらかが必ず実行されます.一方,

    	if(hoge)
    		hogehoge;
    	else if(hege)
    		hogehogehoge;
    		


    であれば,hogehoge hogehogehoge も実行されないこともあります.
    注意

    インデント(字下げ)について毎回注意していますが,if 文においても インデントは論理構造を把握するのに重要です.ところが,教科書のインデント の例はあまり良くないので,以下のどちらかのように揃えるようにしましょう.きっと,こ の方が分かりやすいと思います.

        if( hoge ){
            hogehoge ;
            hogehogehoge ;
        }
    
        if( hege )
            hegehege ;
        else
            hegehegehege ;
    
        if( huge )
            hugehuge ;
        else if( hugehugehuge)
            hugehugehugehuge ;
        else if( hage ){
            hagehage ;
            hagehagehage ;
        }
        else
            hige ;
    

        if( hoge ){
            hogehoge ;
            hogehogehoge ;
        }
    
        if( hege )
            hegehege ;
        else
            hegehegehege ;
    
        if( huge )
            hugehuge ;
        else if( hugehugehuge)
                 hugehugehugehuge ;
             else if( hage ){
                      hagehage ;
                      hagehagehage ;
                  }
                  else
                      hige ;
    

  7. 実習

    実習の演習問題は当日ご案内します.

  8. 次回の予習範囲

    教科書のp.35まで予習をしてきてください.

  9. 宿題

    授業の終わりに