Download presentation
Presentation is loading. Please wait.
Published byかずただ みやまる Modified 約 8 年前
1
コンピュータ基礎実験 第9 回 コンピュータープログラミン グ ( C 言語)(7) 1.繰り返し処理、配列(復 習) 2.乱数
2
繰り返し処理(復習) コンピュータでは、少しずつ条件を変えなが ら同じ処理を繰り返す状況がよくでてきます。 C 言語では、繰り返し処理を行うために「 for 文」、「 while 文」が用意されています。 「 for 文」 : 「初期値」を与え、与えられた条件を 満たしている間、同じ処理を繰り返す 「 while 文」 : 特に初期値を設定せず、与えられた 条件を満たしている間、同じ処理を繰り返す
3
繰り返し処理 for ( 初期値の式 ; 条件式 ; ループの終わりに実行する式 ){ 文 } For 文 While 文 While 文 do ~ while 文 (初回も条件チェック) (初回は条件 チェック無) while ( 式 ){ 文 } do{ 文 } while ( 式 );
4
前回 EX8-6: 自然対数の底 e(=2.71828…) は次の無限級数で与えられる。 上の無限級数の初めの n 項目までを計算するプログラムを作成せよ。 このとき、小数点以下 10 桁 (”%.10f”) で出力せよ。 (→ EX8-6.c) WEB 上で e の値を調べ、 n=1, 5, 10, 20 について自分のプログラムで 計算し、収束する様子を確認せよ。 (double 変数を使用せよ ) 注 ) 「 0!= 」 1 です。 4 前回課題 EX8-6 : EX8-6.c
5
前回課題 EX8-6 解答例 5 #include int main(void) { int i,n; double x=1, sum=0; scanf("%d",&n); for(i=1;i<=n;i++){ if(i!=1){ x*=(double)(i-1); } sum+=1/x; } printf("e=%.10f\n",sum); return 0; } n! を記憶する変数として「 x 」を宣言 n! は n=0 の時、特殊なので扱いを別にする n=0 のとき「 n!=0!=1 」 n! は前回ループの時 (n-1)! を求めてあるの で前回の値に n(=i-1) を掛ければよい 変数「 sum 」にどんどん 1/n! を足していく 初期化「 sum=0 」を忘れるな!
6
配列(復習) 「繰り返し処理」とともに用いると、非常 に便利な機能が「配列」という機能です。 「配列」は、ベクトルや行列の成分のよう に、複数の数字の組み合わせを「添え字」 を用いて表す「変数」(数字を記録する 箱)のセットです。 a[0] 、 a[1] 、 a[2]… のようにカギ括弧を使う。添え字は 0 から b[0][0] 、 b[0][1]…: 添え字が2変数 C[0][0][0] 、 c[0][0][1]… :添え字が3変数 文字列も配列を利用して扱います( New )
7
配列の使用法 配列の宣言 int a[12]; float b[35]; double c[10]; など [ ] 内は配列のメンバー数 初期値の代入 int a[3]={3,-2,1}; 宣言時に初期値を代入できる int a[]={3,-2,1}; 初期値代入の場合はメンバー数省略 可 宣言時以外ではいっぺんに代入するのは不可能 配列の参照 [ ] 内に参照したい番号を書いて参照する( 0 始ま り) int a[3]={1,-2,3}; のとき a[1] には「 -2 」が記憶されて いる
8
文字列 文字列は char 型変数の配列を利用して実現 しています char h[]=”Hello world!\n”; * * 配列メンバー数は初期値代入のため省略されている メンバー数は 14 個、 「 \n 」の後に文字列の終わりを示 す「終端文字」が加えられる 3252441-523’H’’e’’l’ ’o’ 0 12345 アドレス(箱番号) 値 「 h[] 」と名付けた h ⇒ 3 h[0] ⇒ ’H’ h[1] ⇒ ’e’ ‥‥ 6 7 ’\n’ まで
9
例題 EX9-1 文字列と配列: EX9-1.c 9 #include int main(void) { char h[]=”Hello world!\n”; int i; printf(”%s”,h); printf(” 文字列の先頭アドレスは %u です。 \n”,(unsigned int)h); for(i=0; i<13; i++){ printf(”%d 番目の文字は、「 %c 」です。 \n”,i,h[i]); } return 0; }
10
例題 EX9-2 文字列の利用: EX9-2.c 10 #include int intromusic(void); int battle1(char name[], char name_monster[]); int main(void) { char name[20]; char king1[]=" 「王様」ゆうしゃ "; char king2[]=" よ "; char king3[]=" りゅうおうを たおすのじゃ \n"; char king4[]=" しんでしまうとはなさけない \n"; char quest1[]=" たびにでる ?\n"; char quest2[]=" たたかう ?\n"; char quest3[]=" 右へいく ?\n"; char name_m1[]=" メタルスライム "; char name_m2[]=" キラーマジンガー "; char event1[]=" があらわれた \n"; char event2[]=" そのあと なにもであいませんでした \n\n"; char event3[]=" はへいぼんないっしょうをおえ、なくなりまし た \n\n"; char yesno[]="1. はい 2. いいえ \n"; int i,a; intromusic(); printf(" 名前を入れてください : "); scanf("%s",name); printf("\n\n"); printf("%s%s%s%s",king1,name,king2,king3); printf("%s%s",quest1,yesno);/* 旅? */ scanf("%d",&a); if(a==1){ sleep(2); printf("%s%s%s%s",name_m1,event1,quest2,yesno);/* メタル出現 */ scanf("%d",&a); if(a==1){ /* メタルと戦う */ battle1(name,name_m1); } else{ /* メタルと戦わない */ printf("%s",event2); sleep(2); printf("%s%s",name,event3); sleep(2); } else{ printf("%s%s",name,event3); sleep(2); } printf("%s%s%s%s",king1,name,king2,king4); return 0; }
11
例題 EX9-2 文字列の利用: EX9-2- 1.c 11 #include int battle1(char name[], char name_monster[]) { printf(" ちゃららっ \n\n"); sleep(1); printf(" ゆうしゃ %s のこうげき \n",name); sleep(2); printf("%s に 25 のダメージ \n\n",name_monster); sleep(2); printf("%s のこうげき \n",name_monster); sleep(2); printf(" ゆうしゃ %s に 35 のダメージ \n\n",name); sleep(2); printf(" ゆうしゃ %s はしんでしまった \n\n",name); sleep(2); return 0; } int intromusic(void) { char m1[]=" ちゃーちゃ "; char m2[]=" ちゃちゃちゃ "; char m3[]=" ちゃ "; char m4[]=" ちゃん "; printf("%s %s%s %s %s %s\n",m1,m2,m3,m2,m2,m3); sleep(2); printf("%s %s %s\n\n",m1,m2,m4); sleep(3); return 0; }
12
乱数( random number ) コンピューターでは、サイコロの様に毎回ラ ンダムに変化する数字を生成することができ ます 毎回ランダムに変化する数を「乱数」といい ます C言語では乱数を生成する関数として 「 rand() 」関数が標準で用意されています 「 rand() 」はC言語が開発された時から用意されてい るので、設計が古く、ランダムさの性能がよくありま せん 必ず用意されているとは限りませんが、もし 「 random() 」関数が用意されている場合はこちらを 使った方がよい
13
「 rand() 」関数が宣 言されている /* 乱数 EX9-3.c */ #include int main(void) { int i, rn ; for(i=0;i<10;i++){ rn=rand(); printf("%d¥n",rn); } return 0; } 33613 564950497 1097816498 1969887315 1404212 940422543 202055087 768218108 770072198 1866991770 [ 出力例 ] 何回 実行して も同じ結 果 何回 実行して も同じ結 果 ■ 乱数の出し方 13
14
「 rand() 」関数の性質 プログラムを繰り返すと毎回同じ乱数の列が 得られる 本当の乱数ではない!「疑似乱数」 最小値「 0 」、最大値「 RAND_MAX 」の整数 「 RAND_MAX 」がいくつなのかは処理系に依存 printf(”%ld\n”,(long)RAND_MAX); で調べられる 「 rand() 」関数を使うには「 #include 」が必要 プログラム実行毎に、異なる乱数の列を発生 させたいときには、「 srand(s) 」関数を実行 する
15
「 srand(s) 」関数と関数の系列 「 s 」の値(整数型、 seed と呼ぶ)が異なると、 乱数列が異なる → 例題 EX9-4.c #include int main(void) { int s,i,rn; srand(0); printf("seed=0\n"); /* seed が 0 */ for(i=0; i<10; i++){ rn=rand(); printf("%d\n",rn); } printf("\n"); srand(1); printf("seed=1\n"); /* seed が 1 */ for(i=0; i<10; i++){ rn=rand(); printf("%d\n",rn); } printf("seed s を入力 : "); scanf("%d",&s); srand(s); printf("\n"); printf("seed=%d\n",s); for(i=0; i<10; i++){ rn=rand(); printf("%d\n",rn); } return 0; } テクニック srand((unsigned int)time(NULL)); とすると手で入力しなくてよい (#include が必要 )
16
範囲の決まった乱数の生成 「 rand() 」は 0 ~ RAND_MAX の範囲の乱数を生 成 0 ~ 9 の範囲の乱数を生成するには? 「剰余 % 」を利用! #include int main(void) { int i,r; srand((unsigned int)time(NULL)); for(i=0; i<10; i++){ r=rand()%10; /* 0 ~ 9 の間の乱数、 10 で割ったあまりは 0 ~ 9 の範囲 */ printf(”%d\n”,r); } return 0; }
17
例題 EX9-5 ランダムなモンスター出現: EX9-5.c ( 50% の確率で、メタルスライムかキラーマジンガーが出 現) 17 #include int intromusic(void); int battle1(char name[], char name_monster[]); int main(void) { char name[20]; char king1[]=" 「王様」ゆうしゃ "; char king2[]=" よ "; char king3[]=" りゅうおうを たおすのじゃ \n"; char king4[]=" しんでしまうとはなさけない \n"; char quest1[]=" たびにでる ?\n"; char quest2[]=" たたかう ?\n"; char quest3[]=" 右へいく ?\n"; char name_m1[]=" メタルスライム "; char name_m2[]=" キラーマジンガー "; char event1[]=" があらわれた \n"; char event2[]=" そのあと なにもであいませんでした \n\n"; char event3[]=” はへいぼんないっしょうをおえ、なくなりまし た \n\n"; char yesno[]="1. はい 2. いいえ \n"; int i,a,m; srand((unsigned int)time(NULL)); intromusic(); printf(" 名前を入れてください : "); scanf("%s",name); printf("\n\n"); printf("%s%s%s%s",king1,name,king2,king3); printf("%s%s",quest1,yesno);/* 旅? */ scanf("%d",&a); if(a==1){ sleep(2); m=rand()%2; if(m==0){ printf("%s%s%s%s",name_m1,event1,quest2,yesno);/*M 出現 */ } else{ printf("%s%s%s%s",name_m2,event1,quest2,yesno);/*M 出現 */ } scanf("%d",&a); if(a==1){ /* メタルと戦う */ if(m==0){ battle1(name,name_m1); } else{ battle1(name,name_m2); } else{ /* メタルと戦わない */ printf("%s",event2); sleep(2); printf(”%s%s",name,event3); sleep(2); } else{ printf(”%s%s",name,event3); sleep(2); } printf("%s%s%s%s",king1,name,king2,king4); return 0; }
18
課題 EX9-6: 丁半ゲーム(お金をかけてはいけません) サイコロを 2 個ふり、目の合計が偶数なら「丁(ちょう)」奇数なら 「半(はん)」とする。丁か半かを予測するゲームを行うとき、 2 個 のサイコロの代わりとなるプログラムを作成せよ。 ( EX10-6.c ) 18 $./EX10-6.exe サイコロの目は 3 と 2 です 3-2 の半です 課題 EX9-7 0 から 9 までの乱数を N 個発生させ,それぞれの数字が出た回数およ び確率を出力するプログラムを作成せよ。 とくに N=100 と 10000 の場合について, 確率のバラツキはどちらが小さいか確認せよ。 ( EX9-7.c)
19
この部分の 面積は π/4 [ 注 ] 0 と 1 の間の実数の乱数を得るには 例えば x=(double) rand()/RAND_MAX; とするとよい. 19 特別課題 EX9-8 乱数を利用して,円周率を計算せよ. なお,下の図を参 考にせよ. 使う乱数の数は 10000, 1000000, 100000000 と変え, それらの結果を比較せよ. ( ex10-8) モンテ・カルロ法
20
20 特別課題 EX9-9 EX9-2.c, EX9-2-1.c を改造し、メタルスライムに勝ったり負 けたりするゲームを作成せよ. ドラクエもどき3
21
実習結果のレポート 2つのソースファイル「 EX9-6.c 」、「 EX9- 7.c 」を添付ファイルにしてメールを送って ください。 宛先: muroo@cc.tuat.ac.jpmuroo@cc.tuat.ac.jp 件名:コンピュータ基礎実験9 本文:感想および一言 21
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.