Presentation is loading. Please wait.

Presentation is loading. Please wait.

プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.

Similar presentations


Presentation on theme: "プログラミング入門2 第10回 構造体 情報工学科 篠埜 功."— Presentation transcript:

1 プログラミング入門2 第10回 構造体 情報工学科 篠埜 功

2 今回の内容 構造体

3 構造体 3人分の学生の身体検査のデータ char name[3][20]; /* 3人分の学生の名前 */
int height[3]; /* 3人分の学生の身長 */ double weight[3]; /* 3人分の学生の体重 */ 各学生の情報が、3つの配列にばらばらに格納される。 => ひとつにまとめることができると便利がよい。

4 構造体とは? 3人の学生の身体検査のデータ char name[3][20]; /* 3人分の学生の名前 */
int height[3]; /* 3人分の学生の身長 */ double weight[3]; /* 3人分の学生の体重 */ 1人目のデータ 2人目のデータ 3人目のデータ name[0] = “Taro”; height[0] = 176; weight[0] = 64.5 name[1] = “Jiro”; height[1] = 165; weight[1] = 55.5; name[2] = “Saburo”; height[2] = 168; weight[2] = 70.0 各人の3つのデータが別々の配列に入っている。 各人のデータを1つにまとめたい。

5 構造体とは? 構造体とは,複数の型のデータをひとまとめにしたデータ構造 char [20] 型 int 型 double 型 “Taro”
名前 身長 体重 char [20] 型 int 型 double 型 名前 身長 体重 “Taro” 176 64.5 名前 身長 体重 “Jiro” 165 55.5 名前 身長 体重 “Saburo” 168 70.0

6 構造体型 struct { 変数宣言1; 変数宣言2; … } (例) struct { char name[20];
これまで、複合型(基本データを組み合わせて得られる型)として、配列型を扱ってきた。構造体型も複合型である。構造体型は、いくつかの変数宣言がまとまったものであり、以下の形のものである。 struct { 変数宣言1; 変数宣言2; } (例) struct { char name[20]; int height; double weight; } 名前 char [20] 型 身長 int 型 体重 double 型

7 構造体型の変数宣言  変数名; 構造体型の変数宣言の構文 を構造体型を表す型式とすると、 taro (例) struct {
 変数名; taro.name taro (例) struct { char name[20]; int height; double weight; } taro; 20byte taro.height 4byte taro.weight 8byte 宣言する変数名 プログラミング入門2

8 構造体のメンバーアクセス 式eが、メンバー名がmのメンバーを持つ構造体型の式のとき、e.mで構造体のメンバーが得られる。 . をドット演算子と呼ぶ。 (例)taroを前頁の構造体型の変数として宣言する。 struct { char name[20]; int height; double weight; } taro; taro.name, taro.height, taro.weightで各メンバーにアクセスできる。

9 例(打ち込んで確認) #include <stdio.h> int main (void) { struct {
char name[20]; int height; double weight; } taro; taro.name[0] = 'T'; taro.name[1] = 'a'; taro.name[2] = 'r'; taro.name[3] = 'o'; taro.name[4] = '\0'; taro.height = 176; taro.weight = 64.5; printf ("%sの身長は%dcm、体重は%fkgです。\n", &(taro.name[0]), taro.height, taro.weight); return 0; } 例(打ち込んで確認)

10 構造体型の変数の初期化 #include <stdio.h> int main(void) { struct {
char name[20]; /* 名前 */ int height; /* 身長 */ double weight; /* 体重 */ } taro = {“Taro", 176, 64.5}; printf(“%sの身長は%dcm、体重は%fkgです。\n", taro.name, taro.height, taro.weight); return 0; } 構造体の初期化は{ } を使って記述する。

11 typedefの使用 構造体を使うとき、構造体型に、typedefで名前を付けると便利がよい。 typedefは、
の形で使う。 (例1) typedef int aaa; と宣言すると、aaaはintの別名。 (例2) typedef int bbb [3];と宣言すると、bbbはint [3]型の別名。 (例3) typedef struct { char name[20]; int height; double weight; } student; と宣言すると、studentは struct { } 型の別名。

12 構造体型に名前をつける例(打ち込んで確認)
#include <stdio.h> int main(void) { typedef struct{ char name[20]; /* 名前 */ int height; /* 身長 */ double weight; /* 体重 */ } student; student taro = {“Taro“, 176, 64.5}; printf(“%sの身長は%dcm、体重は%fkgです。\n", taro.name, taro.height, taro.weight); return 0; }

13 構造体の代入(p.280) 同じ型の構造体であれば,代入することが可能 student taro;
student jiro = {“Jiro”, 165, 55.5}; taro = jiro; taro=jiroの代入式によって、jiro.name, jiro.height, jiro.weight がそれぞれtaro.name. taro.height, taro.weightに代入される。

14 復習: 配列のコピー (p.93) int a[5]; int b[5];と宣言すると、aとbは型は同じだが、b=aという代入式は書けない。要素毎に代入を行う必要がある。 i = 0; while (i < 5) { b[i] = a[i]; i = i + 1; } 復習 配列型の式eの値は、(sizeofの引数、&の引数の場合を除いて)その先頭要素e[0]のアドレスである。(この場合、式eは式&e[0]で置き換えても同じ。)

15 関数への構造体データの受け渡し(構造体をコピーする例) (打ち込んで確認)
#include <stdio.h> typedef struct { char name[20]; /* 名前 */ int height; /* 身長 */ double weight; /* 体重 */ } student; void print_data( student std ) { printf(“%sの身長は%dcm、体重は%fkgです。\n", std.name, std.height, std.weight); } int main(void) student taro = {“Taro", 176, 64.5}; print_data( taro ); return 0; 構造体taroのコピーがstdに代入され、 print_dataの本体が実行される。

16 関数への構造体データの受け渡し(ポインタを渡す例) (打ち込んで確認)
#include <stdio.h> typedef struct { char name[20]; /* 名前 */ int height; /* 身長 */ double weight; /* 体重 */ } student; void change_data( student * std ) { (*std).height = 180; (*std).weight = 80.0; } int main(void) student taro = {“Taro", 176, 64.5}; change_data( &taro ); printf(“%sの身長は%dcm、体重は%fkgです。\n", taro.name, taro.height, taro.weight); return 0; 構造体taroへのポインタを受け取る。

17 解説 構造体のポインタ渡し *stdはtaro のエイリアス void change_data( student * std ) {
(*std).height = 180; (*std).weight = 80.0; } taro 106番地 106 change_data( &taro ); std (注意) *std.heightと書くと、 *(std.height)と解釈される。 student型のオブジェクトのアドレス を入れるための箱

18 = アロー演算子 -> 式 eが、構造体(型)へのポインタ型( * 型)の式のとき、その構造体のメンバm は (*e).m
void change_data( student *std ) { (*std).height = 180; (*std).weight = 80.0; } void change_data( student * std ) { std->height = 180; std->weight = 80.0; } = change_data( &taro ); 式 eが、構造体(型)へのポインタ型( * 型)の式のとき、その構造体のメンバm は (*e).m で得られるが、これは e -> m と書いてもよい(syntax sugar)。

19 例(打ち込んで確認) #include <stdio.h> typedef struct {
char name[20]; /* 名前 */ int height; /* 身長 */ double weight; /* 体重 */ } student; void change_data(student * std ) { std->height = 180; std->weight = 80.0; } int main(void) student taro = {“Taro", 176, 64.5}; change_data( &taro ); printf(“%sの身長は%dcm、体重は%fkgです。\n", taro.name, taro.height, taro.weight); return 0;

20 (注意)構造体内の配列について 構造体内に配列があるとき、
構造体を関数に渡したら配列の各値もコピーが渡される。(よって、関数内で配列の値を書き変えても呼び出し元の配列には影響がない。) 構造体を構造体型の変数に代入するとき、配列の各値も代入される。

21 S 今日の課題1 キーボードから3点の2次元座標値(x, y)を読み込み, 3点から作られる3角形の面積Sを出力するプログラムを作成せよ。
p2 S = (ax, ay) = (bx, by) p3 のとき、S = ½ | ax by – ay bx | p1 但し,座標を格納する構造体として以下のものを用いること。 typedef struct { double x; double y; } point; (注) double型の値の読み込みは、 scanf (“%lf”, &p.x); の様にする。(pがpoint型の場合) printfで表示の場合は%f。(printf (“%f”, p.x)など) 面積を求める関数は、座標を表すpoint型の引数p1, p2, p3を受け取り、面積をdouble型で求め、それを返り値として返す関数として定義せよ。    double area (point p1, point p2, point p3) { … }

22 今日の課題2 キーボードから2つの複素数を読み込み、その2つの複素数の和を出力するプログラムを作成せよ。ただし、複素数を表すために、以下の構造体 complex を用い、複素数の和は、関数を呼び出す形で求めよ。複素数のキーボードからの入力、画面への出力の形式は自由とする。 typedef struct { double re; double im; } complex; 和を求める関数は、複素数を表すcomplex型の引数c1, c2を受け取って、それらの和を表すcomplex型の値を返す関数として定義せよ。 complex sum (complex c1, complex c2) { …. }

23 構造体を返す関数の例 #include <stdio.h> typedef struct{ int x; int y;
} point; point makePoint (int x, int y) { point p; p.x = x; p.y = y; return p; } int main (void) { p = makePoint (2,3); printf ("x=%d, y=%d\n", p.x, p.y); return 0;

24 チャレンジ課題 課題2と同様のことを、複素数の差、積、商について行え。
以下の3つの関数を定義し、それぞれmain関数から呼び出し、結果を受け取り、結果をmain関数内で表示せよ。 complex diff (complex c1, complex c2) { …. } complex prod (complex c1, complex c2) { complex div (complex c1, complex c2) {


Download ppt "プログラミング入門2 第10回 構造体 情報工学科 篠埜 功."

Similar presentations


Ads by Google