University of Electro-Communications Human Interface section 基礎プログラミングおよび演習 第7回 University of Electro-Communications Human Interface section 関数と変数のスコープ 復習: ブロックと変数の有効範囲(スコープ) 変数はブロック({から}の間)の中だけで有効です。 int main(){ int a; { int x; x = 2*3; printf(”%d\n”, x); } printf(”%d\n”, x); return 0; } a xの有効範囲 (スコープ といいます) aの有効範囲 (スコープ といいます) x コンパイルエラー: `x' undeclared (first use in this function) 変数の有効範囲をスコープといいます。 関数とブロックと変数のスコープ #include <stdio.h> 各変数のスコープ // 2乗を計算する。 double square(double d){ squareのブロック d return d*d; double d が有効 } // n^2個の*を表示。 n^2を返す。 printSqのブロック int printSq(int n){ n int nn = square(n); int n, int nn, int count が有効 int count = nn; while(count){ whileのブロック printf(”*”); int n, int nn, int count に加えて、 int c = count-1; int c が有効 count = c; } printf(”\n”); return nn; } int main(){ printSq(5); mainのブロック return 0; } nn count c グローバル変数とスコープ グローバル変数⇒関数の外に書く変数 msの スコープ pointの スコープ #include ”curses_subset.h” どのブロックにも入ってない #include <math.h> ⇒どのブロックでも使える int point=0; int sleep_by_point(){ sleep_by_point のブロック int ms = 1000 / log(point); 2つのmsは sleep_ms (ms); まったく別の変数 return sleep; } 2つのpointは、 int main(){ main のブロック まったく int ms; while(point){ while のブロック 別の変数。 int point; sleep_by_point(); } ここの int point;のせいで、 if (当たり判定){ if のブロック このブロックでは、3行目の point = point – 100; int point=0;のpointが } 見えなくなる。 } グローバル変数とスコープ #include ”curses_subset.h” #include <math.h> int point=0; point int sleep_by_point(){ ms int ms = 1000 / log(point); sleep_ms (ms); return sleep; } int main(){ int ms; while(point){ int point; sleep_by_point(); } if (当たり判定){ point = point – 100; } } ms point University of Electro-Communications Human Interface section 雑多な文法 代入と計算のまとめ書き演算子 なくても困らない演算子 だが、他人の書いたソースを読むために必要 n = n – 1; のような計算は、繰り返しなどで良く出てくる。 ⇒便利な代入演算子があります。 n += 2; // n=n+2;と同じ n -= 2; // n=n-2;と同じ n *= 2; // n=n*2;と同じ n /= 2; // n=n/2;と同じ n ++; // n=n+1;と同じ n --; // n=n-1;と同じ ++n; // n=n+1;と同じ --n; // n=n-1;と同じ n++と ++n は非常に微妙に違います。 int a=1; int n; n = (a++)*10; // n=10 先に計算してさいごに ++ n = (++a)*10; // n=20 先に++して後で計算 while 以外の繰り返し なくても困らないが、forくらいは便利かも for(式1; 式2; 式3) 文かブロック 1. 式1を実行 2. 式2の値が0なら文 かブロックを飛ばし て次へ 3. 文かブロックを実行 4. 式3を実行 5. 2.から繰り返し for(int c=0; c<3; c++){ printf(”*”); } *** do 文かブロック while(式); 1. 文かブロックを実行 2. 式の値が0なら次へ そうでなければ1へ do{ int k = getchar(); }while(k!=100); break; continue; break文が実行される とその時点でループ を抜ける continue文が実行され ると、以降を実行せず、 ループを続ける。 while(1){ int k = getchar(); if (k==100) break; if (k==101) continue; printf(”key is not 101\n”); }; printf(”key is 100\n”); switch 文 switch(式){ int a = 1; case 数値1: switch(a){ 文かブロック1case 1: printf(”aは1です。\n”); 1; case 2: printf(”aは1か2です。\n”); 文かブロック1default: printf(”最後です。 \n"); 2; } : aは1です。 case 数値2: aは1か2です。 文かブロック2最後です。 1; case 1 にジャンプした場合、その後の、 文かブロック2case 2 の文も default の文も実行してしまう。 2; ⇒ ので、普通は break; と組み合わせて使う。 : default: 文かブロックd1. 式の値を求める 1; 2. 数値n と値が等しければ、 文かブロックdcase 数値n: の文にジャンプ 2; 3. 等しい数値がなければ defaultの : 文にジャンプ switch 文 / goto 文 int a = 1; switch(a){ case 1: printf(”aは1\n”); break; case 2: printf(”aは2\n”); break; default: printf(”1,2ではない \n"); } aは1です。 case 1 にジャンプした場合、 その後のbreak;を実行すると switch 文を抜ける。 if 文; else if 文; … の方が便利だし分かり やすい。 while(1){ ラベル: 文; } goto ラベル; goto ラベル; を実行すると、 ラベル:文; の文にジャンプする。 同じ関数の中なら、どこにでも ジャンプできる。 while(式){ while(式){ while(式){ if (式) goto next; } } } next: printf(”ループを抜けました\n”); プログラムの流れが分かりにくくなる ので多用するとよくない。上の例の ようなときぐらいにしておくのが良い。 if else の連鎖 switch文を使わなくても if else で同じことがかけます。 どっちでもよいので、プログラマはその都度カッコよいと 思うほうを使っています。 int a = 1; switch(a){ case 1: printf(”aは1\n”); break; case 2: printf(”aは2\n”); break; default: printf(”1,2ではない \n"); } int a = 1; if (a==1){ printf(”aは1\n”); }else if (a==2){ printf(”aは2\n”); }else{ printf(” 1,2ではない \n"); } 課題11 ターミナルで動くゲームを作る 課題のページにターミナルで動くシューティングゲー ム? の雛形があります. まずはex11sampleプロジェクトを作って, コンパイルして動かしてみてください. スクロールの向きを変えてください. ついでに 構造体と関数を使って書いてください. 使用するキーと機能を増やしてください. (例えば倍速移動とか) どんなゲームにしたのか,説明を必ず書いてください. 説明がないと採点時に見落としてしまうので. 課題11:資料 curses_subset.h は基礎プロの課題のために長谷川が作った独自の ヘッダファイルです.unixのcursesというカーソルを動かすライブラ リの機能の一部+αを持ちます. curses_subset.h が提供する関数 initscr() endwin() cbreak() nocbreak() echo() noecho() ターミナルの現在のモードを記録。 ターミナルの状態を元に戻す。 編集なしモード。getchar()が1文字ごとにすぐに返ってくる。 編集ありモード。[ENTER]まで、getchar()が返ってこない。 エコーあり。キー入力した文字を表示する。 エコーなし。キー入力した文字を表示しない。 kbhit() 待たずに読み出せるキー入力があれば 0 以外を返す。 clear() move(y,x) 画面クリア カーソルを上から y 行左からx桁に移動する。 sleep_ms(t) t ミリ秒プログラムを停止する。 文字コード 文字コード 実は、文字には番号がつけられています。 getchar() が返す整数はこの文字の番号です。 文字をシングルクォーテーション(’)で囲むと、文字 コード値のことになります。 printf()の文字列に%cを入れておくと、整数を文字 コードだと解釈したときの、文字が表示されます。 int main(){ int charCode = ’A’; // charCodeには、Aの文字コード 65が入る。 printf(”%d\n”, charCode); // 65と表示される。 printf(”%c\n”, charCode); // Aと表示される。 } 65 A 課題12:文字コード表を作る 文字コードの表を作ってみてください。 文字コードは(たぶん)0から255までの整数です。 機種やOSや言語モードによります。 表示できない文字や改行してしまう文字もあります。 http://ja.wikipedia.org/wiki/ASCII に英語文字コード表があります。 文字コードの整数と文字を表示させてください。 8文字ごとに改行を入れると見やすいです。 桁数をそろえて表示するには、printfの%dの代わりに %3d などを使います。 詳しくは BasicP04.pdf を参照 表示例の抜粋: 32 33 ! 40 ( 41 ) 48 0 49 1 56 8 57 9 34 " 42 * 50 2 58 : 35 # 43 + 51 3 59 ; 36 $ 44 , 52 4 60 < 37 % 45 53 5 61 = 38 & 46 . 54 6 62 > 39 ' 47 / 55 7 63 ?
© Copyright 2024 ExpyDoc