プログラミング応用 第 15 回 知的情報システム学科張 暁華 プログラミング応用 1
授業のマナー ------ 人の話を聞くときの社会常識 1. 欠席者のかわりに登録を行わない 倫理に反することをやらない あなたの信を問われている蟻の穴から堤防が決壊 2. 私語しないこと : 質問 意見は手を挙げて大きな声ではっきりと意思表示 3. 授業以外のことをしない : 携帯をカバンにいれ イヤホンを使って音楽等を聞かない授業中ゲームを遊ばない 授業と関連のないページをアクセスしない 4. 原則として 授業中に無断で教室から出入りしないこと 5. 机の上突っ伏して寝ないこと プログラミング応用 2
授業内容 第 01 回ガイダンスー C 言語最低限の復習第 02 回繰り返し制御構造第 03 回多数のデータを扱う配列第 04 回関数の基礎第 05 回複数の引数を持つ関数第 06 回構造体の基本第 07 回構造体と関数第 08 回ポインタの基本第 09 回ポインタと配列第 10 回ポインタと構造体第 11 回ポインタと関数第 12 回ファイルの基本第 13 回ファイル処理の応用第 14 回総合演習 (1) 第 15 回総合演習 (2) プログラミング応用 3
総合演習 Lack Number Search コマンドライン 簡易電卓 しっかり理解しておく! 実用上のプログラムを作成するには欠かせないものだ! プログラミング応用 4
Lack Number Search この演習 ex15_1.c では 判断力や瞬発力などを磨きながら右脳 ( 本当?) をトレーニングするソフトを作成する 1 から 9 までの数字を一つ抜いて無作為の順で表示し その抜いた数字を瞬時に見つけさせるトレーニングである 例 : 2 6 1 5 3 9 4 8 の中に 7 が抜かれた 必要な知識 : 条件文 繰り返し 配列 ポインタ 関数 時間の計り方法など プログラミング応用 5
Lack Number Search ex15_1.c 例 :1 から 9 まで 1 桁の数字を八つ ( 一つを抜く ) 提示し プレーヤは 欠けた数字を瞬時に見つけ入力する システムが 10 回数字を提示する 毎回の数字は無作為に順序を決める 抜く数字を無作為に決める 10 回のプレー時間を図る #include <time.h> #include <stdio.h> #include <stdlib.h> #define MAX_STAGE 10 // 挑戦回数 void swap(int *x,int *y); void dispcopy(int *dgt, int *a, int x); void shuffle(int *a); プログラミング応用 6
Lack Number Search int main(void) { int i, j, stage,x; int dgt[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9; int a[8]; // 表示用 int no; // 読み込んだ値 double jikan; // 時間 clock_t start, end; // 開始時刻 終了時刻 srand(time(null)); // 乱数の種を設定 printf(" 毎回 1から9までの数字を一つ抜きで提示する n"); printf(" 欠けている数字を入力してください n"); start = clock(); // 開始時刻 プログラミング応用 7
Lack Number Search for (stage = 0; stage < MAX_STAGE; stage++) { x = rand() % 9; // 抜きたい要素番号を乱数で生成 //x 番目の要素を飛ばしてdgtを表示用 aにコピー dispcopy(dgt, a, x); // 表示用数字をシャーフルする shuffle(a); for (i = 0; i < 8; i++) // 全要素を表示 printf("%d ", a[i]); printf(":"); while(1){ scanf("%d", &no); if(no!= dgt[x]){ // 不正解 printf(" a 頑張ろう!"); else break; // 正解 プログラミング応用 8
Lack Number Search end = clock(); // 終了時刻 // 秒数を計算 jikan = (double)(end - start) / CLOCKS_PER_SEC; printf("%.1f 秒かかりました n", jikan); if (jikan > 25.0) printf(" 鈍すぎます n"); else if (jikan > 20.0) printf(" 少し鈍いですね n"); else if (jikan > 17.0) printf(" まあまあですね n"); else printf(" 素早いですね n"); return 0; プログラミング応用 9
Lack Number Search void swap(int *x,int *y) { int t; t = *x; *x = *y; *y = t; return; void dispcopy(int *dgt, int *a, int x) { int i, j; i = j = 0; while (i < 9) { if (i!= x) a[j++] = dgt[i]; i++; return; //dgt[x] を飛ばしてコピー プログラミング応用 10
Lack Number Search void shuffle(int *a) { int i, j; for (i = 7; i > 0; i--) { // 配列 aをシャッフル j = rand() % (i + 1); //iとjの要素を交換? if (i!= j) swap(&a[i], &a[j]); // 交換する return; プログラミング応用 11
コマンドライン いままでのプログラムの main 関数は 次の二つのカタチ void main(void) int main(void) どちらも引数を受け取らない ところで Linux 入門授業で gcc -o abc abc.c をよく使っている 実は この一行はコマンドラインで -o abc abc.c は オプションや引数と呼ばれ gcc コマンドに渡される プログラミング応用 12
コマンドの引数 コマンドで引数を受け取るのは 次のように書く void main(int argc, char *argv[]) argc の中にコマンドを含む オプションや引数の数 argv の中にコマンドラインに現れる文字列の組 例えば prog abc def 3 であれば プログラム名は prog で abc, def と 3 はそれぞれ引数である プログラミング応用 13
コマンドの確認例 ex15_2.c 例 : コマンドラインの引数などを表す文字列を出力せよ 引数などを半角空白で区切ること #include <stdio.h> void main(int argc, char *argv[]) { int i; printf("argc = %d n",argc); for(i=0;i<argc;i++) printf("argv[%d]: %s n", i, argv[i]); プログラミング応用 14
数字文字列を数値へ変換 数字文字列とは 数字や小数点で構成される文字列である たとえば 123 は文字列で 数値ではない 123 は数値である 関数 atoi で文字列 123 を数値 123 へ変換できる ( 整数 ) 関数 atof で文字列 123.45 を数値 123.45 へ変換できる ( 浮動小数点数 ) プログラミング応用 15
簡易電卓 ex15_3.c 例 : コマンドライン入力より 足し算と引き算を行う簡易電卓を作成せよ なお 3 + 4 や 3 4 の形式で入力とする 注意 :argv[0]: コマンド名自身が入っている argv[1]: 一つ目の数字 ( 文字列 ) argv[2]: 演算子 argv[3]: 二つ目の数字 ( 文字列 ) プログラミング応用 16
簡易電卓 #include <stdio.h> #include <stdlib.h> void main(int argc, char *argv[]) { char op; float a, b, res; if(4!= argc){ printf(" コマンドラインエラー! n"); exit(-1); a = atof(argv[1]); b = atof(argv[3]); op = argv[2][0]; プログラミング応用 17
簡易電卓 switch(op){ case '+': res = a + b; break; case '-': res = a - b; break; default: printf(" a 間違えた演算子! n"); exit(-1); printf("%f %c %f = %f n",a,op,b,res); プログラミング応用 18
プログラミング応用 課題 1.(hw15_1.c) 例題 ex15_3.c のプログラムを修正し 割り算 / 掛け算 * を演算できるようにせよ 提出 URL: http://cat.cc.it-hiroshima.ac.jp/~zhao/lect/2017/pa/lec15/ プログラミング応用 19