情報科学演習
2016.11.14

Back to index page



  1. 本日の作業内容

  2. 前回の宿題の結果について

    過年度生の方にコンパイルエラーがありました.気をつけてください.また,解答用紙を使っていないものが相変わらず出されています.こちらも何度も注意をしていることなので,以後は気をつけてください.最初から解答用紙に記入すればこのような問題は起こらないはずなのですが...

    コンパイルエラー: b1209 b1545
    解答用紙不使用: b1556

    以下は問題のある解答の例です.参考にしてください.

            a = rand() % 12 - 6;
    

    まだ乱数の範囲がよくわかっていない人がいます.12で割った余りの最大値は11ですから,それから6を引くと5です.この乱数では6が出ません.自分で実際に確認してないのでしょうか?

            a=rand()%7-6;
            b=rand()%7-6;
    

    こちらは意味不明ですね.何なんでしょうか?

            if(x<=1 && x>= -1 && y<=1 && y>= -1) 
                    printf("1st shot: (%d, %d) -> Point:%d\n",x,y,xy=10);
            else if(x<=2 && x>= -2 && y<=2 && y>= -2)
                    printf("1st shot: (%d, %d) -> Point:%d\n",x,y,xy=8);
            else if(x<=3 && x>= -3 && y<=3 && y>= -3)
                    printf("1st shot: (%d, %d) -> Point:%d\n",x,y,xy=6);
            else if(x<=4 && x>= -4 && y<=4 && y>= -4)
                    printf("1st shot: (%d, %d) -> Point:%d\n",x,y,xy=4);
            else if(x<=5 && x>= -5 && y<=5 && y>= -5)
                    printf("1st shot: (%d, %d) -> Point:%d\n",x,y,xy=2);
            else
                    printf("1st shot: (%d, %d) -> Point:%d\n",x,y,xy=0);
    

    こんな面倒なことは宿題に出しません.また,こういうことをやっている人は結局判定を間違っています.

            if(c == 0 || c == 1)
                    printf("%d\n", d = 10);
            else if(c == 2 || c == 4)
                    printf("%d\n", d = 8);
            else if(c == 5 || c == 8 || c == 9)
                    printf("%d\n", d = 6);
            else if(c == 10 || c == 13 || c == 16)
                    printf("%d\n", d = 4);
            else if(c == 17 || c == 18 || c == 20 || c == 25)
                    printf("%d\n", d = 2);
            else
                    printf("%d\n", d = 0);
    

    同じく面倒なことをやっています.

    今回の宿題は円の内側か外側かを判断するだけなのですがねえ.1年生はつい一年前まである点が原点を中心とする円の内側か外側かの判定を当たり前にやっていたはずですが,どうしたんでしょうね.

            if(c<=1)
                    printf("10\n",g=10);
            else if(c<=4)
                    printf("8\n",g=8);
            else if(c<=9)
                    printf("6\n",g=6);
            else if(c<=16)
                    printf("4\n",g=4);
            else if(c<=25)
                    printf("2\n",g=2);
            else
                    printf("0\n");
    

    この上のような書き方を結構多くの1年生がやっていたのですが,どこでそんな変なことを覚えたんでしょうか?まず, printf というのは画面出力のための命令であって,代入するために用意するものではありません.最初の頃の宿題ではこのように意味のない変数が printf 文に含まれていた場合には0点としました.今回は減点で済ましていますが,続くようだと考えます.また,最後の else のところには変数 g の値が無いので,後のほうで間違った答えとなります.

        if(a*a + b*b <= 1){
            x = 10;
            printf("%d",x);
        }
        else if((a*a + b*b > 1) && (a*a + b*b <= 4)){
            x = 8;
            printf("%d",x);
        }
        else if((a*a + b*b > 4) && (a*a + b*b <= 9)){
            x = 6;
            printf("%d",x);
        }
        else if((a*a + b*b > 9) && (a*a + b*b <= 16)){
            x = 4;
            printf("%d",x);
        }
        else if((a*a + b*b > 16) && (a*a + b*b <= 25)){
            x = 2;
            printf("%d",x);
        }
        else{
            x = 0;
            printf("%d",x);
        }
    

    if による判定は昇順か降順に並べておけば上の例のような論理演算子は不要であることを前の宿題で説明しました.

            if(e<=9)
                    c = 6;
                    
            else if(e<=16)
                    c = 4;
            
            else if(e<=25)
                    c = 2;
                    
            else if(e<=1)
                    c = 10;
            
            else if(e<=4)
                    c = 8;
            
                    else
                            c = 0;
    

    こんないい加減な順番で並べてはダメです.

            if(a<=1)
                    shot1=10;
                    
            else if(a<=4)
                    shot1=8;
                    
            else if(a<=9)
                    shot1=6;
    
            else if(a<=16)
                    shot1=4;
            
            else if(a<=25)
                    shot1=2;
    
            else
                    shot1-0;
    

    最後の else のところで間違って入力しています.こういうのは自分で何度も実行して確かめればおかしいことに気づくはずです.

    以後はインデント等のおかしいものです.

    #include        <stdio.h>
    #include        <stdlib.h>
    #include        <time.h>
    
    main()
    {
                    srand((unsigned)        time(NULL));
    
                    int     a       =       rand()  %       13-6,
                            b       =       rand()  %       13-6,
                            c       =       rand()  %       13-6,
                            d       =       rand()  %       13-6,
                            f,
                            num     ,
    

    前回も言いましたが,スペースの代わりにTABが入っています.見づらくてたまりません.次回以降は採点しません.

           if(c<=1){
                    printf("10\n");
                    g=10;}
             else if(c<=4){          
                     printf("8\n");
                     g=8;}
              else if(c<=9){
                      printf("6\n");
                      g=6;}
                    else if(c<=16){
                       printf("4\n");
                       g=4;}
                     else if(c<=25){
                        printf("2\n");
                        g=2;}
                      else{
                         printf("0\n");
                         g=0;}
    

    どういう根拠のインデントなのでしょうか?

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
            main()
            {
            srand((unsigned) time(NULL));
    

    これも以前にも注意しました. main は下がりません!

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

    最後の return まで気を抜かない!

            printf("2st shot:(%d,%d)->Point:%d\n",a,b,d);
            printf("Total point:%d\n",c+d);
    
        return(0);
    }
    

    これも以前説明したのですが,Webテキストなどから貼り付けたものと自分の入力したものが混在している時にこのような間違いになることがあります.自分でTABは確認しましょう.

  3. 前回の復習

    • else

      else の処理について実習を行いました.if だけではやりづ らい2者択一の処理も else を使ってすっきりと実現できます. 今後も必要に応じて使ってください.

    • 論理演算式

      if 文の判別式の部分で論理演算の間違いをしている人が実習中に結構 見られました.以下のようなものは間違いですので,注意してください.

      	    if(a == 1, 2, 3)
      
      	    if(a == 1 || 2 || 3)
      

    • 除算と剰余算の上手な使い方

      トランプの課題を行いましたが,以下のように考えると if 文がすっきりしますので,適宜活用してください.トランプについては配列を学習したらまた扱います.

               0  1  2  3  4  5  6  7  8  9 10 11 12  <-- 13で割ったら商が0 Spades
              13 14 15 16 17 18 19 20 21 22 23 24 25  <-- 13で割ったら商が1 Hearts
              26 27 28 29 30 31 32 33 34 35 36 37 38  <-- 13で割ったら商が2  Diamonds
              39 40 41 42 43 44 45 46 47 48 49 50 51  <-- 13で割ったら商が3  Clubs
      13で割った剰余   0  1  2  3  4  5  6  7  8  9 10 11 12
                       A  2  3  4  5  6  7  8  9 10  J  Q  K
      				 
      上のように処理をするために,発生させる乱数を0〜51としています.1〜52でも同様のことが出来ますが,右の商による分別を行うためには1引かなければなりません.

      また,いずれ配列が出てきたときには,配列の要素の循環のために0から始まる数にしておく方が楽になることがわかります.
  4. switch

    switch 文は規則性の無い選択処理の際に使用すると便利です.が,み なさんの場合は if 文を使用してすっきりと書けるものまで switch を使ってしまう例がこれまで見られます.ですので,この授 業では本日の実習以外では switch 文を使用する処理は使わない と思ってください.すみません.

    正確には,if else 文と swith 文では分岐の動作が違います.if else 文では条件がたくさんあるとき,上から順番に if の式の真偽判定を順に行っていきます.下の方にある条件に合致するとしたら,それまで上でずっと続けられた判定は時間の無駄になってしまいます.一方,switch 文の場合は一発で該当する case 句に飛びますので,負荷の低減になります.ですので,分岐が多い場合には switch 文を使用するのが適切と言えます.
    注意

    教科書のp.35に switch 文の基本構成を示した図がありますが,ここで case の次にある「定数式」というのがわかりづらいかと思います.教科書にもあるようにこれは「整数型」か「文字型」で無いといけないのですが,教科書の例題3.7は「文字型」の例となっており,そのため演算記号の両側に文字を記述するための記号である引用符 ' ' がついています.「整数型」の場合には当然ですが引用符はあってはいけません.

    また,定数式ということで,変数や変数を含む式,また,文字列が来ることはできません. 1 + 1 のように変数を含まない式は可能ですが,使うことは無いでしょう.文字は教科書のp.143のASCIIコード表にあるように数値として計算機の内部で処理されます.そのように,単純な数値を値に持つものが定数式です.先ほどの 1 + 1 は2という数値になりますし,文字の '+' であればコード表にあるように10進法で43という数値で表されるので switch 文の中で使用できるのです.

    最後に,定数式ですが,比較演算子,等価演算子,論理演算子などは使用できません.数値の範囲や大小などを入れることはできないということです.あくまで,ある「値」になっているかどうかだけを判断します.

  5. 実習

    実習の演習問題予習分はこれです.

  6. 次回の予習範囲

    教科書のp.41まで予習をしてきてください.教科書のp.38にある復号演算子は特 に重要です.必ず予習してきてください.

    また,次回は for 文に関する小テストを実施しますので,予習は特に念入りにお願いします.

  7. 宿題

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


目次ページに戻る