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

Slides:



Advertisements
Similar presentations
プログラミング論 第八回数字の計算,整数の入出力. 本日の内容 前回の課題(続き) 前回の課題(続き) 数字の計算をする 数字の計算をする – 加減乗除を行う – インクリメント演算子とデクリメン ト演算子.
Advertisements

C 言語講座第 5 回 構造体. 構造体とは ... 異なる型の値をまとめて新しい型とする 機能がある . つまり , 複数の変数を 1 つのまとまりにできる . 配列と違って同じ型でデータをまとめるのではな く違った型のデータをまとめられる .
第 2 章 数値の入力と変数 scanf と変数をやります 第 2 章 数値の入力と変数 1. 以下のプログラムを実行してみよう  C 言語では文の最後に「 ; 」(セミコロン)が付きます 第 2 章 数値の入力と変数 2 #include int main() { int x; x = 3; printf("x.
プログラミング演習( 2 組) 第 9 回
情報処理演習 (秋学期・樋口担当) 2回目 10/1 日本工業大学 コンピュータリテラシーII.
7/10 if 文課題 力作が多くて感心! 演習1:キーボードから2つの整数を入力し、小さい方の数字を 表示せよ。
ループで実行する文が一つならこれでもOK
4章 制御の流れ-3.
計算技術研究会 C言語講座 第3回 Loops (for文 while文).
第2章 数値の入力と変数 scanfと変数をやります.
基礎プログラミングおよび演習 第9回
プログラミング基礎I(再) 山元進.
第2回ネットワークプログラミング 中村 修.
C言語講座 第4回 ポインタ.
第5回C言語講座 ~ポインタと配列.
プログラミング入門2 第2回 複合文、繰り返し 情報工学科 篠埜 功.
第7回 条件による繰り返し.
プログラミング演習 バージョン1 担当教員:綴木 馴.
プログラムの制御構造 選択・繰り返し.
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
繰り返し計算 while文, for文.
基本骨格 #include #include : int main(void) { 変数の宣言 実行すること return 0; } #include int main(void) { int i; printf(”Hello world!\n”);
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング序論 2. n人のインディアン.
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
04: 式・条件分岐 (if) C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
今までの練習問題の復習.
indentについて forやifの「中身」を右に寄せる. forやifの「外枠」は右に寄せない. int x; x = 3;
第7回 条件による繰り返し.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
高度プログラミング演習 (05).
関数への道.
プログラミング言語論 第四回 理工学部 情報システム工学科 新田直也.
岩村雅一 知能情報工学演習I 第11回(後半第5回) 岩村雅一
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
復習 一定回数を繰り返す反復処理の考え方 「ループ」と呼ぶ false i < 3 true i をループ変数あるいはカウンタと呼ぶ
疑似乱数, モンテカルロ法によるシミュレーション
C言語 はじめに 2016年 吉田研究室.
C言語ファミリー C# 高級言語(抽象的) Java オブジェクト指向 C++ C 機械語(原始的)
IF文 START もしも宝くじが当たったら 就職活動する 就職活動しない YES END NO.
プログラミングⅡ 第2回.
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
復習 Cにおけるループからの脱出と制御 break ループを強制終了する.if文と組み合わせて利用するのが一般的. continue
復習 if ~ 選択制御文(条件分岐) カッコが必要 true 条件 false 真(true)なら この中が aを2倍する 実行される
C言語講座 制御(選択) 2006年 計算技術研究会.
復習 breakとcontinueの違い int i; for (i = 1; i <= 100; i++) { ・・・処理1・・・・
第5章 まだまだ続く反復処理!! ~繰り返しその2 for~
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
第2章 printf(“変数と入力”); scanf(“%d”,&num);
ループだよ!難しいよ! 第5章 while(ループ);.
cp-15. 疑似乱数とシミュレーション (C プログラミング演習,Visual Studio 2019 対応)
第4章 double 小数型の変数;.
岩村雅一 知能情報工学演習I 第10回(後半第4回) 岩村雅一
第7章 そろそろ int 以外も使ってみよう! ~データ型 double , bool~
プログラミング1 プログラミング演習I 第2回.
プログラミング序論演習.
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
第2章 数値の入力と変数 scanfと変数をやります.
復習 いろいろな変数型(2) char 1バイト → 英数字1文字を入れるのにぴったり アスキーコード → 付録 int
情報処理Ⅱ 第3回 2004年10月19日(火).
情報処理Ⅱ 2006年10月20日(金).
C言語講座 四則演算  if ,  switch 制御文.
分岐(If-Else, Else if, Switch) ループ(While, For, Do-while)
知能情報工学演習I 第10回( C言語第4回) 課題の回答
プログラミング演習I 補講用課題
第1章 文字の表示と計算 printfと演算子をやります 第1章 文字の表示と計算.
第1章 文字の表示と計算 printfと演算子をやります.
= 55 課題6-1 #define _CRT_SECURE_NO_WARNINGS
ファーストイヤー・セミナーⅡ 第10回 if文による選択処理(2).
Presentation transcript:

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

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

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

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

代入・単項演算子 代入演算子 記法 意味 += 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引く 前置と後置の違いは扱いません。

比較・論理演算子 条件式:真なら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みたいに書くと予想外の動きをするので注意

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以下か 偽 真 { }を使わなかった場合はその行のみ適用

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;

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

演習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");

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の 変数・定数は式でもよい。

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

演習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といった数字を 直接書かずに書ける

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(初期化式;条件式;更新式) //初期化式を行い、}まで行ったら更新 //条件式が偽になったら脱出

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

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

演習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で終了していることに注意

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

疑似乱数の取得 #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)

シード値の変更 #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です)

乱数の加工 #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となっています。 実数乱数、半開区間については 今回のおまけに記載しています。

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

演習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になるはず。

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

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)から脱出するように なっています。

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

乱数の加工 番外編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型になってしまうからです。

乱数の加工 番外編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以下の実数乱数に 加工できます。

乱数の加工 番外編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以下/未満の実数に 加工できます。

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

演習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;

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

演習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;

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

演習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;

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

演習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;

お疲れさまでした!