プログラミング入門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 第10回 芝浦工業大学情報工学科 青木 義満
プログラミング入門2 第4回 配列 for文 変数宣言 初期化
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
プログラミング入門2 第10回 動的な領域確保 情報工学科 篠埜 功.
第12回新しい型と構造体.
第13回構造体.
課題解説: 関数の引数にポインタを使って2数を入れ替える
解答 1 複素数を構造体として定義し、二つの複素数の積(結果は複素数)を返す 関数 を定義せよ。
第12回構造体.
プログラミング入門2 ポインタについて補足 構造体 第11回 芝浦工業大学情報工学科 青木 義満、篠埜 功
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第1回 導入 情報工学科 篠埜 功.
プログラミング入門2 第6回 関数(2) 芝浦工業大学情報工学科 青木 義満
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
理由:文字数より要素数の多い配列を用いた時に,文字列の最後を示すため
構造体.
第16章 構造体 16.1 構造体の定義と構造体変数 16.2 構造体の配列.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
第16章 構造体 16.1 構造体の定義と構造体変数 16.2 構造体の配列.
演習問題の答え #include #include #define NUM 5 typedef struct { // 構造体の定義 float shincho; // 身長 float taiju; // 体重 } shintai; void hyouji(shintai.
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
構造体 プログラミング入門2 芝浦工業大学情報工学科 青木 義満
構造体 構造体, 構造体とポインタの組み合わせ,.
プログラミング 3 構造体(1).
第10回 プログラミングⅡ 第10回
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
第11回 宿題 出題日:12月21日 締切日:1月7日(木).
精密工学科プログラミング基礎 第10回資料 (12/18実施)
プログラミング入門2 第12回 構造体の配列 データ型 関数のプロトタイプ宣言 動的な記憶域確保 芝浦工業大学情報工学科
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
プログラミング入門2 第8回 ポインタ 情報工学科 篠埜 功.
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
プログラミング入門2 第11回 情報工学科 篠埜 功.
今までの練習問題の復習.
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
プログラミング入門2 第11回 共用体、列挙体 情報工学科 篠埜 功.
第11回 プログラミングⅡ 第11回
プログラミング入門 第12回 情報工学科 篠埜 功.
プログラミング入門 第12回 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第9回(後半第3回) 岩村雅一
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
精密工学科プログラミング基礎Ⅱ 第5回資料 今回の授業で習得してほしいこと: 構造体 (教科書 91 ページ)
C言語 はじめに 2016年 吉田研究室.
構造体と共用体.
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
プログラミング序論演習.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
ネットワーク・プログラミング Cプログラミングの基礎.
プログラミング入門2 第5回 配列 for文 変数宣言 初期化
プログラミング論 構造体
プログラミング入門 第12回 情報工学科 篠埜 功.
プログラミング入門2 第2回 型と演算 条件分岐 篠埜 功.
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
第3回簡単なデータの入出力.
四則演算,変数 入力文,出力文,代入文, ライブラリ関数
マスク合成(のような処理) 出力画像 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) 繰り返し文 篠埜 功.
知能情報工学演習I 第9回(後半第3回) 課題の回答
C言語講座第5回 2017 構造体.
高度プログラミング演習 (10).
岩村雅一 知能情報工学演習I 第9回(C言語第3回) 岩村雅一
Presentation transcript:

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

今回の内容 構造体

構造体とは 学生の身体検査のデータ 太郎君の身体検査のデータ char name[20]; /* 名前 */ int height; /* 身長 */ double weight; /* 体重 */ 太郎君の身体検査のデータ name: “Taro” height: 176 weight: 64.5 このようなデータを一つのかたまりとして扱いたい。

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

構造体型 struct { 変数宣言; … } (例) struct { char name[20]; int height; これまで、複合型(基本データを組み合わせて得られる型)として、配列型を扱ってきた。構造体型も複合型である。構造体型は、いくつかの変数宣言がまとまったものであり、以下の形のものである。 struct { 変数宣言; … } (例) struct { char name[20]; int height; double weight; } name char [20] 型 height int 型 weight 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でtaroの各メンバーが得られる。

例(打ち込んで確認) #include <stdio.h> #include <string.h> int main (void) { struct { char name[20]; int height; double weight; } taro; strcpy (taro.name, “Taro”); taro.height = 176; taro.weight = 64.5; printf ("%sの身長は%dcm、体重は%fkgです。\n", &(taro.name[0]), taro.height, taro.weight); return 0; } 例(打ち込んで確認) 文字列を配列に代入するときに strcpyを用いると便利が良い。

構造体型の変数の初期化 #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; } 構造体の初期化は{ } を使って記述する。それぞれ対応するメンバーが初期化される。 char型の配列の初期化は、 char name [20] = ”Taro”; のように書いてよい。 (注意) char型の配列nameに対し、name=“Taro”のように代入することはできない。

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; } 106 taro 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; } = 式 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;

構造体を返す関数(打ち込んで確認) #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,y) = (%d, %d)\n", p.x, p.y); return 0; xy平面上の点を表すために、int型の変数x,yからなる構造体型を定義し、それにpointという名前をつけている。

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

基本課題1 キーボードから3人分の名前および数学、英語の点数をint型で入力し、各科目の平均点をdouble型で小数点第一位まで求めよ。 (実行例) 名前を入力してください: Taro 数学の点数を入力してください: 80 英語の点数を入力してください: 90 名前を入力してください: Jiro 数学の点数を入力してください: 70 英語の点数を入力してください: 70 名前を入力してください: Saburo 数学の点数を入力してください: 90 英語の点数を入力してください: 60 数学の平均点は80.0点、英語の平均点は73.3点です。 (注) printfで変換指定を%.1fとすると小数点第一位までの表示となる。

基本課題2 キーボードから2つの複素数を読み込み、その2つの複素数の和を出力するプログラムを作成せよ。ただし、複素数を表すために、以下の構造体 complex を用い、複素数の和は、関数を使って求めよ。 typedef struct { int re; int im; } complex; 和を求める関数は、複素数を表すcomplex型の引数c1, c2を受け取って、それらの和を表すcomplex型の値を返す関数として定義せよ。 complex sum (complex c1, complex c2) { …. } (実行例) 複素数aの実数部を入力してください: 2 複素数aの虚数部を入力してください: 3 複素数bの実数部を入力してください: 4 複素数bの虚数部を入力してください: 5 a + b = 6 + 8i です。

発展課題1 基本課題2と同様のことを、複素数の積について行え。 積を求める関数は、複素数を表すcomplex型の引数c1, c2を受け取って、それらの積を表すcomplex型の値を返す関数として定義せよ。 complex prod (complex c1, complex c2) { …. }

発展課題2 キーボードから3点の2次元座標値(x, y)をdouble型で読み込み,3点から作られる3角形の面積Sをdouble型で出力するプログラムを作成せよ。 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での表示は、 printf (“%f”, p.x); のようにする。 面積を求める関数は、座標を表すpoint型の引数p1, p2, p3を受け取り、面積をdouble型で求め、それを返り値として返す関数として定義せよ。    double area (point p1, point p2, point p3) { … }

発展課題3 基本課題1のプログラムに、それぞれの科目ごとに得点の高い順に名前を表示する処理を追加せよ。 (実行例) 名前を入力してください: Taro 数学の点数を入力してください: 80 英語の点数を入力してください: 90 名前を入力してください: Jiro 数学の点数を入力してください: 70 英語の点数を入力してください: 70 名前を入力してください: Saburo 数学の点数を入力してください: 90 英語の点数を入力してください: 60 数学の平均点は80.0点、英語の平均点は73.3点です。 科目毎に得点の高い順に並べると、 数学: Saburo, Taro, Jiro, 英語: Taro, Jiro, Saburoです。