第11回 http://www.fit.ac.jp/~matsuki/lecture.html プログラミングⅡ 第11回 http://www.fit.ac.jp/~matsuki/lecture.html
連絡 小テスト 授業開始直後と終了直前に小テストを2行います 授業開始直後テスト(復習テスト)⇒前回の復習 授業終了直前テスト(本テスト)⇒その日の内容の復習 本テストの成績(正答率)が50%以下の場合は、宿題を出します(レポートとは別)。 宿題を決められた期日までに提出しない場合は、欠席扱いにします
宿題の提出について 以下の場合は、出題日の出席を欠席とする 締切日を過ぎた場合 正解率が7割未満の場合 提出は、PDFファイルを印刷して、それに答えを書いて提出すること。
プログラミングに関する質問時間 月曜日と金曜日の12:00から13:00までは, CAE室で,プログラミングに関する質問を受け付けています. 遠慮なく相談に来てください.
今日の内容 構造体のサイズ 構造体とポインタ 構造体と配列 関数と構造体 引数に渡す 構造体へのポインタを引数として渡す
構造体のサイズ char型 ・・・ 1バイト int型 ・・・ 4バイト double型 ・・・ 8バイト Car型・・・ ?バイト typedef struct { int num; double gas; char name[20]; }Car; 4バイト×1個 8バイト×1個 1バイト×20個 32バイト (4+8+20) 書込め printf(“%dバイト\n”, sizeof(Car) ) 書込め
構造体のサイズ 名前、電話番号、年齢の構造体を以下のように定義した。 Info型・・・ ?バイト typedef struct { char name[20]; char tel[20]; int age; }Info; 1バイト×20個 1バイト×20個 4バイト×1個 44バイト (20+20+4) 書込め printf(“%dバイト\n”, sizeof(Info) ) 書込め
構造体とポインタ 変数と同じように、構造体へのポインタを考える typedef struct { char name[20]; friend typedef struct { char name[20]; char tel[16]; int age; }Info; Info friend = {“松木”, “090-1234-5678”, 20}; Info *p; 松木 090-1234-5678 20 p アドレス専門 ?????? 書込め ポインタ変数
構造体とポインタ typedef struct { char name[20]; char tel[16]; int age; }Info; friend typedef struct { char name[20]; char tel[16]; int age; }Info; Info friend = {“松木”, “090-1234-5678”, 20}; Info *p; p = &friend; 松木 090-1234-5678 20 p アドレス専門 0012FE30 ???????? friendのアドレスをpに代入 書込め
ポインタを使った構造体メンバの参照 構造体変数のメンバをポインタで参照するには、 「->」(マイナス「-」と不等号記号「>」)を使う 構造体変数のメンバをポインタで参照するには、 「->」(マイナス「-」と不等号記号「>」)を使う アロー演算子という 書込め printf(“名前は%s\n”, p->name); printf(“電話番号は%s\n”, p->tel); printf(“年齢は%d\n”, p->age); 書込め 書込め ポインタ名 メンバ名
pはポインタなので、アロー演算子でメンバを参照 #include <stdio.h> #include <string.h> /*構造体型のCarの宣言*/ typedef struct { char name[20]; char tel[16]; int age; }Info; main() { Info friend; Info *p; p = &friend; strcpy(p->name, “松木”); strcpy(p->tel, “090-1345-9696”); p->age = 30; printf(“名前: %s\n”, p->name); printf(“電話番号: %s\n”, p->tel); printf(“年齢: %d\n”, p->age); } 構造体へのポインタを定義 書込め friendのアドレスをpに代入 (pはfriendを指すことになる) 書込め 書込め pはポインタなので、アロー演算子でメンバを参照 書込め
構造体と配列 通常の変数と同じように、構造体の変数を考えることが可能 氏名、電話番号、年齢の構造体の場合、 松木 090-1257-9696 30 田中 090-8579-4545 24 ・・・・・・ person[0] person[1]
構造体配列の定義 typedef struct { char name[20]; char tel[16]; int age; }Info; Info person[5]; 構造体型の定義 書込め 構造体配列の定義
構造体配列の参照 typedef struct { char name[20]; char tel[16]; int age; }Info; Info person[5]; person[1].age = 20; 要素番号1番の配列のageに20を代入 書込め
書込め Infoという名前の構造体型を定義 strcpy(person[0].name, “松木”); #include <stdio.h> #include <string.h> /*構造体型のCarの宣言*/ typedef struct { char name[20]; char tel[16]; int age; }Info; main() { Info person[5]; int i; strcpy(person[0].name, “松木”); strcpy(person[0].tel, “090-1345-9696”); person[0].age = 30; strcpy(person[1].name, “田中”); strcpy(person[1].tel, “090-8579-4545”); person[1].age = 24; for (i = 0; i < 2; i++) { printf(“名前: %s\n”, person[ i ].name); printf(“電話番号: %s\n”, person[ i ].tel); printf(“年齢: %d\n”, person[ i ].age); } Infoという名前の構造体型を定義 構造体配列を定義 書込め for文を使ってまとめて表示 書込め
構造体配列の初期化 構造体型の定義 構造体配列の宣言と 書込め 初期化 typedef struct { char name[20]; char tel[16]; int age; }Info; Info person[5] = { {“松木”, “090-1234-9696”, 37}, {“田中”, “080-8579-5656”, 28}, : {“鈴木”, “050-5879-2626”, 18} }; 構造体型の定義 構造体配列の宣言と 初期化 書込め
アロー演算子(->)を使ってもOK 書込め Info person[3] = { {“松木”, “090-1234-5678”,20}, {“田中”, “080-3147-9696”,37}, {“鈴木”, “050-8765-5891”,18} }; Info *p; for (p=person; p != person+3; p++) { printf(“名前は%s\n”, p->name); printf(“電話番号は%s\n”, p->tel); printf(“年齢は%d\n”, p->age); } 書込め 書込め
構造体の関数への受け渡し
引数として構造体を使う 構造体型の変数も、関数の引数として利用することが可能。 名前、電話番号、年齢を表示する関数showを作ってみましょう。
show関数にfriendを渡して呼び出す #include <stdio.h> #include <string.h> /*構造体型のInfoの宣言*/ typedef struct { char name[20]; char tel[16]; int age; }Info; /*show関数のプロトタイプ宣言 */ void show( Info c ); main() { Info friend; strcpy(friend.name, “松木”); strcpy(friend.tel, “090-1345-9696”); friend.age = 30; show(friend); } 構造体型 Infoを定義 書込め 構造体変数 friendを定義 show関数にfriendを渡して呼び出す 書込め 次ページにつづく
printf(“名前は%s\n”, c.name); printf(“電話番号は%s\n”, c.tel); void show( Info c ) { printf(“名前は%s\n”, c.name); printf(“電話番号は%s\n”, c.tel); printf(“年齢は%d\n”, c.age); } 書込め 書込め 仮引数Cのメンバを参照 書込め main関数 show関数 friend c メンバはすべてコピーされる ・name ・tel ・age 書込め
構造体へのポインタを引数に使う 構造体は、データサイズが大きい。 データすべてを関数にコピーすると処理が遅くなる。 ポインタ(アドレス)のみを渡せば、処理速度が向上する。 書込め 書込め
show関数にfriendのアドレスを渡す #include <stdio.h> #include <string.h> /*構造体型のInfoの宣言*/ typedef struct { char name[20]; char tel[16]; int age; }Info; /*show関数のプロトタイプ宣言 */ void show( Info *pc ); main() { Info friend; strcpy(friend.name, “松木”); strcpy(friend.tel, “090-1345-9696”); friend.age = 30; show(&friend); } 構造体へのポインタを受け取る 書込め 構造体変数 friendを定義 show関数にfriendのアドレスを渡す 書込め 次ページにつづく
構造体へのポインタpcという仮引数で受け取る void show( Info *pc ) { printf(“名前は%s\n”, pc->name); printf(“電話番号は%s\n”, pc->tel); printf(“年齢は%d\n”, pc->age); } 書込め 書込め pcはポインタなので、 アロー演算子でメンバを参照 main関数 show関数 friendのアドレス pcにアドレスが渡される メンバはコピーされない もし、pc->age += 3とすれば、friendのageも3増えることになる 書込め
構造体に値を入力する関数を作る 構造体へのポインタを引数に受け取って、その構造体に値を入力させる関数Inputを作る void Input( Info *p )
構造体へのポインタpという仮引数で受け取る 関数showは値を変更しないので、ポインタで受け取る必要がない void Input( Info *p ) { printf(“名前を入力してください:”); scanf(“%s”, p->name); printf(“電話番号を入力してください:”); scanf(“%s”, p->tel); printf(“年齢を入力してください”); scanf(“%d”, &p->age); } void show( Info c ) printf(“名前は%s\n”, c.name); printf(“電話番号は%s\n”, c.tel); printf(“年齢は%d\n”, c.age); 構造体へのポインタpという仮引数で受け取る 書込め 書込め 書込め 関数showは値を変更しないので、ポインタで受け取る必要がない 書込め
Input( &(person[1]) ); show(my_friend); show( person[1] ); 構造体変数を定義 #include <stdio.h> #include <string.h> /*構造体型のInfoの宣言*/ typedef struct { char name[20]; char tel[16]; int age; }Info; /*関数のプロトタイプ宣言 */ void show( Info c ); void Input( Info *pc ); main() { Info my_friend; Info person[3]; Input( &my_friend ); Input( &(person[1]) ); show(my_friend); show( person[1] ); } 構造体変数を定義 Input( person + 1 ) でも同じ 書込め 書込め 書込め