情報科学演習
2012.01.30

Back to index page



  1. 本日の作業内容

  2. 小テストについて

    授業の最初に配列に関する小テストを実施します.解答用紙は閲覧可能ですので, 事前に準備をしておいてください.

    解答用紙

    提出方法

    以下のようなメールを作成し,送信してください.

    宛先
    課題の提出専用なので,質問をこのアドレスに送らないでください.
    件名test_c6_120130_s1140** C6クラス
    test_c7_120130_s1140**C7クラス
    本文学生番号と氏名を必ず記入すること
    上記記載が署名にある人は署名のみでも可
    添付ファイル名test_c6_120130_s1140**.cC6クラス
    test_c7_120130_s1140**.cC7クラス

  3. 宿題の結果について

    今回はいつもと違って,2年生よりも1年生の方が全般的に成績が良かったようで す.理由はメンター学習室で処理の仕方のヒントをもらったためと思われます. 宿題のページに書いていたように,今回は処理に if 文を使用しない ことが条件です.そのための考え方を以下に簡単に説明しますので,参考にして ください.

    配列と反復処理の組合せに関しては,添字の動きをよく理解することが大事です. そのためには,頭で考えるだけでは無くメモに実際に書いてみることを以前から お薦めしています.
    では,今回の課題で表示する入れ換えた部分ですが,添字だけを抜き出すと以下 のようになっていることに気づきます.

    [0][0] [1][1] [0][2] [1][3] [0][4]
    [1][0] [0][1] [1][2] [0][3] [1][4]
    
    一つ目の添字は01010,10101のように0と1が交互にきています.これは剰余で考 えることが出来ますが,例えば,01234という数字をそれぞれ2で割った余りは 01010ですし,12345を2で割った余りは10101です.そこから解答例のように変数 i に変数 j を足して2で割った余りを取ることで実現でき ます.

    では,いつものように問題のある解答の例を以下に示しておきますので,今後の 参考にしてください.

            for(i=0; i<=0; i++){
                    for(j=0; j<=4; j++)
                            printf("%2d ", ary[j%2][j]);
                    printf("\n");
    
            }
            for(i=0; i<=0; i++){
                    for(j=0; j<=4; j++)
                            printf("%2d ", ary[(j+1)%2][j]);
                    printf("\n");
    
            }
    

    for 文を2つに分けて処理しています.ちょっとごまかしている解答で すね.

            tmp = ary[0][1];
            ary[0][1] = ary[1][1];
            ary[1][1] = tmp;
    

    配列の要素を入れ換えるのではなく,表示を入れ換えるだけです.なので,この ような方法は駄目です.

            for(i=0;i<2;i++){
                    for(j=0;j<5;j++){
                            if(j%2==1){
                                    b=a[i][j];
                                    a[0][j]=a[1][j];
                                    a[1][j]=b;
                            }
                            printf("%2d ",a[i][j]);
                    }
                    printf("\n");
            }
    

    if 文を使用しないこと.

            for(i = 0; i <= 1; i++){
                    for(j = 0; j <= 4; j++){
                    a = rand() % 90 + 10;
                    ary[i][j] = a;
                    printf("%d ", ary[i][j]);
                    }
                    printf("\n");
            }
    

    相変わらずインデントのおかしいものが散見されます.注意して下さい.

            printf("%d %d %d %d %d \n",ary[0][0],ary[1][1],ary[0][2],ary[1][3],ary[0][4]);
            printf("%d %d %d %d %d \n\n",ary[1][0],ary[0][1],ary[1][2],ary[0][3],ary[1][4]);
    

    今回もありました.絶対にやっちゃダメ!な解答です.

  4. 前回の復習

    前回の実習課題iの理解が難しい人が多く見られました.単純な値の入 れ換えは配列以前に変数を使用しても実習していたはずなので,よく確認してく ださい.なお,要素を入れ換えるのではなく,ただ表示を逆にしていただけで済 ませていた人が多くいたと推測されます.その場合,課題の ii がまっ たく出来ないという状態になるはずなので,もう一度入れ換えの方法の確認をし て下さい.

    その後の課題iiですが,配列の要素の 参照と値の入れ換えの組合せがややこしいので,処理に関して混乱している様子 でした.そこで,授業中に説明したのですが,以下のように手作 業で for ループを動かしてみることをお薦めします.メモなどに実際 の変数や配列の要素の値の変遷を書いていくと,プログラミングの参考になりま すので,今後もこのような手法も一つだと思って活用してください.

    問題

    例題5.3を参考に,配列の要素の値を大きい順に並べ替える操作を行なうプログ ラムを考える.100以下の正の整数を乱数で5つ発生させ,それらを大きい順に並 べ変えよ.

     85  48  72  41  51
     85  72  51  48  41
    

    例えば,上の例のように現在配列 ary に順に85,48,72,41,51が入っ ているとします.このとき,配列の要素は以下の表のようになっています.

    添字01234
    要素8548724151

    まず,先頭の要素(0番目)と次(1番目)の要素,2番目の要素と順に比較し,もし 後の方が大きい場合には値を入れ換える操作を行うものとします.そのとき,比 較の操作は

        if(ary[i] < ary[j])
    

    のように2重ループの変数 i j を使用して行うものとし ます.そのとき, i j の値と配列の要素がどのように変 化していくのかを順に示すと,以下のようになります.

    変数ij添字 01234操作
    01要素8548724151そのまま
    02要素8548724151そのまま
    03要素 8548724151そのまま
    04要素 8548724151そのまま
    一巡目終了
    12要素8572484151入れ換え
    13要素8572484151そのまま
    14要素8572484151そのまま
    二巡目終了
    23要素8572484151そのまま
    24要素8572514148入れ換え
    三巡目終了
    34要素8572514841入れ換え
    四巡目終了

    このように i j が変化していくようなループを作れば完 了です.内側のループの繰り返しの回数が段々と減っているのは,次のように表 示するプログラムと同じです.

    ****
    ***
    **
    *
    

  5. 文字列配列

    C言語では文字列(abc shimane のような文字の組)は配列 となります.それぞれの文字は配列の要素として利用可能です.文字列に関して は以下のような注意が必要です.

    • ヌル文字

      文字列の最後には文字列の終わりを意味するヌル文字 \0 があります. これは目には見えませんが,必ず付いているものです.ですので,配列の要素の 個数は文字数+1にしておく必要があります.

      実際にNULL文字が存在するのかは以下のようなプログラムで確認することが出来 ます.

          char str[2] = "1";
      
          printf("%d %d\n", str[0], str[1]);
      

    • 文字としての数字

      見た目には区別しにくいですが,char 型で定義すると数字も文字にな り,四則演算はできなくなります.注意してください.次の配列は数値です.

          int ary[2] = {1, 2};
      
          printf("%d\n", ary[0]+ary[1]);
      

      しかし,次のものは文字なので,計算には使用できません.

          char str[3] = {'1', '2', '\0'};
      
          printf("%d\n", str[0]+str[1]);
      

    • static 宣言

      教科書のp.59からは初期化のところで,auto (省略可)と static の宣言の話が出てきます.この授業の範囲では auto で構 いませんので,特別に宣言することは不要です.

    • %s %c

      教科書では配列の要素としての文字列を printf を用いて出力する際 に %s を使用しています.教科書のp.21にあるように,%s は「文字列」を表示させるものです.一方,文字列の中の「一文字」を出力する 際には %c を使用します.この違いに注意してください.本日の実習 では,主として %c を使用します.

  6. 実習

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

  7. 次回の予習範囲

    次回はこれまでの総復習です.特別の予習範囲はありませんが,これまで分かっ ていない部分をしっかり把握してください.

  8. 宿題

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


目次ページに戻る