Download presentation
Presentation is loading. Please wait.
1
構造体 プログラミング入門2 芝浦工業大学情報工学科 青木 義満
I’ll get started with Introduction and Conventional works around our study, then mention our motivation and goal. Next, I’ll explain our 3D Face Modeling Method and its medical application. Finally, I’ll conclude this presentation with some future works. 芝浦工業大学情報工学科 青木 義満
2
構造体 構造体の必要性! 5人分のサッカー選手データ 全てのデータを関数に渡して,処理する場合
char name[5][256]; int assist[5]; int score[5]; void func( char name[ ][256], int assist[ ], int score[ ] ) void func( char name[ ][256], int *assist, int *score) ・氏名 ・所属チーム ・得点 ・アシスト ・年俸 ・・・・・ 選手 データをひとまとめにして 効率良くデータを管理・処理したい 構造体の必要性! プログラミング入門2
3
構造体とは? 多人数の学生の身体検査のデータ 各配列は独立していて,それぞれの関連性がわかりにくい
char name[5][256]; /* 5人分の学生の名前 */ int height[5]; /* 5人分の学生の身長 */ double weight[5]; /* 5人分の学生の体重 */ 1人目のデータ 2人目のデータ name[0][256] height[0] weight[0] name[1][256] height[1] weight[1] 各配列は独立していて,それぞれの関連性がわかりにくい 個人のデータを“カード”でまとめて表し,そのカードを人数分用意 プログラミング入門2
4
構造体とは? 重要 構造体とは,ひとまとまりのデータを集めたデータ構造である 1枚のカード 名前 芝浦 義満 身長 168cm
名前 芝浦 義満 身長 168cm 体重 70kg 名前 身長 体重 char 型 int 型 double 型 1枚のカード 名前 芝浦 次郎 身長 165cm 体重 55.5kg 名前 芝浦 太郎 身長 176cm 体重 64.5kg 複数の型のデータを ひとまとめにして扱う! プログラミング入門2
5
構造体の宣言 ~自分で新しい“型”をつくる
構造体の宣言 ~自分で新しい“型”をつくる 構造体を宣言することは,意味のあるデータをひとまとまりにした,新しい変数の“型“を自分で作ることである 宣言の方法 1枚のカードをどう作るか? 手順 ①どんなデータをひとまとめにして扱うかを決定 ②構造体の名前(変数の型)を決定 typedef struct type(型)を define(定義) 構造体 { } 中括弧でくくって ひとまとめに char name[256]; int height; double weight; 構造体のメンバーという 構造体の名前(型名) ※int, double などと同じ役割 ※セミコロン忘れずに! student ; プログラミング入門2
6
構造体データの使い方 変数(オブジェクト)の宣言 構造体内のメンバーへのアクセス char name[256]; int height;
int x; int型のオブジェクト x を宣言 student aoki; student型のオブジェクト aoki を宣言 { } char name[256]; int height; double weight; typedef struct student student aoki; 構造体オブジェクト aoki は,以下のメンバを持つ aoki.name[256] aoki.height aoki.weight 構造体のメンバはドット(.)演算子でアクセス可能 構造体の定義 プログラミング入門2
7
構造体を使ったプログラム(構造体のメンバ)
ソースファイル名:list1203.c (p.274, 若干変更) 構造体メンバへの値の代入と表示 #include <stdio.h> #include <string.h> /* 文字列操作関数用 strcpy使用のため*/ typedef struct{ char name[20]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ } student; int main(void) { student sanaka; /* 構造体メンバへの値の代入 */ strcpy(sanaka.name, "Sanaka"); /* 文字列sanakaをsanaka.nameにコピー */ sanaka.height = 175; /* 身長 */ sanaka.weight = 60.5; /* 体重 */ /* 構造体メンバの表示 */ printf("氏 名 = %s\n", sanaka.name); printf("身 長 = %d\n", sanaka.height); printf("体 重 = %f\n", sanaka.weight); return (0); } プログラミング入門2
8
解説 typedef struct{ char name[20]; /* 名前 */ int height; /* 身長 */
float weight; /* 体重 */ } student; int main(void) { student sanaka; /* 構造体メンバへの値の代入 */ strcpy(sanaka.name, "Sanaka"); /* 文字列sanakaをsanaka.nameにコピー */ sanaka.height = 175; /* 身長 */ sanaka.weight = 60.5; /* 体重 */ strcpy(sanaka.name, "Sanaka"); 文字配列へのポインタ 文字配列(sanaka.name)に“Sanaka”を代入 プログラミング入門2
9
構造体を使ったプログラム(メンバの初期化)
ソースファイル名:list1204.c (p.275, 若干変更) 構造体メンバの初期化 /* 学生を表す構造体で表した佐中君を初期化 */ #include <stdio.h> typedef struct { char name[20]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ } student; int main(void) { student sanaka = {"Sanaka", 175, 60.5}; printf("氏 名 = %s\n", sanaka.name); printf("身 長 = %d\n", sanaka.height); printf("体 重 = %f\n", sanaka.weight); return (0); } 構造体メンバの初期化 プログラミング入門2
10
配列では不可能! 構造体同士の値の代入 (p.280) student aoki, maeda; aoki = maeda;
同じ種類の構造体データであれば,互いに値を代入することが可能 student aoki, maeda; aoki = maeda; maedaのメンバ(name, height, weight) をそれぞれaokiの対応するメンバに代入 配列では不可能! プログラミング入門2
11
復習: 配列のコピー 注意点 (p.93) vb = va ; for (i = 0; i < 5; i++)
va[5], vb[5] と2つの配列は要素数も同じだし,もっと簡単に次のように代入できないの? vb = va ; for (i = 0; i < 5; i++) vb[i] = va[i]; 面倒でも,1つ1つ代入していく 重要 代入演算子によって,配列を代入することはできない プログラミング入門2
12
関数での構造体データの使用(値変更なし)
ソースファイル名:struct1.c 関数への構造体データの受け渡し(値は変更しない) #include <stdio.h> typedef struct { char name[20]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ } student; void print_data( student std ) { printf("氏 名 = %s\n", std.name); printf("身 長 = %d\n", std.height); printf("体 重 = %f\n", std.weight); } int main(void) student sanaka = {"Sanaka", 175, 60.5}; print_data( sanaka ); return (0); 構造体データを受け取り, 値を表示する関数 値を変更しない→ポインタでなくてOK プログラミング入門2
13
関数での構造体データの使用(値変更あり)
ソースファイル名:struct2.c 関数への構造体データの受け渡し(値の変更あり) #include <stdio.h> typedef struct { char name[20]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ } student; void change_data( student *std ) { (*std).height = 180; (*std).weight = 80.0; } int main(void) student sanaka = {"Sanaka", 175, 60.5}; change_data( &sanaka ); printf("氏 名 = %s\n", sanaka.name); printf("身 長 = %d\n", sanaka.height); printf("体 重 = %f\n", sanaka.weight); return (0); 構造体データを受け取り, 値を変更する関数 値を変更する→ポインタ(アドレス)で受け取り! プログラミング入門2
14
解説 構造体のポインタ渡し std (*std).height → *std.height change_data( &sanaka );
*stdはsanaka のエイリアス 106番地 void change_data( student *std ) { (*std).height = 180; (*std).weight = 80.0; } 106番地 sanaka *std std (*std).height → *std.height student型のオブジェクトのアドレス を入れるための箱 (student型オブジェクトへのポインタ) ()は省略不可 *よりも.の方が優先順位が高いため, *(std.height)と解釈されてしまう! プログラミング入門2
15
関数での構造体データの使用(値変更あり)
ソースファイル名:struct3.c(p.277,変更あり) 関数への構造体データの受け渡し(値の変更あり,アロー演算子使用) #include <stdio.h> typedef struct { char name[20]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ } student; void change_data( student *std ) { std->height = 180; std->weight = 80.0; } int main(void) student sanaka = {"Sanaka", 175, 60.5}; change_data( &sanaka ); printf("氏 名 = %s\n", sanaka.name); printf("身 長 = %d\n", sanaka.height); printf("体 重 = %f\n", sanaka.weight); return (0); 構造体データを受け取り, 値を変更する関数 値を変更する→ポインタ(アドレス)で受け取り! プログラミング入門2
16
= アロー(->)演算子 std->height = 180; 重要 change_data( &sanaka );
void change_data( student *std ) { (*std).height = 180; (*std).weight = 80.0; } void change_data( student *std ) { std->height = 180; std->weight = 80.0; } = std->height = 180; 構造体へのポインタ名 -> メンバ 重要 ポインタptrが指す構造体のメンバmemである(*ptr).memは, ->演算子を用いてptr->memと簡潔に記述せよ プログラミング入門2
17
複数のデータの扱い (構造体の配列, p.282) 構造体の配列の宣言
構造体データを複数扱う際には,構造体の配列を用いる(データカードを人数分用意する) 構造体の配列の宣言 std[0].name std[0].height std[0] std[0].weight typedef struct { char name[20]; int height; float weight; } student; std[1].name std[1].height std[1] std[1].weight std[2].name student std[5]; std[2].height std[2] std[2].weight ・・・・・・・・・・・・・ プログラミング入門2
18
構造体の配列 ソースファイル名:list1208.c (p.283を変更) 構造体の配列 プログラミング入門2
#include <stdio.h> #define NUMBER /* 学生の人数 */ typedef struct { char name[20]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ } student; int main(void) { int i; student std[]= { { "Sato", 178, 61.0 }, { "Sanaka", 175, 60.5 }, { "Takao", 173, 80.0 }, { "Mike", 165, 72.0 }, { "Masaki", 179, 77.5 }, }; puts(" "); for (i = 0; i < NUMBER; i++) printf("%-8s %6d%6.1f\n", std[i].name, std[i].height, std[i].weight); return (0); } プログラミング入門2
19
構造体の配列を関数へ渡す方法 = ソースファイル名: struct4.c どちらも配列の先頭アドレスを受け取る
#include <stdio.h> #define NUMBER /* 学生の人数 */ typedef struct { char name[20]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ } student; void print_data( student data[] ) { int i; puts(" "); for (i = 0; i < NUMBER; i++) printf("%-8s %6d%6.1f\n",data[i].name, data[i].height, data[i].weight); } in main(void) student std[] = { { "Sato", 178, 61.0 }, { "Sanaka", 175, 60.5 }, { "Takao", 173, 80.0 }, { "Mike", 165, 72.0 }, { "Masaki", 179, 77.5 }, }; print_data( std ); return (0); void print_data( student data[ ] ) = student *data どちらも配列の先頭アドレスを受け取る 受け取ると,関数内で data[i]として 配列要素を扱える 配列データを関数に渡す時には, その配列の先頭要素のアドレスを渡す std(配列名)=&std[0] プログラミング入門2
20
S 演習課題 問1)構造体 (kadai1101.c) キーボードから3点の2次元座標値(x, y)を読み込み,
演習課題 問1)構造体 (kadai1101.c) キーボードから3点の2次元座標値(x, y)を読み込み, 3点から作られる3角形の面積Sを出力するプログラムを作成せよ。 p1 p2 p3 S 但し,構造体は以下のものを用いること typedef struct { double x; double y; } point; プログラミング入門2
21
演習課題 問2)構造体の配列と関数(kadai1102.c)
演習課題 問2)構造体の配列と関数(kadai1102.c) student構造体の配列を用い,5名分の学生データを体重の軽い順に並べ替え(ソート),並べ替える前と並べ替えた後の結果を表示するプログラムを作成せよ。 並べ替え(ソート)のアルゴリズムについては,前回のレポートを参考にせよ。 void weight_sort( student *data, int num); もしくは, student data[ ] 配列の要素数 typedef struct { char name[20]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ } student; 提出期限: 12月18日(月)13:00(厳守) メールのタイトル:pro2-11+学籍番号+自分の苗字 例) L aoki プログラミング入門2
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.