情報科学演習
2014.11.05

Back to index page



  1. 本日の作業内容

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

    今週は変則的な時間割なので,メンター学習室は無いと前回の授業の時に言いましたが,理解度の不足している人も結構いるようなので,11/6(木)の18:00-19:00に開設します.場所は同じくこの720教室です.学習面で不安な人は活用してください.

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

    初めての小テストの割には1年生のコンパイルエラーが少なかったんですが,その分提出数も少なくなってしまいました.エラーの無いプログラムを今後も作っていきましょう.さて,以下が採点対象外です.

    コンパイルエラー  b1078 b1137 b1412 b1433

    珍しいミスですが,scanf を使ったもの  b1424

    解答用紙に番号,氏名の記入が無かったもの    b1401

    前回の宿題を間違えて提出したもの     b1478

    以下が問題のある解答の例の一部です.順に見ていきましょう.まずは,乱数の間違いです.それぞれ問題点を指摘しておきました.

        int a = rand() % 90 + 10;
        int b = rand() % 10;       ← 0が出ます.
    
    
            m = rand() % 100;      ← 0から9が出ます
            n = rand() % 10;       ← 0が出ます
    
    
    
            a = rand() % 89 + 10;     ← 99が出ません
            b = rand() % 9 + 1;
    
            int num1 = rand() % 90 + 10;
            int num2 = rand() % 10 + 1;    ← 10が出ます
    
    
            int n=rand()%99+1;     ← 1から9が出ます
            int m=rand()%9+1;
    
    
            a = rand() % 90 + 10;
            b = rand() %  8 +  2;    ← 1が出ません
    

    次に示すのは比較演算子では無く代入になってしまっているもので,必ず1回はやってしまいます.注意しましょう.

            if(a % b = 0)
    

    次は if 文の問題です.

            if(a % b==0) printf("OK!\n");
            else printf("NG\n");
    

    上に示すのは間違いでは無いのですが,このような表記は出来れば止めましょう.

            if(a%b==0)
                    printf("Random numbers: %d and %d --> OK!",a,b);
            else
                    printf("Random numbers: %d and %d --> NG!",a,b);
    

    上の例は教科書に出ているのをそのまま流用したものですが,if の選択と関係ない部分は if の外に出しておきましょう.解答例を参照してください.

            if(i/j==0)
                    printf("Random numbers: %d and %d --> OK!", i, j);
            if(i/j!=0)
                    printf("Random numbers: %d and %d --> NG", i, j);
    

    剰余を忘れた例ですね.困ったら剰余!を常に意識しておきましょう.

    さて,ここからはインデント(字下げ)の悪い例です.きちんと見栄えの良いプログラムをかけるようになりましょう.

    main()
    {
        srand((unsigned) time(NULL));
    
            int num1,num2;
    

            printf("\n-----------------------------\n\n");
    
        return(0);
    }
    

    上2つは前回もしてきました,TAB幅の問題です.コピペの残骸と思われますが,自分では見えないことが多いので注意しましょう.必ず,TABかスペースかを確認しましょう.

        if(a%b==0)
        printf("Random numbers: %d and %d --> OK!\n\n", a,b);
    

    if 文なのに処理が字下げされていません.教科書をよく見ましょう.

    /*                                                    */
     #include <stdio.h>
    
     main()
     {
    

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

    上2つは,これも前回指摘しました.何故,main() 関数を字下げするのでしょうか?

    #include <stdio.h>
    
    main()
            {
                    int a= rand(),b= rand(),c,d;
    

    何故,main() の中括弧 { } 以下を字下げするのでしょうか?

            if(c==0)
              printf("Random numbers: %d and %d --> OK!\n",a,b);
    
    
            if(num1 % num2 == 0)
                printf(" OK! ");
    

    上のものは両方とも字下げ幅が場所で変わってきています.きちんと文字数を揃えましょう.そのためにTABを使用します.

  4. 宿題について

    今回は全クラスでコンパイルエラーなど不備な答案がありませんでした.素晴らしいです.この調子でがんばって行きましょう.

    ただし,処理に関しては問題大有りでした.特に1年生の方にまずい書き方がたくさん見られました.以下に代表的なものを載せておきますので,よく見て以後は注意してください.

    まずは乱数の発生です.

           a = rand() % 67 + 66;    ← 65が出ませんし,132まで出ます
    
            int a = rand() % 57 + 65;  ← 122が出ません
    

    以下は if 文に関するものです.

            if(isupper(a)){
                    printf("My student number: s144099\n\n");
                    printf("ASCII code %d is %c : upper case\n\n", a);
                    printf("-----------------------------\n");
                    }
    
            else if(islower(a)){
                    printf("My student number: s144099\n\n");
                    printf("ASCII code %d is %c : lower case\n\n", a);
                    printf("-----------------------------\n");
                    }
    
            else{
                    printf("My student number: s144099\n\n");
                    printf("ASCII code %d is %c : symbol\n\n", a);
                    printf("-----------------------------\n");
                    }
    

    学生番号やハイフンによるラインは発生した乱数に依存しません.必ず表示させるものです.なので,if 文の処理にすることはおかしいですね.また,2番目の printf には変数の値を入れる%表現が,%d % c と2つあるのに,与えている変数は a 一つだけです.このため,文字の %c の方に表示する値が不定となり,正しく出ません.今回この変数が一つ足らないミスが多くの1年生で見られました.

            if(num >= 65 && num <= 90)
                    printf("ASCII code %d is %c : upper case\n\n", num, num);
    
            if(num >= 97 && num <= 122)
                    printf("ASCII code %d is %c : lower case\n\n", num, num);
    
            if(num >= 91 && num <=96)
                    printf("ASCII code %d is %c : symbol\n\n", num, num);
    

    上のものも結構見られました.出た乱数に対してどれかの表示を必ず行うので,このような場合には else を使ってください.

        if(64<<a&& a<91)
            printf(" ASCII code %d is %c: upper case\n",a,a);
        if(a>96&& a<123)
            printf(" ASCII code %d is %c: lower case\n",a,a);
         else
            printf(" ASCII code %d is %c: symbol\n",a,a);
    

    これは2番目の if に問題があります.ここは else if でないと正しい処理となりません.例えば,65が出ると最初の printf upper case が表示されますが,最後の else にも該当するので,symbol も表示されてしまいます.

            c = a;
    
    
            printf("ASCII code %d is %c  :",a,c);
    

    上のものは何故変数 c が必要なのでしょうか?

            printf("ASCII code %d" , a );
            printf(" is %c" , a );
    

    なぜ printf を2つに分けるのでしょうか?

            if(65 <= a <= 90)
    

    比較演算子は上のような使い方はしません.左側の方だけ判定しますので,これは間違いです.

            i = rand() % 58 + 65;
    

    これは過年度生の解答にあったものですが,変数 i は反復処理で活躍しますので,他では使わないようにしてください.

            printf("ASCII code 69 is %c : ", num);
    

    なぜに69限定?

    以下はいつものようにインデント(字下げ)のおかしいものです.このようなものは見る気が無くなります.

        printf("My student number: s144002 \n\n");
         printf("ASCII code %d is %c :",a);
         if(a >= 97)
            printf("lower case \n\n");
         else if(a >= 91)
            printf("symbol \n\n");
            else if(a >= 65)
            printf("upper case \n\n");
         printf("-----------------------------\n");
        return(0);
    

    自由気ままですね.法則がまったくわかっていません.

            if(m>=65 && m<=90)
            printf("ASCII code %d is %c : upper case\n\n", m);
    

    if 文の処理はTAB1つ分下げてください.

            return(0);
            }
    

    最後の閉じ括弧がインデントされていますね.最後まで気を抜かずに注意してください.

        if(65<=a&a<=90)
          printf("upper case");
    

    最初は4文字分インデントされていますが,次は2文字分になってしまっています.

        printf("ASCII code %d is %c : ",a);
    
            if(a <= 90)
            printf("upper case\n");
    

    なぜ if が下がる?

        if(m < 91)
           printf("ASCII code %d is %c : upper case\n\n", m);
    
         else if(91 <= m <= 96)
             printf("ASCII code %d is %c : symbol \n\n",m);
    
          else if(m > 96)
    

    2番目の if 文の式もおかしいですが,インデントが何故か徐々に右にずれてきています.変です.

        if(65 <= a,a<= 90)
            printf("ASCII code %d is %c : upper case\n",a,a);
                else if(91 <= a,a <= 96)
                    printf("ASCII code %d is %c : symbol\n",a,a);
                        else
                            printf("ASCII code %d is %c : lower case\n",a,a);
    

    これも2番目の if 文の式がおかしいですが,それに加えて,なぜかどんどん右にずれていってしまっています.変です.

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

    毎回注意しているのですが,直りません.なぜ全部を1文字分開けるのですか,45番?

            #include <stdio.h>
            #include <stdlib.h>
            #include <time.h>
    
    main()
            {
            int a;
            srand((unsigned) time(NULL));
            a = rand() % 58 + 65;
    

    こちらも毎回注意しているのに直りません.何故,ヘッダファイルとmain 関数の括弧までインデント,54番?

    main()
            {
    
                    printf("My student number:s144099\n\n");
    
                    srand((unsigned)time(NULL));
    

    こちらもなぜ最初の中括弧からインデント?

            if(m>=91)
                    if(m<97)
                            printf("symbol");
    
            else
                            printf("lower case");
    

    else の処理の printf が下がりすぎ.

            if(a <= 90)
            {
                    printf(" upper case\n\n");
            }
    

    最後にこれは間違いでは無いのですが,if 文の中括弧の位置は開始の方はif と同じ行に書くのが普通です.

  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. 宿題

    授業の終わりに宿題の案内をします.ただ し,問題を見ることができるのは6日以降です.


目次ページに戻る