1 / 20

プログラミング演習 Ⅱ 第 8 回 マクロ・列挙体等

プログラミング演習 Ⅱ 第 8 回 マクロ・列挙体等. 情報・知能工学系 山本一公 kyama@tut.jp. 前回の課題の解説・ポイント(1). 課題6-1 プログラム そのもの は 特にどうということは ない 出力は全部 unsigned にキャスト char / signed char / unsigned char : 1 byte signed short int / unsigned short int : 2 byte signed int / unsigned int : 4 byte

isi
Download Presentation

プログラミング演習 Ⅱ 第 8 回 マクロ・列挙体等

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. プログラミング演習Ⅱ第8回マクロ・列挙体等プログラミング演習Ⅱ第8回マクロ・列挙体等 情報・知能工学系 山本一公 kyama@tut.jp

  2. 前回の課題の解説・ポイント(1) • 課題6-1 • プログラムそのものは特にどうということはない • 出力は全部 unsigned にキャスト • char / signed char / unsigned char : 1 byte • signed short int / unsigned short int : 2 byte • signed int / unsigned int : 4 byte • signed long int / unsigned long int : 8 byte • signed long longint / unsigned long longint : 8 byte • float : 4 byte • double : 8 byte • long double : 16 byte

  3. 前回の課題の解説・ポイント(2) • 課題6-2 • 説明スライドの通り • 右シフトと左シフトを組み合わせることで回転を実現する unsigned lrotate(unsigned x, int n) /* 左回転 */ { return (x << n | x >> (sizeof(unsigned)* 8 – n)); } unsigned rrotate(unsigned x, int n) /* 右回転 */ { return (x >> n | x << (sizeof(unsigned) * 8 – n)); }

  4. 課題5の採点結果から • 課題5−2 • 今の関数呼び出しが初めてかどうか(Wを直接返すかどうか)を判定するために、変数を用意すること自体は正しい • その変数の初期値として0を代入しておき、その変数が0なら初めての呼び出しなので、1を代入すれば良いだけ • 呼ばれる度にその変数に1を加算する必要はない • 初めてかどうかだけが判定できれば良いのだから • 加算し続けると、そのうち0に戻ってしまって、予期せぬ不具合が起きる可能性がある

  5. 課題6の採点結果から • 課題6−2 • ビット数を数える必要がある • やり方は正しければ何でも良い • 大域変数countを用意して、count_bits()でカウントさせている人がいる • この場合、rrotate()/lrotate()より先に、count_bits()が一度呼び出されている必要がある • それをプログラマがやらないといけない • 関数が独立していない。使うとき注意が必要になる • 実装としてあまり好ましくない

  6. 今日の内容 • 教科書 pp.183~193, 198~205 • 再帰は来年になってから • 関数形式マクロ • コンマ演算子 • 列挙体 • 列挙定数 • 入出力と文字 • getchar(), putchar(), EOF • JISコード (ASCIIコード)

  7. 関数形式マクロ(1) • 関数っぽくマクロを書くことができます • 引数・返却値の型を気にしなくてもよい • ただし、自動的に型が拡張されるので注意! • マクロなので、コンパイル時に展開される • 通常、プログラムサイズ⇒大、速度⇒高 #define sqr(x) ((x) * (x)) /* 二乗を計算する関数形式マクロ */ … printf(“その数の二乗は%dです。\n”, sqr(nx));

  8. 関数形式マクロ(2) • 副作用に注意 • sqr(a++) ⇒ (a++)*(a++) • 意図しない結果に! • 引数・マクロ全体を ()でくくろう! • 式を入れるとおかしなことに #define add(x,y) x + y … z = add(a, b) * add(c, d); ⇒ z = a + b * c + d; 意図しない結果に!

  9. 関数形式マクロ(3) • “{“と”}”で囲んでブロックを作って、その中に処理(複数の文)を書く • 「手続き形式マクロ」とも呼ぶ • 教科書では間違いの例として紹介されているが、if文のブロックを”{”と”}”で囲まなかったのが問題 • この書き方自体が悪い訳ではない #define putsa(str) {putchar(’_a’); puts(str);}

  10. コンマ演算子 • “,”で式をつなぐと、一つの式になる • 左から順に評価される • これを利用して、先の例を常に問題が出ないように書き直すことができる • 警報を発して文字列を表示するマクロ #define putsa(str) (putchar(‘\a’), puts(str) )

  11. 関数形式マクロの展開のされ方を見る • コンパイルするときに、gccにオプションとして”-E”を与える • “gcc –E list8-1.c” のようにする • コンパイルされず、前処理(preprocess) だけが行われる • C言語ソースファイル中の”#”で始まる行の処理(#defineや#include)だけが行われる • 関数型でもマクロなので「コンパイル前に文字の置き換えが行われるだけ」なことに注意せよ

  12. 列挙体(1) • 値の集合を表すデータ構造 • メンバーに順番に値が割り当てられる • 列挙定数はint型 enum animal { Dog, Cat, Monkey, Invalid }; /* Dog = 0, Cat = 1, Monkey = 2, Invalid = 3となる */ enum animal select(void) /* 返り値がenum型 */ { inttmp; … return (tmp); /* 実際の返り値はint型 */ }

  13. 列挙体(2) • 列挙体メンバーは定数 • case文で使える • 上手く使えれば便利 enum animal selected; do { switch (selected = select()) { case Dog : dog(); break; case Cat : cat(); break; case Monkey : monkey(); break; } while (selected != Invalid);

  14. 列挙定数 • 列挙定数は値を変えられる • 途中でも変えられる • 月名と月数の対応 enum animal { Dog = 1, Cat, Monkey, Invalid }; /* Dog = 1, Cat = 2, Monkey = 3, Invalid = 4となる */ enum animal { Dog, Cat= 3, Monkey, Invalid }; /* Dog = 0, Cat = 3, Monkey = 4, Invalid = 5となる */ enum month { January = 1, February, March, April, …, December };

  15. 入出力関数とEOF • getchar() • 標準入力(キーボード)から1文字読み込む • 返却値は int型。読み込んだ文字を返す • ファイルの終端かエラーでEOFを返す • EOF: ファイルの終端( End of File)の意。stdio.h内で定義されている。 • putchar() • 標準出力(端末画面)へ1文字書き込む • 返却値は int 型。書き込んだ文字を返す • エラーでEOFを返す

  16. 文字(1) • 文字には「文字コード」という数値が割り当てられている • 文字はコンピュータ内部では数値として扱われている • JISコード表(p.200, Table 8-1) • アルファベット・半角カナと文字コードの対応表 • アルファベットの部分はASCIIコードと同じ

  17. 文字(2) • 1文字をシングルクォートで囲むと文字コード(数値)になる • 拡張表記 • p.203, Table 8-2 • printf()やputs()の中でも使う ‘0’= 0x30, ‘1’= 0x31, ‘A’= 0x41, ‘a’= 0x61, ……

  18. 今週の課題 • 教科書p.187, 演習8-3のプログラムを作成せよ。main関数等も作成して、完成したプログラムを作成すること。gccに”-E”オプションを与えて、関数形式マクロが正しく展開されていることを確かめること。 • 教科書p.205, 演習8-8のプログラムを作成せよ。※ヒント:基本的には、1文字ずつ読み込んで、改行があったら数えている行数を増やせばよい。行の途中でEOFは出ないと考えて良い※キーボードからEOFを出すには”Ctrl + D”

  19. レポートについて • 電子メールで提出 • 提出先は prog2@slp.cs.tut.ac.jp • Subjectを「プログラミング演習2 課題7提出 学籍番号・氏名 」とすること • C言語ソースファイルを添付する • メールの本文には何も書かなくて良いです • ソースファイルの頭にコメントで以下の情報を入れる • 学籍番号・氏名 • プログラムの説明(どのように動くのか、工夫した点等) • 実行結果(長い場合は一部)を貼る • 提出締切は、12月12日(水) 12:00 (1週間後)

  20. 授業用Webサイト • URL: http://www.slp.cs.tut.ac.jp/~kyama/programming2/ • 課題のpdfファイルが置いてあります。 • 授業で使ったpptファイルを置いていきます。 • 質問メールは、以下のどちらかのアドレスまで • kyama@tut.jp • prog2@slp.cs.tut.ac.jp • C-515へ直接質問しに来ても構いません

More Related