情報科学演習
2013.01.15

Back to index page



  1. 本日の作業内容

  2. 小テストの結果について

    小テストでは時間の制約のプレッシャーが厳しいのでミスが良く出ます.基本的なものも多く見られましたので,以後は注意してください.

    コンパイルエラーは以下の解答でありました.

            b1202 b1223 b1251 b1255 b1266 b1269 1280
            b1085 b1103
    

    また,コンパイルは通っても,配列の不適切な操作でセグメンテーション違反の警告が出るものもありました.

            b0907 b1034 
    

    解答用紙の不使用も出ました.

           b1260 b1273 b1281 
    

    以下は例によって不適切な処理の例です.

            int a = rand()%12 + 1;
    
            printf("Days of month %d:%d",a,day[a]);
    

    上の例が最も多く見られたもので,教科書の最初,p.53に書かれている先頭の要素の添字が0であることを理解していないときのものです.実習を通してその辺は理解が進んだと思います.

                    a=rand() %11+1;
    
                    printf("Days of month %d:%d\n",a,day[12]);
    

    乱数の発生がまずいのと(これでは12月は絶対出てきません),配列の添字を理解していないことによって生じたミスと思われます.

            int a=rand()% 12+1;
    
            if(a==1,3,5,7,8,10,12)
                    printf("Days of month %d: 31",a);
            if(a==4,6,9,11)
                    printf("Days of month %d: 30",a);
            if(a==2)
                    printf("Days of month %d: 28",a);
    

            for(i=1; i<12;i++){
                    month=rand() % 12 + 1;
                    if(month=1||3||5||7||8||9||12){
                            printf("Days of month %d: 31",month);
                    }
                    if(month=4||6||9||11){
                            printf("Days of month %d: 30",month);
                    }
                    if(month=2){
                            printf("Days of month %d: 28",month);
                    }
            }
    

            if(a==4|a==6|a==9|a==11)
                    printf("30\n\n");
            else if(a==2)
                    printf("28\n\n");
            else
                    printf("31\n\n");
    

    代表的なものを3つ挙げましたが,これは例によって,絶対にやっちゃだめなものです.配列の単元の問題であることをまったく考慮していません.残念ながら0点です.

            for(i=1;i<=1;i++){
                    i  = rand() % 12 + 1;
                    printf("Days of month %d: %d\n\n", i, day[i]);
            }
    

    何のために for 文を使用しているのでしょうか?

  3. 宿題の結果について

    配列が始まってから以下のようにセグメンテーション違反という警告が出ることがありますので,注意してください.配列で取り扱う添字の範囲外の操作を行うと出ることがあります.

    b1247

    以下は問題のある解答の例です.心当たりのある人は以後は気をつけてください.

            int num[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
            int temp[10], mul[10];
    

    まず,1から順に増えていくかけ算の項ですが,このような規則性のあるものに配列を用意する必要は無いですね.また,他にも2つ配列を用意していますが,計算をするのには不要です.変数や配列はなるべく少なくすることを以後は考えてください.

    さらに,配列の名前ですが,temp というのは気温(temperature)を表すために例として用意したものですが,この名前も不適切ですね.

    = 1 + 2 + 6 + 16 + 45 + 48 + 42 + 24 + 18 + 60 = -1209474492
    

    今回,このようにわけのわからない和が出てきた人がたくさんいました.これは和を取る変数(例えば sum )を初期化していないために起こるものです.複合演算子( +=, *=, etc.)を使用するときは,その変数の初期値があるかを必ず確認してください.

            int a[11]= {0,0,0,0,0,0,0,0,0,0,0};
            int i;
    

    前回サイコロの例で余分に1つ要素を用意する配列を紹介しましたが,だからと言っていつも使う必要はありません.無駄なことは止めましょう.

                    j = rand() % 10 + 1;
    

    乱数の生成は相変わらず問題がある人がいます.これは1桁の整数にならないですね.また,このような用途で変数名の i j を使うのは止めましょうと何度も言っていますので,そちらも注意してください.

            int ram[10];
            int i, SUM;
            printf("\nMy student number: s1240**\n\n");
            for(i=0; i<10; i++){
                    ram[i] = rand() % 9 + 1;
                    printf("%d ", ram[i]);
            }
            printf("\n");
            for(i=0; i<10; i++){
                    printf("%d*%d", ram[i], i+1);
                    if(i<9)
                            printf(" + ");
            }
            printf("\n= ");
            for(i=0; i<10; i++){
            printf("%d", ram[i] * (i+1));
                    if(i<9)
                            printf(" + ");
                            SUM += ram[i] * (i+1);
            }
            printf(" = %d", SUM);
            printf("\n\n-----------------------------------\n");
            return(0);
    

    上のプログラムは間違っている部分があるのですが,これとそっくり同じものが相当な数出ています.その人達は,おそらく単位は取れないと思いますので,いますぐ反省してきちんと学習してください.

            for(i = 0 ; i <= 9 ; i = i ++){
    

    これは過年度生のものですが,以前からこのように for 文の式3のところをこのように書く人がいます.これは,教室以外の実行環境では無限ループになるので,以後は気を付けてください.単純に i++ と書くだけでいいはずなのに,どうしてこのように書くのかが以前からわかりませんでした.

  4. 前回の復習

    配列を扱いました.配列は添字(インデックス)を使って中の値を参照するもので すが,その添字は記号を利用した数式でも構いません.そのため,for 文などと組み合わせて,たくさんの値を一度に代入したり,計算した りすることが可能です.これが配列の便利なところなので,今後も反復処 理と組み合わせて利用する実習課題を行っています.

  5. 2次元配列

    教科書p.54の図5.3にあるように2次元の配列を用意すると,マトリックス状にデー タを格納できます.これを利用して,表計算のようなことも出来ます.例えば, 次のような配列があるとします.

        ary[3][3] = {{11, 12, 13}, {21, 22, 23}, {31, 32, 33}}
    

    要素は例えば,ary[0][1] は12ですし,ary[2][0] は31です.

    このとき,ふたつ目のインデックス(添字)が1に関する和を取ると,12+22+32の 足し算となります.これがデータを行と列に並べた場合の列に関する和となりま す.

    111213
    212223一つ目の添字が1のものはこの行ary[1][j]
    313233
    2つ目の添字が1のものはこの列
    ary[i][1]

    また,マトリックス的なものでは無い多次元配列の使い方としては,前回説明し た温度測定の場合でもあります.1次元の配列だと,1日の温度のデータが格納で きるだけですが,次元を上げていくと次のようにも使えます.

    次元補足
    2 temp[15][0]
    temp[16][14]
    15日午前0時の気温
    16日午後2時の気温
    3 temp[1][15][0]
    temp[2][1][15]
    1月15日午前0時の気温
    2月1日午後3時の気温
    4 temp[12][2][1][16]
    temp[13][1][15][0]
    2012年2月1日午後4時の気温
    2013年1月15日午前0時の気温

    このように添字を使用すれば,後から値を読み出すときに変数を使用して簡単に 出来ます.

    	    year = 13;
    	    month = 1;
    	    date = 15;
    	    hour = 0;
    
    	    printf("%d\n", temp[year][month][date][hour]);
    

  6. 実習

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

  7. 次回の予習範囲

    教科書のp.66-70を予習してきてください.

  8. 宿題

    授業の終わりに宿題の案内をします.ただし,問題を見ることができるのは16日以降です.レポート提出システムから閲覧してください.

    すみません.宿題の説明文に足らない情報がありました.修正してアップロードしているので,もう一度問題を良く見てください.


目次ページに戻る