Presentation is loading. Please wait.

Presentation is loading. Please wait.

C言語講座第二回 2017 分岐とループと乱数.

Similar presentations


Presentation on theme: "C言語講座第二回 2017 分岐とループと乱数."— Presentation transcript:

1 C言語講座第二回 2017 分岐とループと乱数

2 前回の補足(1.入出力型指定子早見表) 入出力型指定子 printf() scanf() int %d long %ld float %f
double %lf char %c

3 前回の補足(2.return 0;に関して) int main()内で書くreturn 0;について return 0;はそのまま「0を返す」という意味です。 main関数の最後にこれを書くのは、 main関数が0を返した時はそのmain関数が正常終了したことを表すからです。 逆にエラーが起きた場合はreturn 1;とかされるようにしておくわけですね。 void main()の場合は何も返さないのでエラーチェックもできません。 現状ではエラーチェック自体に意味がないので 説明する必要もないのですが一応。

4 その他補足 ■コメントアウト //を頭につけた行や /**/で囲まれた部分は実行に影響しない。 長いプログラムを書いたりや多人数で開発したりする時のメモに使う。 ■スペース タブや半角スペース、改行はわりと自由に挿入してよい。 (変数名や命令名を区切ってはダメ) 記号や演算子、数字の桁なんかを揃えると見やすいかも。 a = a b; c = c d;

5 代入・単項演算子 代入演算子 記法 意味 += A += B AにBを加える -= A -= B AからBを引く *= A *= B
/= A /= B AをBで割る %= A %= B AをBで割った余りを Aに代入 単項演算子 記法 意味 ++ ++AまたはA++ Aに1加える -- --BまたはB-- Bから1引く 前置と後置の違いは扱いません。

6 比較・論理演算子 条件式:真ならtrue(=1)を、偽ならfalse(=0)を返す 比較演算子 記法 意味 == A == B
< A < B AはB未満か > A > B AはBより大きいか <= A <= B AはB以下か >= A >= B AはB以上か != A != B AとBは等しくないか 論理演算子 記法 意味 && (A >= 100) && (A <= 200) Aは100以上かつ200以下か || (A <= 100) || (A >= 200) Aは100以下または200以上か ! !(A >= 100) Aは100以上ではないか 200 >= A >= 100みたいに書くと予想外の動きをするので注意

7 if else #include <stdio.h> int main(){ int a; a = 50;
if (a <= 100){ printf("aは100以下です。\n"); } else{ printf("aは100以下ではありません。\n"); return 0; aは100以下か { }を使わなかった場合はその行のみ適用

8 else if else{if}と同じ #include <stdio.h> int main(){ int a;
if (a <= 100)printf("aは100以下です。\n"); else if(a >= 80){ printf("aは80以上100未満です。\n"); } else{ printf("aは80未満です。\n"); return 0;

9 演習1 scanf()を用いてint型変数a,bにそれぞれ一桁ずつ数字を読み込み、 ・aよりもbの方が大きい場合 ・aとbが等しい場合 ・aよりもbの方が小さい場合 の3つの場合に対してそれぞれ違う文章がprintf()されるプログラムを書け。 ただし、 はじめにaとbが等しいかを判定し、 等しくなければどちらの方が大きいかを判定せよ。

10 演習1解答例 #include <stdio.h> int main(){ int a, b; printf("a="); scanf("%d", &a); printf("b="); scanf("%d", &b); if (a == b){ printf("aとbは等しいです。\n"); } else if (a > b){ printf("aはbより大きいです。\n"); else{ printf("aはbより小さいです。\n");

11 switch switch(変数)の変数と同じ caseの{以下を実行 break;でswitch{}から脱出
#include <stdio.h> int main(){ int a = 0; switch (a){ case 0:{ printf("aは0です。\n"); break;} case 1:{ printf("aは1です。\n"); default:{ printf("エラーが発生しました。\n"); } return 0; switch(変数)の変数と同じ caseの{以下を実行 break;でswitch{}から脱出 どのcaseにも該当しない場合はdefaultの{以下を実行する。 defaultは書かないことも可能。 switchおよびcaseの 変数・定数は式でもよい。

12 演習2 scanf()を用いてchar型変数aに一文字読み込み、 ・その文字がaである場合 ・その文字がAである場合 ・それ以外 の3つの場合に対してそれぞれ違う文章がprintf()されるプログラムを書け。 ヒント:char型が内部的には整数で表現されていることを利用する。

13 演習2解答例 'A' = 65 'a' = 97だが、 65や97といった数字を 直接書かずに書ける
#include <stdio.h> int main(){ char a; scanf("%c", &a); switch (a){ case 'a':{ printf("aはaです。\n"); break;} case 'A':{ printf("aはAです。\n"); default:{ printf("aはaでもAでもありません。\n"); } return 0; 'A' = 65 'a' = 97だが、 65や97といった数字を 直接書かずに書ける

14 whileとfor #include <stdio.h>されたmain()の中で
int i = 0; while(i < 10){ printf("i=%d\n", i); i++; } //while(条件式)の //条件式が偽になるまで繰り返す int i = 0; for(i=0; i<10; i++){ printf("i=%d\n", i); } //for(初期化式;条件式;更新式) //初期化式を行い、}まで行ったら更新 //条件式が偽になったら脱出

15 演習3 int型変数i,sumを用意し、 while文かfor文を使って1,3,5,7,9の和を求め、 それを出力するプログラムを書け。 余裕のある人は両方の構文で書いてみること。

16 演習3解答例1 #include <stdio.h> int main(){ int i = 1; int sum = 0; while(i<=9){ sum += i; i += 2; } printf("合計は%d\n",sum);

17 演習3解答例2 #include <stdio.h> int main(){ int i,sum; for(i=1, sum=0; i<=9; i+=2){ sum += i; } printf("合計は%d\n",sum); forの初期化式、更新式には カンマで区切って 2つ以上の式を書ける (indexに関係ない式も可) あと式を書かないのも一応可能 while,for どちらのプログラムでも i=11で終了していることに注意

18 do-whileの紹介 #include <stdio.h>されたmain()の中で
int i = 20; do{ printf("%d", i); i++; }while(i < 10); //doの{ }内を一度実行した後、 //while(条件式)の条件式が偽になるまで繰り返す //ここではi = 20だが一度は出力される

19 疑似乱数の取得 #include <stdio.h> #include <stdlib.h> int main(){ int x; x = rand(); printf("x=%d\n", x); return 0; } 疑似乱数は xn+1=f(xn)という漸化式になっており、 rand();をするとxn+1が返ってくる。 そのためx0(シード値)が決まると rand();を何回実行した時の値が 何になるか決まる。 任意のiに対するxiは 0≦xi≦RAND_MAX(= 2 15 −1)であり 一様整数乱数(int)

20 シード値の変更 #include <stdio.h> #include <stdlib.h> int main(){ srand(1); int x; x = rand(); printf("x=%d\n", x); return 0; } シード値をnにする場合はsrand(n); プログラムの途中で書くことも出来る。 (シード値のリセット) ランダム性を持たせたい場合は #include <time.h>された状態で srand((unsigned int)time(NULL));とすると 現在時刻に応じてシード値が決まる →起動するたびに違ったシード値になる ただしデバッグが大変になるので ここではデフォルトの1で行きます (何も書かなかった場合も1です)

21 乱数の加工 #include <stdio.h> #include <stdlib.h> int main(){ srand(1); int x = rand() % 201; int y = 50 + rand() % 151; printf("x=%d,y=%d\n", x, y); return 0; } 0以上 2 15 −1以下の乱数を そのままでは使えないので 加工しましょう。 左の例では 0≦x≦200 50≦y≦200となっています。 実数乱数、半開区間については 今回のおまけに記載しています。

22 演習4 int型変数xに、0以上100以下の一様整数乱数を代入し、 xの値を表示した後、xの値が ・45以下 ・45より大きく55以下 ・55より大きい の3つの場合にそれぞれ違う文章がprintf()されるプログラムを書け。 できた人はsrand(5);、srand(10);にして試してみること。

23 演習4解答例 srand(1);の時x=41 srand(5);の時x=54 srand(10);の時x=71になるはず。
#include <stdio.h> #include <stdlib.h> int main(){ srand(1); int x; x = rand() % 101; printf("x=%d\n", x); if (x <= 45){ printf("xは45以下。\n"); } else if (x <= 55){ printf("xは45より大きく55以下。\n"); else { printf("xは55より大きい。\n"); return 0; srand(1);の時x=41 srand(5);の時x=54 srand(10);の時x=71になるはず。

24 お疲れさまでした! ここから先はおまけです。

25 whileとbreak int main(){ char a; while(1){ scanf("%c", &a); if(a == 'A'){ break; } return 0; while(1)と書くと( )内が真なので 無限ループします。が、 break;を使うことで解消できます。 break;はswitch文の他に while,for,doからも脱出することが できるからです。 左のプログラムではaに一文字代入し それがAであった場合のみ break;でwhile(1)から脱出するように なっています。

26 whileとcontinue int main(){ char a; while(1){ scanf("%c", &a); if(a != 'A'){ continue; } break; return 0; break;とは逆に、continue;を使うと continue;以下の命令を飛ばして (更新式→)条件式の判定→再ループ/脱出 という動きをさせることができます。 と偉そうに書きましたが 書いている本人は使ったことありません。

27 乱数の加工 番外編1 #include <stdio.h> #include <stdlib.h> int main(){ double a; a = rand()/RAND_MAX; printf("a=%f\n",a); } 0以上1以下の実数乱数を作りたい! と思っても左のプログラムでは 上手くいきません。 これはrand()とRAND_MAXが共に int型であるため、計算結果も int型になってしまうからです。

28 乱数の加工 番外編2 #include <stdio.h> #include <stdlib.h> int main(){ double a; a = (double)rand()/RAND_MAX; printf("a=%f\n",a); } そこで、 rand()をdouble型にキャストします。 こうすることで 計算結果も高精度であるdouble型になり 無事に0以上1以下の実数乱数に 加工できます。

29 乱数の加工 番外編3 #include <stdio.h> #include <stdlib.h> int main(){ double a; a = (double)rand()/(RAND_MAX+1); printf("a=%f\n",a); } また、0以上1未満の乱数に 加工したい場合、 左のプログラムのように RAND_MAX+1で割ることで 1を除外することができます。 加工した0以上1以下/未満の実数に 任意の最大値maxを掛ければ 0以上max以下/未満の実数に 加工できます。

30 演習5-1 文字当てゲームを作りたい。 まず、char型変数ansにランダムな半角英小文字('a'~'z')を一文字代入しておく。 それとは別のchar型変数aにscanf()で一文字読み込み、 aとansが一致した場合のみ終了するようなプログラムを書こう。 ※"aを入力してください"などのメッセージを表示させない方がいいかも。 もし表示させたくて上手くいかない場合はscanf(" %c", &a)という風に %cの前に半角スペースを挟んでみてください。

31 演習5-1解答例 #include <stdio.h> #include <stdlib.h> int main(){ char ans = 'a' + rand()%26; char a; while (1){ scanf("%c", &a); if (a == ans){ break; } return 0;

32 演習5-2 26文字から当てるのは大変なのでansは'a','b','c','d','e'のどれかにしよう。 当てるまでに答えた回数を記録したい。 回答回数を表すint型変数timesを用意し、 一度'a'~'e'のどれかを答えるごとに1加算されるようにする。 また、当たったら1を回答回数で割って正解率を求めよう。 それをdouble型変数perに代入し、printf()して終了するように追記しよう。

33 演習5-2解答例 #include <stdio.h> #include <stdlib.h>
int times = 0; double per; while (1){ scanf("%c", &a); if (a >= 'a' && a <= 'e'){ times += 1; if (a == ans){ break; } per = (double)100/times; printf("正解率 = %f%%\n", per); return 0; #include <stdio.h> #include <stdlib.h> int main(){ char ans = 'a' + rand() % 5; char a;

34 演習5-3 26文字から当てるのは大変なのでansは'a','b','c','d','e'のどれかにしよう。 ノルマ正解率を導入しよう。 ゲーム開始前に、double型変数normaに0以上100以下の実数乱数を代入、 printf()しておく。 ゲーム終了後に、perとnormaを比較し、 perがnorma以上かそうでないかの場合それぞれで 異なるメッセージをprintf()して終了するように追記しよう。

35 演習5-3解答例 #include <stdio.h> #include <stdlib.h>
double norma = (double)100 * rand()/RAND_MAX; printf("ノルマ = %f%%\n", norma); while (1){ /*中略*/ } per = (double)100/times; printf("正解率 = %f%%\n", per); if(per >= norma){ printf("クリア\n"); else{ printf("失敗\n"); return 0; #include <stdio.h> #include <stdlib.h> int main(){ char ans = 'a' + rand() % 5; char a; int times = 0; double per;

36 演習5-4 最後に、ランダム性を持たせよう。 #include <time.h>を書き、 int main(){の直後にsrand((unsigned int)time(NULL));を書けば完成。

37 演習5-4解答例 #include <stdio.h> #include <stdlib.h>
printf("ノルマ = %f%%\n", norma); while (1){ scanf("%c", &a); if (a >= 'a' && a <= 'e'){ times += 1; if (a == ans){ break; } per = (double)100/times; printf("正解率 = %f%%\n", per); if(per >= norma){ printf("クリア\n"); else{ printf("失敗\n"); return 0; #include <stdio.h> #include <stdlib.h> #include <time.h> int main(){ srand((unsigned)time(NULL)); char ans = 'a' + rand() % 5; char a; int times = 0; double per; double norma = (double)100 * rand()/RAND_MAX;

38 お疲れさまでした!


Download ppt "C言語講座第二回 2017 分岐とループと乱数."

Similar presentations


Ads by Google