第11回

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