Top Banner
プププププププププププ 10 プププププ ププ
24

プログラミング入門2 第10回 構造体

Mar 15, 2016

Download

Documents

gary-boyer

プログラミング入門2 第10回 構造体. 情報工学科 篠埜 功. 今回の内容. 構造体. 構造体. 3 人分の学生の身体検査のデータ char name[3][20];/* 3 人分の学生の名前 * / int height[3]; /* 3 人分の学生の身長 * / double weight[3];/* 3 人分の学生の体重 * /. 各学生の情報が、3つの配列にばらばらに格納される。 => ひとつ に まとめることができると便利がよい。. 各人のデータを1つにまとめたい。. 構造体とは?. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: プログラミング入門2 第10回 構造体

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

Page 2: プログラミング入門2 第10回 構造体

今回の内容• 構造体

Page 3: プログラミング入門2 第10回 構造体

構造体

• 3 人分の学生の身体検査のデータ char name[3][20]; /* 3 人分の学生の名前 */ int height[3]; /* 3 人分の学生の身長 */ double weight[3]; /* 3 人分の学生の体重 */

各学生の情報が、3つの配列にばらばらに格納される。=> ひとつにまとめることができると便利がよい。

Page 4: プログラミング入門2 第10回 構造体

構造体とは?

• 3 人の学生の身体検査のデータ char name[3][20]; /* 3 人分の学生の名前 */

int height[3]; /* 3 人分の学生の身長 */ double weight[3]; /* 3 人分の学生の体重 */

1 人目のデータ name[0] = “Taro”; height[0] = 176; weight[0] = 64.5

2 人目のデータ name[1] = “Jiro”; height[1] = 165; weight[1] = 55.5;

各人の3つのデータが別々の配列に入っている。

各人のデータを1つにまとめたい。

3 人目のデータ name[2] = “Saburo”; height[2] = 168; weight[2] = 70.0

Page 5: プログラミング入門2 第10回 構造体

構造体とは?

構造体とは,複数の型のデータをひとまとめにしたデータ構造名前身長体重

char [20] 型int 型double 型

名前身長体重

“Taro”

176

64.5

名前身長体重

“Jiro”

165

55.5

名前身長体重

“Saburo”

168

70.0

Page 6: プログラミング入門2 第10回 構造体

構造体型

(例) struct { char name[20]; int height; double weight;}

名前身長体重

char [20] 型int 型

double 型

これまで、複合型(基本データを組み合わせて得られる型)として、配列型を扱ってきた。構造体型も複合型である。構造体型は、いくつかの変数宣言がまとまったものであり、以下の形のものである。struct { 変数宣言 1; 変数宣言 2; …}

Page 7: プログラミング入門2 第10回 構造体

プログラミング入門2 7

構造体型の変数宣言

(例) struct { char name[20]; int height; double weight; } taro;

• 構造体型の変数宣言の構文 を構造体型を表す型式とすると、

宣言する変数名taro.weight

taro.height

taro.nametaro

20byte

4byte

8byte

変数名 ;

Page 8: プログラミング入門2 第10回 構造体

構造体のメンバーアクセス

• 式 e が、メンバー名が m のメンバーを持つ構造体型の式のとき、 e.m で構造体のメンバーが得られる。 . をドット演算子と呼ぶ。

struct { char name[20]; int height; double weight;} taro;

taro.name, taro.height, taro.weightで各メンバーにアクセスできる。

(例) taro を前頁の構造体型の変数として宣言する。

Page 9: プログラミング入門2 第10回 構造体

例(打ち込んで確認)#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;}

Page 10: プログラミング入門2 第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;}

Page 11: プログラミング入門2 第10回 構造体

typedef の使用• 構造体を使うとき、構造体型に、 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 { char name[20]; int height; double weight;} 型の別名。

Page 12: プログラミング入門2 第10回 構造体

構造体型に名前をつける例(打ち込んで確認)

#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;}

Page 13: プログラミング入門2 第10回 構造体

構造体の代入( 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 に代入される。

Page 14: プログラミング入門2 第10回 構造体

• int a[5]; int b[5]; と宣言すると、 a と b は型は同じだが、 b=a という代入式は書けない。要素毎に代入を行う必要がある。

復習: 配列のコピー ( p.93 )

復習配列型の式 e の値は、( sizeof の引数、 & の引数の場合を除いて)その先頭要素 e[0] のアドレスである。( この場合、式 e は式 &e[0] で置き換えても同じ。 )

i = 0; while (i < 5) { b[i] = a[i]; i = i + 1; }

Page 15: プログラミング入門2 第10回 構造体

関数への構造体データの受け渡し(構造体をコピーする例)(打ち込んで確認)

#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 の本体が実行される。

Page 16: プログラミング入門2 第10回 構造体

関数への構造体データの受け渡し(ポインタを渡す例)(打ち込んで確認)

#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 へのポインタを受け取る。

Page 17: プログラミング入門2 第10回 構造体

解説

構造体のポインタ渡し

change_data( &taro );

void change_data( student * std ){ (*std).height = 180; (*std).weight = 80.0;}

std

taro

*std は taro のエイリアス

106 番地106

student 型のオブジェクトのアドレスを入れるための箱

(注意) *std.height と書くと、 *(std.height) と解釈される。

Page 18: プログラミング入門2 第10回 構造体

アロー演算子 ->

change_data( &taro );

void change_data( student *std ) { (*std).height = 180; (*std).weight = 80.0;}

void change_data( student * std ) { std->height = 180; std->weight = 80.0;}

=

式 e が、構造体(型)へのポインタ型 ( * 型 ) の式のとき、その構造体のメンバ m は (*e).mで得られるが、これは e -> mと書いてもよい( syntax sugar )。

Page 19: プログラミング入門2 第10回 構造体

例(打ち込んで確認)#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;}

Page 20: プログラミング入門2 第10回 構造体

(注意)構造体内の配列について• 構造体内に配列があるとき、

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

Page 21: プログラミング入門2 第10回 構造体

今日の課題1

– キーボードから 3 点の 2 次元座標値( x, y )を読み込み, 3 点から作られる 3 角形の面積 S を出力するプログラムを作成せよ。

ab

S

但し,座標を格納する構造体として以下のものを用いること。typedef struct { double x; double y;} point;

( 注 ) double 型の値の読み込みは、 scanf (“%lf”, &p.x);の様にする。 (p が point 型の場合 )printf で表示の場合は %f 。 (printf (“%f”, p.x) など )

a = (ax, ay) b = (bx, by)

のとき、 S = ½ | ax by – ay bx |

p1

p2

p3

面積を求める関数は、座標を表す point 型の引数 p1, p2, p3 を受け取り、面積を double 型で求め、それを返り値として返す関数として定義せよ。    double area (point p1, point p2, point p3) { … }

Page 22: プログラミング入門2 第10回 構造体

今日の課題2

– キーボードから2つの複素数を読み込み、その2つの複素数の和を出力するプログラムを作成せよ。ただし、複素数を表すために、以下の構造体 complex を用い、複素数の和は、関数を呼び出す形で求めよ。複素数のキーボードからの入力、画面への出力の形式は自由とする。

typedef struct { double re; double im; } complex;

和を求める関数は、複素数を表す complex 型の引数 c1, c2 を受け取って、それらの和を表す complex 型の値を返す関数として定義せよ。 complex sum (complex c1, complex c2) { …. }

Page 23: プログラミング入門2 第10回 構造体

構造体を返す関数の例#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) { point p; p = makePoint (2,3); printf ("x=%d, y=%d\n", p.x, p.y); return 0;}

Page 24: プログラミング入門2 第10回 構造体

チャレンジ課題

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