[ [[高橋のページ:http://tortoise1.math.ryukoku.ac.jp/~takataka/index-j.html]] ]
[ [[プログラミングおよび実習II2006]] ]

*プログラミングおよび実習II 2006年11月24日 [#f77c90c9]

#contents

//&color(#ff0000){工事中};

**準備 [#c2f04eb5]

準備として以下のことを行ってください
-「実習課題提出状況の確認などのためのシステム([[menuコマンド>プログラミングおよび実習II/menu]])」をインストールする
-そこから数当てゲームを呼び出して遊ぶ

**今日のテーマ: 疑似乱数 [#g238d170]

例えば数当てゲームのプログラムを作るとしたら…

+コンピュータがある範囲内の適当な数をでたらめに決める
+人間が思いついた数を入力する
+当たりならそう表示して終了,さもなくば2に戻る

というような手順になるでしょう.
今回は,1.で考えているようなでたらめな数(乱数)をC言語で作り出す方法を取り上げます.ただし,でたらめな数といってもまったくのでたらめというわけではなく,例えば「0から99までの整数」というように何らかのルールに則ったもののことです.

というわけでいきなりですが次のプログラムを作って実行してみましょう.

http://tortoise1.math.ryukoku.ac.jp/~takataka/course2006/prog2/random0.png

このプログラムを実行すると,0から19までの整数が10個表示されます.
以下のようなことをして結果がどうなるか観察してみましょう.

-このプログラムを何回も実行してみる
-9行目の関数 srand() の引数をいろいろ変えてみる
-11行目の数 20 をいろいろ変えてみる

ここで登場した二つの関数 rand() と srand() は,次のようなものです

: rand() | 引数なし.戻り値(int型)は,0以上「ある定められた最大値」以下の整数.
rand()が呼ばれる度に,その内部では,「乱数っぽい数」を生成する漸化式にしたがって,前の値から次の値を計算している.
: srand() | unsigned int型(符号なしの整数)の数ひとつを引数にとり,それをrand()が生成する乱数の「種」とする.戻り値なし.
種が変われば,rand()が返す乱数も変わる.
乱数の種は,rand()が計算する数列の初期値を決めるもの(ただし,「最初にrand()を呼んだときに返される値」 = 「種の値」 というわけではないことに注意).

上記のように,rand()が生成する値は漸化式によって次々計算されるものですから,真の意味での乱数ではなく,「疑似乱数」と呼ばれています.

ちなみに,rand()が生成する疑似乱数の最大値は,stdlib.h 中で RAND_MAX として定義されています.したがって,

 double x;
 
 x = (double)rand() / RAND_MAX;

とかやると,xにはdouble型で0から1までの疑似乱数を代入することができます.

**今日の課題 [#i51a82bb]

***課題1124-A (締切:今日の実習終了時) [#gd107cec]

種と個数を入力したら,その個数分の疑似乱数を出力するプログラムを作成しましょう.
ただし,以下のことに注意して下さい.

-ソースファイルの名前は random.c とする
-種はunsigned int型の変数に入れる.scanf()で読み込むときは,int型なら"%d"やけど,unsigned int型のときは….手持ちの本やウェブなどで調べてみましょう.
-疑似乱数の値は,0から(個数-1)までとする.例えば100個なら,0から99まで.
-以下の実行例に示すように,「種を入力してね」とか「個数は?」というような表示はせず,素っ気なく数字を出力するだけにする(課題Bに示すように,ソートのプログラムにデータを渡せるようにするためです).
#pre{{
$ ./random
35     <== これは,プログラムの出力ではなく自分でキー入力した種の値
10     <== これは,プログラムの出力ではなく自分でキー入力したデータの個数
5
7
3
8
4
1
3
9
4
1
}}

適当な種や個数で正しく動作することを確認したら,チェックを受けてください.


***課題1124-B (締切:次回の実習終了時,締切後チェック対象外)[#d35adf14]

まずは[[このファイル>http://tortoise1.math.ryukoku.ac.jp/~takataka/course2006/prog2/gakunai/sortcheck.c]]を手元に sortcheck.c という名前で保存して,エディタで中身を確認しましょう.
-入力部分は,今までのように「データ件数を入力させてからデータを順次入力させる」のではなく,「いきなりデータが入力されるので,データ件数は自分で数える(ただし最大N件までしか受け取らない)」ようになっています
-sorted() は,何をする関数でしょうか

次に,今まで自分で作ったソースと組み合わせてコンパイル&実行し,適当な値を入力して動作確認しましょう.その際に使うソートの関数は,四つ(単純選択法,バブル,ヒープ,クイック)のうちのいずれかひとつで構いません.

[コンパイルエラーのありがちな原因]
-関数名を間違えてる(sortcheck.cのプロトタイプ宣言と自分の作った関数名を見比べよう)
-グローバル変数nswapの宣言がない,名前が違ってる,など

上記の動作確認ができたら,今度は課題Aのプログラムと組み合わせて,次のように実行してみましょう(課題A,Bの実行形式がそれぞれrandom,sortという名前と仮定してます)
 $ ./random | ./sort
このようにすると,randomの出力が端末画面に表示されるかわりにsortに渡されます(このような実行の仕方については,[[課題1027-C>プログラミングおよび実習II/20061027#pipe]]に解説があります).

動作確認して「正しくソートできたみたいです」となったら,チェックを受けてください.

***課題1124-C (課題1124-A,Bを今日中に提出した人のみ対象のおまけ課題,締切:次回の実習終了時,締切後チェック対象外) [#d5c5c3f8]

[[menuコマンド>プログラミングおよび実習II/menu]]から,数当てゲームを実行できます.これと同じようなゲームのプログラムを作ってみましょう.

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS