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

Slides:



Advertisements
Similar presentations
構造体 構造体とは? 複数のデータをパックしたもの。 新しい “ 型 “ として使用できる. 構造体 キーワード struct strcut は構造体を宣言する命令。 struct { double x,y; }a,b,c; ↑ ここまでが宣 言 ← この形式で、構造体 a,b,c, を定 義.
Advertisements

プログラミング入門2 芝浦工業大学情報工学科青木 義満 第11回構造体. プログラミング入門2 2 構造体 5 人分のサッカー選手データ 全てのデータを関数に渡して,処理する場合 char name[5][256]; int assist[5]; int score[5]; void func( char.
C 言語講座第 5 回 構造体. 構造体とは ... 異なる型の値をまとめて新しい型とする 機能がある . つまり , 複数の変数を 1 つのまとまりにできる . 配列と違って同じ型でデータをまとめるのではな く違った型のデータをまとめられる .
アルゴリズムとデータ構造 第2回 線形リスト(復習).
ポインタ プログラミング入門2 第10回 芝浦工業大学情報工学科 青木 義満
プログラミング入門2 第4回 配列 for文 変数宣言 初期化
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
プログラミング入門2 第10回 動的な領域確保 情報工学科 篠埜 功.
第12回新しい型と構造体.
第13回構造体.
第12回構造体.
プログラミング入門2 ポインタについて補足 構造体 第11回 芝浦工業大学情報工学科 青木 義満、篠埜 功
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
プログラミング入門2 第1回 導入 情報工学科 篠埜 功.
プログラミング入門2 第6回 関数(2) 芝浦工業大学情報工学科 青木 義満
構造体.
第16章 構造体 16.1 構造体の定義と構造体変数 16.2 構造体の配列.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
演習問題の答え #include #include #define NUM 5 typedef struct { // 構造体の定義 float shincho; // 身長 float taiju; // 体重 } shintai; void hyouji(shintai.
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
構造体 プログラミング入門2 芝浦工業大学情報工学科 青木 義満
精密工学科プログラミング基礎Ⅱ 第3回資料 今回の授業で習得してほしいこと: 2次元配列の使い方 (前回の1次元配列の復習もします.)
構造体 構造体, 構造体とポインタの組み合わせ,.
プログラミング 3 構造体(1).
第10回 プログラミングⅡ 第10回
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
C言語講座 第3回 ポインタ、配列.
プログラミング入門2 第5回 関数(1) 芝浦工業大学情報工学科 青木 義満
第11回 宿題 出題日:12月21日 締切日:1月7日(木).
精密工学科プログラミング基礎 第10回資料 (12/18実施)
プログラミング入門2 第12回 構造体の配列 データ型 関数のプロトタイプ宣言 動的な記憶域確保 芝浦工業大学情報工学科
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
プログラミング入門2 第8回 ポインタ 情報工学科 篠埜 功.
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング入門2 第11回 情報工学科 篠埜 功.
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
プログラミング入門2 第11回 共用体、列挙体 情報工学科 篠埜 功.
第11回 プログラミングⅡ 第11回
プログラミング入門 第12回 情報工学科 篠埜 功.
プログラミング入門 第12回 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
復習 前回の関数のまとめ(1) プログラムはmain()関数の先頭から実行される
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
精密工学科プログラミング基礎Ⅱ 第5回資料 今回の授業で習得してほしいこと: 構造体 (教科書 91 ページ)
構造体と共用体.
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
プログラミング 3 2 次元配列.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
ポインタとポインタを用いた関数定義.
ネットワーク・プログラミング Cプログラミングの基礎.
第5回 プログラミングⅡ 第5回
プログラミング入門2 第5回 配列 for文 変数宣言 初期化
プログラミング論 構造体
プログラミング入門 第12回 情報工学科 篠埜 功.
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
cp-3. 計算 (C プログラミング演習,Visual Studio 2019 対応)
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
マスク合成(のような処理) 出力画像 Out 入力画像1 In1 In1 In2 Out 入力画像2 In
左右反転と180度回転 [0][xsize – 1] [0][0] → i ↓ j [ysize – 1][xsize – 1]
プログラミング入門2 第5回 配列 変数宣言、初期化について
プログラミング入門2 第3回 条件分岐(2) 繰り返し文 篠埜 功.
C言語講座第5回 2017 構造体.
プログラミング 3 ポインタ(1).
Presentation transcript:

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

今回の内容 構造体

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

構造体とは? 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つにまとめたい。

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

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

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

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

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

構造体型の変数の初期化 #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; } 構造体の初期化は{ } を使って記述する。

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 { } 型の別名。

構造体型に名前をつける例(打ち込んで確認) #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; }

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

復習: 配列のコピー (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]で置き換えても同じ。)

関数への構造体データの受け渡し(構造体をコピーする例) (打ち込んで確認) #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の本体が実行される。

関数への構造体データの受け渡し(ポインタを渡す例) (打ち込んで確認) #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へのポインタを受け取る。

解説 構造体のポインタ渡し *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型のオブジェクトのアドレス を入れるための箱

= アロー演算子 -> 式 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)。

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

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

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) { … }

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

構造体を返す関数の例 #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;

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