|
[14] 構造体 演習課題
〆切は 7/17(金)14:10 です.
-
演習 1
サンプルプログラム③(sample3.cです.sample1.c ではありません)
を別名(ex01.c)にコピーし,
これを書き換えて
以下の手順に従って
複数の有理数の合計を出力するようにしなさい.
なお,入力の終わりは「分子が 0 の有理数」を入力した時点とする.
【手順】(すべて main 関数内で実行)
-
有理数 sum を用意し,0 に初期化する(分子を 0,分母を 1 とする).
sum.a = 0; sum.b = 1;
-
以下の i, ii, iii を無限ループ
while(1){ ... }
で繰り返す.
-
有理数 x を読み込む.
-
もし
x.a == 0
ならば break; を実行して無限ループから脱出する.
-
sum + x を改めて sum に代入する.
有理数の足し算は関数 add を使う必要があることに注意(このまま + と書いても動きません).
-
sum の値を出力する.
入出力例(キーボードからの入力は赤色)
有理数の分子と分母を入力してください:1 2
有理数の分子と分母を入力してください:3 4
有理数の分子と分母を入力してください:5 6
有理数の分子と分母を入力してください:7 8
有理数の分子と分母を入力してください:0 0
入力された有理数の合計 = 71/24
上の入出力例は以下の結果を示している:
-
演習 2
まず,このプログラム(ex02.c)をダウンロードしなさい.
これはサンプルプログラム③を以下の点で変更したものとなっている.
ただし,関数 sub と div は未完成なので,これらを完成させなさい.
【サンプルプログラム③からの変更点】
-
最大公約数を求める関数 gcd において,
引数 a, b が負の場合でも対応できるよう変更(変更済み).
-
有理数の引き算を行うための関数
sub
を新しく作成(未完成).
-
有理数の掛け算を行うための関数 mul を新しく作成(作成済み).
-
有理数の割り算を行うための関数
div
を新しく作成(未完成).
-
main 関数で,有理数の足し算以外の計算も行う(関数を呼出す)ように変更(変更済み).
-
計算式の表示を行うための関数 print_expression を新しく作成(作成済み).
入出力例(キーボードからの入力は赤色)
有理数 x の分子と分母を入力してください:6 8
有理数 y の分子と分母を入力してください:8 16
3/4 + 1/2 = 5/4
3/4 - 1/2 = 1/4
3/4 * 1/2 = 3/8
3/4 / 1/2 = 3/2
-
演習 3
まず,このプログラム(ex03.c)をダウンロードしなさい.
このプログラムはサンプルプログラム④
を次の点で変更したものとなっている.
ただし,関数 print_neighbor は未完成なので,これを完成させなさい(現時点では,全員分の名前が表示されるだけになっている).
【サンプルプログラム④からの変更点】
-
マクロ MAX を 6 に変更(変更済み).
-
プレイヤー情報をデータファイルから読み込むように変更(変更済み).
-
近くにいるプレイヤーを表示するための関数 print_neighbor を新しく作成(未完成)
-
main 関数において,print_neighbor を呼出すように変更(変更済み).
【関数 print_neighbor の仕様】
-
引数 a[] :全プレイヤーの情報が入った配列
-
引数 k :注目するプレイヤーの配列内での添字
-
機能: a[k]
に該当するプレイヤーの近くにいるプレイヤーの名前を表示する(実行例を参照のこと).
ただし,ここでいう「近くにいる」とは,両者の x 座標の差を dx として, y 座標の差を dy としたとき,
dx*dx + dy*dy < 10 が成立する場合をいう.
-
注意点: a[k] 自身(本人)を近くにいるプレイヤーとして表示してはいけません.
入出力例(キーボードからの入力は赤色)
データファイル名を入力してください:data3.txt
データファイルから 6 人分のデータを読み込みました.
aman さんの近くにいる人(たち):shiro さん;
taro さんの近くにいる人(たち):saburo さん; goro さん;
jiro さんの近くにいる人(たち):
saburo さんの近くにいる人(たち):taro さん; goro さん;
shiro さんの近くにいる人(たち):aman さん;
goro さんの近くにいる人(たち):taro さん; saburo さん;
(上の実行で使っている data3.txt の内容は以下の通り:ここからダウンロードしなさい)
aman 8 8
taro 2 3
jiro 2 8
saburo 3 5
shiro 9 9
goro 3 3
-
演習 4
まず,このプログラム(ex04.c)をダウンロードしなさい.
このプログラムはサンプルプログラム④
をもとにして作った簡単なゲームになっている.
このゲームは,以下に示す仕様のもと,迫ってくる敵(ハンター)から逃げ切ることが目的である.
【ゲームの仕様】 (ただし,WIDTH, HEIGHT, MAX はいずれもマクロで,順番に 3, 3, 5 と定義されている)
-
プレイヤーとハンターは,x-y 座標上のいずれかの点(ただし,x, y とも整数)に位置する.
-
プレイヤーもハンターも,動ける範囲は座標 (0,0) を左下,座標 (WIDTH-1, HEIGHT-1) を右上とした四角形の中に限定されている.
-
プレイヤーもハンターも,1 ターン毎に上下左右のいずれかの方向に 1 マスだけ移動できる.
-
プレイヤーが先手で,それに応じてハンターも動いてくる.
-
ハンターに捕まる(位置が重なる)ことなく MAX ターンが過ぎれば,プレイヤーの勝ちである.
-
もしも動けない方向へ移動しようとした場合(例えば,座標 (0,0) にいて,左に移動しようとした場合)は,
そのターンは移動できずにそこに待機となる.
このプログラムでは,プレイヤーを移動させる関数 move が未完成になっている.
(現状では「その方向に逃げることはできません」と表示するだけで何もしていない)
以下の仕様に従って,この関数を完成させなさい.
なお,関数 move の中では講義で説明した 「p->x」という書き方を用いること.
【関数 move の仕様】
-
引数 p :プレイヤーの情報が入った構造体へのポインタ
-
引数 dx, dy :プレイヤーを移動させる量
-
機能: ポインタ p が参照しているプレイヤー(構造体)の x, y 座標を更新する.
更新する量は dx, dy であり,それぞれ x 座標を dx だけ, y 座標を dy だけ増やす.
(なお,dx, dy は負の場合もある)
-
注意点:
移動できる範囲には制限があるので,移動できない場合は
「その方向には逃げることができません」
とだけ表示して,実際は移動させない.
入出力例(キーボードからの入力は赤色)
[Y] はあなた,[H] はハンターの位置を表している.
あなたの名前を入力してください:aman
aman : (0,0)
hunter : (2,2)
+ --- + ---[H]
| | |
| | |
+ --- + --- +
| | |
| | |
[Y]--- + --- +
[1 回目]
どの方向に逃げますか?(1:上,2:右,3:下,4:左)
> 1
aman : (0,1)
hunter : (1,2)
+ ---[H]--- +
| | |
| | |
[Y]--- + --- +
| | |
| | |
+ --- + --- +
[2 回目]
どの方向に逃げますか?(1:上,2:右,3:下,4:左)
> 3
aman : (0,0)
hunter : (1,1)
+ --- + --- +
| | |
| | |
+ ---[H]--- +
| | |
| | |
[Y]--- + --- +
[3 回目]
どの方向に逃げますか?(1:上,2:右,3:下,4:左)
> 2
aman : (1,0)
hunter : (1,0)
+ --- + --- +
| | |
| | |
+ --- + --- +
| | |
| | |
+ ---(X)--- +
aman は捕まってしまいました... GAME OVER
(※
実は,1 回だけわざと逃げることのできない方向を選んで,1 手だけ無駄にするとクリアできます.)
余裕のある人は
-
演習 2【発展課題】
演習 2 で作ったプログラムを別名(ex02e.c)にコピーし,次のように改良しなさい:
分子または分母に負の数が含まれてもよいように,関数 reduce を改良しなさい.
つまり,関数 reduce を使って約分する際に,
有理数として負になる場合は必ず分子の値を負にして,分母は常に正となるようにしなさい.
(例)「5/-10」→
「-1/2」
(例)
「-15/-10」→
「3/2」
入出力例(キーボードからの入力は赤色)
有理数 x の分子と分母を入力してください:2 -3
有理数 y の分子と分母を入力してください:-10 -4
-2/3 + 5/2 = 11/6
-2/3 - 5/2 = -19/6
-2/3 * 5/2 = -5/3
-2/3 / 5/2 = -4/15
-
演習 3【発展課題】
演習 3 で作ったプログラムを別名(ex03e.c)にコピーし,次のように変更しなさい:
最も遠い人の名前だけを表示しなさい(与えられるデータでは,一番遠い人が 1 人に決まると仮定してよい).
距離は dx*dx + dy*dy で求まるのでこれを使うこと(正しくは距離の 2 乗だが,最も遠い人を決定するだけならこれを使っても支障はない).
入出力例(キーボードからの入力は赤色)
データファイル名を入力してください:data3.txt
データファイルから 6 人分のデータを読み込みました.
aman さんから最も遠くにいる人:taro さん
taro さんから最も遠くにいる人:shiro さん
jiro さんから最も遠くにいる人:shiro さん
saburo さんから最も遠くにいる人:shiro さん
shiro さんから最も遠くにいる人:taro さん
goro さんから最も遠くにいる人:shiro さん
|