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