プログラミング演習II 2004年12月 14日(第7回) 理学部数学科・木村巌 前回までの復習 関数ポインタ 教科書10.5から(p. 337~348) スタックというデータ構造と、配列を使ったス タックの実現 逆ポーランド記法 逆ポーランド記法計算機の実装例(+, -のみ) 今日学ぶこと 構造体 typedef 構造体のサイズ 構造体の応用 関数の引数に構造体を使う 関数の引数に構造体へのポインタを使う 構造体の配列 新しい型を決める これまで学んだのは、 char, int, floatなどの基本型 それらの配列 それらを指すポインタ、など 基本型や、それらの配列など派生型を一まと めにすることができる……構造体(structure) ひとつの意味を持たせることができる 構造体(structure) 異なる型の値をまとめて、新しい型を定義す る 配列は、同じ型の値をまとめることしかできな かった 例:車のナンバー(int型)、ガソリン量 (double)などを一つにまとめ、「車」をあらわ す型が定義できる 構造体の宣言 構造体形の宣言……structというキーワード を使う 構文 struct 構造体型名 { 型名 識別子; 型名 識別子; … }; 例 例:車をあらわすCarという構造体の定義 struct Car { int num; /* number */ double gas; /* gas */ }; これで、struct Car型という新たな型が定義さ れた 構造体変数を宣言する 構文 たとえば、先の例のstruct Car型については 構造体型名 構造体変数名; struct Car car1; car1は、struct Car型の値を格納する変数とな る メンバへのアクセス 構造体型の変数(単に構造体ともいう)を宣 言すると、そのメンバへのアクセスが可能に なる struct Car car1; と宣言すると、car1のナンバー をあらわすnumやガソリン量をあらわすgasな どのメンバにアクセスできる メンバにアクセスするには、ドット演算子をつ かう メンバにアクセスする(続) 構文 たとえば、 構造体変数名.メンバ car1.num = 1234; /* ナンバーをあらわすnumに1234を代入 car1.gas = 25.5; /* ガソリン量をあらわすgasに25.5を代入 */ */ Sample1.c (p. 353)、Sample2.c(p.355)を打ち 込んで、コンパイル・実行してみよう 構造体の記述の仕方 typedefにより名前を割り当てることができる struct Carという長い型名に対して、typedefに より別名を割り当てることができる 構文 typedef 型名 識別子; Typedefで名前を割り当てる 例 typedef struct Car { int num; double gas; } Car; とすることで、Car car1; とCar型の変数car1を宣言できる Sample3.c (p. 357)を打ち込んで、コンパイル・実行 してみよう 注:構造体型名と、typedefで割り当てる識別子は異 なっていても良い Typedefで名前を割り当てる(続) typedefで名前を割り当てるのは、長い構造体 型名を短縮するという用途よりも、ある型(例えば、 struct Car型)が、実際にどのように定義されている か(この場合、構造体であること)を隠蔽するという用途の 方が実際的 抽象データ型(abstract data type, ADT) typedefは、構造体の型名に別名を割り当て る以外にも使える 構造体の初期化 構造体を宣言したあと、ドット演算子を使って各メン バを初期化する もうひとつのやり方は、宣言と同時にメンバの所期 かも行ってしまうもの 例 Car car1 = {1234, 25.5}; カンマで区切った順に、メンバが初期化される 昔のCでは出来なかった Sample4.cを入力し、コンパイル・実行してみよう 構造体を構造体へ代入する 構造体のメンバに値を代入する方法は上に 見てきたとおり 同じ構造体型の構造体変数に、構造体を代 入することが出来る 通常の変数への代入と同じ書き方 Sample5.cを入力して、コンパイル・実行して みよう 構造体のサイズ sizeof演算子で、構造体型のサイズ(メモリに 占める領域)をバイト単位で知ることが出来る 各メンバの型のサイズの総和に等しいか、大 きくなることがある sizeof (構造体) >= sizeof(メンバ1)+sizeof(メ ンバ2) + …… + sizeof (メンバn) Sample6.cを入力し、コンパイル・実行してみ よう 構造体のサイズと 構造体へのポインタのサイズ Sample6.cでは、構造体そのもののサイズと、 その構造体へのポインタのサイズを見ている 後者のほうが、一般的には小さい ビットフィールドの話は省略 構造体の応用 関数の引数として構造体を使う Sample8.cを打ち込んで、コンパイル・実行し てみよう 引数は値渡し 各メンバがコピーされて、そのコピーが関数に渡 される 関数側で引数の構造体を変更しても、元の構造 体には反映されない 構造体へのポインタを引数に 構造体を関数の引数とすると、関数呼び出し のたびに構造体のコピーが行われる 構造体が巨大な場合、無視できない処理時 間がかかる 構造体へのポインタを引数として使うとよい 構造体より、そのポインタの方が小さいのだった ポインタ渡しだと、それが指す構造体を変更する ことも出来る 構造体へのポインタを引数に(続) 構造体へのポインタから、メンバにアクセス アロー演算子 -> を使う 構造体へのポインタ->構造体メンバ 「(*構造体へのポインタ).構造体メンバ」と同じ Sample9.cを入力し、コンパイル・実行してみ よう 構造体の配列 構造体型も他の型と同じように、配列をなす ことができる typedefによって、Car型が作られたとすると Car cars[3]; /* Carの配列 cars[] */ Sample10.cを入力し、コンパイル・実行してみ よう 更に進んだ話題(次回予告) 構造体のポインタから、typedefによって別の 型を作る 各メンバへのアクセスは、関数、もしくはマク ロを使う このようにして、ある型が、実際にはどのよう に実装されているのかを隠蔽する 抽象データ型(Abstract Data Type, ADT) スタックも(構造体は使っていないが)その例 初期化して、push, popするのみ 使う人は、配列であることを意識しなくてよい 今日学んだこと 構造体 typedef 構造体のサイズ 構造体の応用 関数の引数に構造体を使う 関数の引数に構造体へのポインタを使う 構造体の配列 レポート課題 typedef struct Book { char author[31]; char title[63]; char isbn[10]; } Book; により、Book型を定義する.Sample10.c(教科書 p. 373)を参考に、本5冊について、著者名、 表題、ISBNを管理するプログラムを作成せ よ. レポート課題(続) 締め切り:2004年12月20日一杯(日本時間 で) 提出:メールで木村([email protected])まで. 感想などあると木村が喜びます 試験通知 中間試験を、2005年1月11日に行います 中間試験の範囲は、それまでやったところすべて 形式は、筆記試験.持ち込み可 期末試験を、2005年2月1日に行う予定です 期末試験の範囲は、後期にやったところすべて
© Copyright 2024 ExpyDoc