C プログラミング (C Programming)

[2020/05/21, H.Aman]

[6] 「配列」サンプルプログラムの解説

[6] 「配列」演習課題(教科書では主に 5 章が対応)

  • 演習 1

    サンプルプログラム 1 (sample1.c) を ex01.c という別の名前のファイルにコピーし, それを編集して次の入出力例のように実行できるプログラムを作りなさい.
    (この問題では,配列の大きさは 100 と直書きしてよい)

    【プログラムの仕様】
    100 個の整数を読み込み, 49 番目,50 番目,51 番目に入力された三つを表示する.

    【入出力例】 (赤字は実行時にキーボードから入力する内容)
    整数を 100 個入力してください:
    62 7 -31 52 ……(中略)…… 197
    49 番目から 51 番目の数は以下の通りです:
    229 -152 521
    ただ,実際に 100 個の整数を入力するのは大変なので, (以前に学習した) 用意されたデータファイル(data1-1.txt)からのリダイレクトを使用する(以下のデータファイルをプログラムと同じフォルダへダウンロードして使いなさい):

    【入出力例】 (赤字は実行時にキーボードから入力する内容)
    a < data1-1.txt
    整数を 100 個入力してください:
    49 番目から 51 番目の数は以下の通りです:
    -67 -264 -208
    確認テスト [6] に連動した問題があります
    演習 1 用データ 1 (data1-1.txt) / 2 (data1-2.txt) / 3 (data1-3.txt) / 4 (data1-4.txt)

  • 演習 2

    サンプルプログラム 2 (sample2.c) を ex02.c という別の名前のファイルにコピーし, それを編集して次の入出力例のように実行できるプログラム作りなさい.

    【プログラムの仕様】
    10 個の整数(-99以上99以下)をいったん配列 a に格納し, その後,逆順で配列 b へコピーする.

    【手順とヒント】
    サンプルプログラム 2 では SIZE を 5 に設定してあるので, まずはこれを 10 に書き換える.
    さらに for 文の中では b[i] = a[i]; を繰り返しているが, この代入部分を書き換えることになる.
    • a[0] の代入先は b の中の一番後ろなので b[SIZE-1] になる.
    • a[1] の代入先は b の後ろから 2 番目なので b[SIZE-2] になる.
    • a[2] の代入先は b の後ろから 3 番目なので b[SIZE-3] になる.
    • ...
    • では,これを一般化して a[i] の代入先は b の後ろから何番目になって,どう書けるか?
    【注意すべきこと】
    プログラムの冒頭部分で
        #define  SIZE  10
    と書くことになるが,それ以外の部分に 10 と直接書いてはいけません(すべて SIZE と書くこと).
    そうしないとマクロを使う意味がなくなってしまいます.
    例えば,下の実行例では「10 個の整数を入力してください:」と表示していますが,これも 10 と直接書くのはダメです.
    %d を使って SIZE の値を表示させるように工夫してください.

    【入出力例】 (赤字は実行時にキーボードから入力する内容)
    10 個の整数を入力してください: 
    97 5 0 -2 81 4 -6 13 -9 8
      a  b
    ------
     97  8
      5 -9
      0 13
     -2 -6
     81  4
      4 81
     -6 -2
     13  0
     -9  5
      8 97

  • 演習 3

    サンプルプログラム 3 (sample3.c) を ex03.c という別の名前のファイルにコピーし, それを編集して次の入出力例のように実行できるプログラム作りなさい.

    【プログラムの仕様】
    動作はサンプルプログラム 3 と基本的に同じだが, 交換は n ≠ m (つまり n != m )である限り続けることにする.

    【手順】
    交換を何回繰り返すかは事前にはわからないので,以下の
    • 「何番目と何番目を交換しますか」と尋ねる部分
    • 交換を実行する部分
    • 交換結果を表示する部分
    というひとまとまりを while で繰り返すとよい.
    ただし,この場合は最低でも 1 回は「何番目と何番目を交換しますか」と尋ねることになるので do - while 文にしておくとよい. (※ while だと,最初に n != m をチェックしてから繰り返しが始まることになるが,1 回目だとまだ n と m を入力していないため)

    【入出力例】 (赤字は実行時にキーボードから入力する内容)
    5 個の整数を入力してください: 
    5 -2 4 13 8
    何番目と何番目を交換しますか:
    2 5
    2 番目と 5 番目を交換した結果:
    5 8 4 13 -2
    何番目と何番目を交換しますか:
    1 4
    1 番目と 4 番目を交換した結果:
    13 8 4 5 -2
    何番目と何番目を交換しますか:
    1 1
    終了します

  • 演習 4

    サンプルプログラム 4 (sample4.c) を ex04.c という別の名前のファイルにコピーし, それを編集して次の入出力例のように実行できるプログラム作りなさい.

    【プログラムの仕様】
    100 人分の成績(0 以上 100 以下の整数)を読み込み, 出席番号順(入力された順)に成績と順位を表示し, 最後に平均点(小数点以下第 1 位まで)を表示する.
    【注意すべきこと】
    プログラムの冒頭部分で
        #define  SIZE  100
    と書くことになるが,それ以外の部分に 100 と直接書いてはいけません(すべて SIZE と書くこと).
    特に,平均点を求めるために 100 で割るという部分は "/100" ではなく "/SIZE" と書くこと.
    プログラムをそのように作っておけば,人数が変わってもすぐに対処できます.

    【入出力例】 (赤字は実行時にキーボードから入力する内容)
    100 人分の成績を入力してください:
    89 48 51 92 51 …… 95
    1 番は 89 点で 2 位
    2 番は 48 点で 5 位
    3 番は 51 点で 3 位
    ・・・・・・
    100 番は 51 点で 3 位
    平均点は 68.2 点でした.
    実際にはデータファイルを使うとよい.
    data4-1.txt を使った場合,平均点は 42.9 点である. (その場合の実行結果はこちら
    確認テスト [6] に連動した問題があります
    演習 4 用データ 1 (data4-1.txt) / 2 (data4-2.txt) / 3 (data4-3.txt) / 4 (data4-4.txt)

余裕のある人は

  • 発展課題 1

    サンプルプログラム 5 (sample5.c) を ex05.c という別の名前のファイルにコピーし, それを編集して次の入出力例のように実行できるプログラム作りなさい.

    【プログラムの仕様】
    行列の演算 2A-B を出力する.

    【入出力例】 (赤字は実行時にキーボードから入力する内容)
    行列 A の各要素を入力してください:
    1 2 3 4
    行列 B の各要素を入力してください:
    2 3 4 5
    
    A =
      1  2
      3  4
    
    B =
      2  3
      4  5
    
    2A - B =
      0  1
      2  3

  • 発展課題 2

    演習 4 で最高点と最低点も出力するように改良せよ. 発展版の方はファイル名を ex04e.c として提出しなさい.

    【ヒント】
    最高点と最低点を記録するための変数をそれぞれ用意する(例えば max と min).
    そして,1 人目の成績(x[0])を仮に最高点,最低点としておき(つまり,max = x[0]; min = x[0]),
    その後の繰り返しの中で,より高い成績が登場した時(max < x[i] の場合)は最高点を書き換える(つまり max = x[i];).
    最低点についても同様である.

  • 発展課題 3

    発展課題 1 での計算を 2A-B ではなく AB (行列の掛け算)とせよ. 発展版の方はファイル名を ex05e.c として提出しなさい.

    【ヒント】
    n 次の正方行列 の掛け算を とする.
    このとき,行列 C の (i,j) 成分は
    で求まる.

    それゆえ,各行列の (i,j) 成分を a[i][j], b[i][j], c[i][j] で表すとすると,
    1. まず,c[i][j] = 0; として初期化しておく.
    2. for 文で k = 0 ~ n-1 について次を繰り返す(合計を求める):
      c[i][j] += a[i][k] * b[k][j];
    これによって c[i][j] を求めることができる.
    ※配列では添字が 0 から始まるので,上の式とは k の値が 1 だけずれている点に注意.

    上の手順はあくまでも 1 個の c[i][j] を求めるだけであり, これを i と j の繰り返しの中に入れることで行列の掛け算を実現できる.
    for 文で i = 0 ~ n-1 について次を繰り返す{
    for 文で j = 0 ~ n-1 について次を繰り返す{
    上述した c[i][j] を求める処理
    }
    }

    【入出力例】 (赤字は実行時にキーボードから入力する内容)
    行列 A の各要素を入力してください:
    1 2 3 4
    行列 B の各要素を入力してください:
    2 3 4 5
    
    A =
      1  2
      3  4
    
    B =
      2  3
      4  5
    
    A B = 
     10 13
     22 29