Presentation is loading. Please wait.

Presentation is loading. Please wait.

前回の復習 構造体②.

Similar presentations


Presentation on theme: "前回の復習 構造体②."— Presentation transcript:

1 前回の復習 構造体②

2 構造体と配列 通常の変数と同じように、構造体変数についても配列を設定できる。これを構造体配列という。 a[0] a[1] a[2] int
char b[3] short d int a char b[3] short d a[2]

3 実行してみる #include <stdio.h> #include <string.h>
struct data { int no; char name[10]; }; int main(void) { struct data list[2]; list[0].no = 99; strcpy(list[0].name, "高専太郎"); list[1].no = 100; strcpy(list[1].name, "電情次郎"); for(int i = 0; i < 2; i++) printf("出席番号:%d番, 名前:%s\n", list[i].no, list[i].name); return 0; }

4 構造体配列の宣言 構造体配列 テンプレートと配列を個別に宣言 テンプレートと配列を同時に宣言 struct data{ int no;
char name[10]; }; struct data list[10]; struct data{ int no; char name[10]; } list[10]; 構造体配列

5 実行してみる① { }でまとめて初期化ができる #include <stdio.h> struct data {
char name[20]; int ave; }; int main(void) { struct data list[4] = { { "野比のび太", 0 }, { "源静香", 90 }, { "剛田武", 40 }, { "骨川スネ夫", 70 } for (int i = 0; i < 4; i++) printf("番号:%d番, 名前:%s, 平均点:%d\n", i+1, list[i].name, list[i].ave); return 0; } { }でまとめて初期化ができる

6 実行してみる② 構造体のポインタ配列も同様な処理でできる &がつかないことに注意 #include <stdio.h>
#include <string.h> struct data { int no; char name[10]; } list[2]; int main(void) { struct data *plist = list; (*plist).no = 99; strcpy((*plist).name, "高専太郎"); (*(plist + 1)).no = 100; strcpy((*(plist + 1)).name, "電情次郎"); for(int i = 0; i < 2; i++) printf("出席番号:%d番, 名前:%s\n", (*(plist + i)).no, (*(plist + i)).name); return 0; } 構造体のポインタ配列も同様な処理でできる &がつかないことに注意

7 実行してみる③ 構造体のポインタ配列のアロー演算子も同様 #include <stdio.h>
#include <string.h> struct data { int no; char name[10]; } list[2]; int main(void) { struct data *plist = list; plist->no = 99; strcpy(plist->name, "高専太郎"); (plist + 1)->no = 100; strcpy((plist + 1)->name, "電情次郎"); for(; plist != list + 2; plist++) printf("出席番号:%d番, 名前:%s\n", plist->no, plist->name); return 0; } 構造体のポインタ配列のアロー演算子も同様

8 型の再定義

9 実行してみる #include <stdio.h> int main(void) { typedef unsigned char u_char; u_char c; c = 100; printf("%d \n", c); return 0; }

10 typedef unsigned char u_char
型の名前を変更する 型の名前は「unsigned char」などを組み合わせると、長くなる。そんなときtypedefを使うと、任意の名前を付けることができる typedef unsigned char u_char 既存の型名 新しい型名 自由に名前を付けなおせる

11 = 構造体名を変更する typedefを使えば構造体テンプレートにも任意の名前を定義できる
typedef struct { int no; char name[10]; } DATA; DATA list; struct data{ int no; char name[10]; }; struct data list; = 同じ結果 DATAそのものが型名になっているので、structはいらなくなる

12 実行してみる #include <stdio.h> typedef struct { char name[10]; int age; } PROFILE; int main(void) { PROFILE prof[2] = { {"Taro", 15 }, {"Jiro", 17 } }; for (int i = 0; i < 2; i++) printf("%sさんは %d歳です \n",prof[i].name, prof[i].age); return 0; }

13 構造体と関数

14 実行してみる #include <stdio.h> struct data { int no; char name[10];
}; void disp(struct data gakuse); int main(void) { struct data list1 = { 99, "高専太郎"}; disp(list1); return 0; } void disp(struct data gakuse){ printf("出席番号:%d番, 名前:%s\n", gakuse.no, gakuse.name);

15 関数に構造体を渡す(値渡し) list1 gakuse 構造体をコピー main関数 disp関数 int a char b[3]
short d int a char b[3] short d 構造体をコピー

16 実行してみる #include <stdio.h> struct data { int no; char name[10];
}; void disp(struct data *gakuse); int main(void) { struct data list[2] = { { 99, "高専太郎" },{ 100, "電情次郎"}}; disp(list); return 0; } void disp(struct data *gakuse) { for (int i = 0; i < 2; i++) printf("出席番号:%d番, 名前:%s\n", gakuse[i].no, gakuse[i].name);

17 関数に構造体を渡す(参照渡し) list[0] list[1] *gakuse アドレスを渡す main関数 disp関数 list int
char b[3] short d int a char b[3] short d アドレスを渡す

18 構造体の入れ子構造 構造体の中に構造体を宣言することができる data int a long b char c[8] 構造体d int x
y

19 入れ子の構造体は必ず先に宣言する ドットが2つになる #include <stdio.h>
#include <string.h> struct xy { double x; double y; }; struct data { int no; char name[10]; struct xy hw; int main(void) { struct data list1; list1.no = 99; list1.hw.x = 176.3; list1.hw.y = 72.3; strcpy(list1.name, "高専太郎"); printf("出席番号:%d番, 名前:%s\n", list1.no, list1.name); printf("身長:%4.1f cm, 体重:%4.1f kg\n", list1.hw.x, list1.hw.y); return 0; } 入れ子の構造体は必ず先に宣言する ドットが2つになる

20 今日の練習問題① 構造体テンプレート名をstatusを作成し、構造体のメンバに「名前(name)」「レベル(level)」「体力(HP)」「攻撃力(att)」「防御力(def)」「すばやさ(agi)」を設定してステータス画面を作成してください。それぞれのデータは以下の通りです。ただし構造体配列を使うこと。 構造体配列 名前 レベル 体力 攻撃力 防御力 素早さ chara [0] 勇者 1 15 18 16 20 [1] 戦士 5 600 205 189 2 [2] 魔法使い 10 48 12 22

21 #include <stdio.h>
struct status { char name[10]; int level; int HP; int att; int def; int agi; }; int main(void) { struct status chara[3]; chara[0] = { "勇者", 1, 15, 18, 16, 20 }; chara[1] = { "戦士", 5, 600, 205, 189, 2 }; chara[2] = { "魔法使い", 10, 48, 12, 18, 22 }; for(int i = 0; i < 3; i++) printf("%s: %dレベル, HP = %d, att = %d, def = %d, agi = %d\n", chara[i].name, chara[i].level, chara[i].HP, chara[i].att, chara[i].def, chara[i].agi); return 0; }

22 今日の練習問題② 構造体のテンプレート名をstudentsとしてメンバを学籍番号「.num」、名前「.name」、住所「address」とし、ポインタ配列を使って以下の表となるようにしてください。 構造体変数 学籍番号 名前 住所 mem0 1010 太郎 鯖江市 mem1 1234 次郎 福井市 mem2 4649 三郎 敦賀市 mem3 8888 史郎 小浜市

23 #include <stdio.h>
#include <string.h> struct students { int num; char name[10]; char address[10]; }mem[4]; int main(void) { struct students *pmem = mem; pmem->num = 1010; strcpy(pmem->name, "太郎"); strcpy(pmem->address, "鯖江市"); (pmem + 1)->num = 1234; strcpy((pmem + 1)->name, "次郎"); strcpy((pmem + 1)->address, "福井市"); (pmem + 2)->num = 4649; strcpy((pmem + 2)->name, "三郎"); strcpy((pmem + 2)->address, "敦賀市"); (pmem + 3)->num = 8888; strcpy((pmem + 3)->name, "史郎"); strcpy((pmem + 3)->address, "小浜市"); for(int i = 0; i < 4; i++) printf("学生番号: %d, 名前: %s, 住所: %s\n", (pmem + i)->num, (pmem + i)->name, (pmem + i)->address); return 0; }

24 今日の練習問題③ 構造体テンプレート名をweatherとし、ここ1週間の天気のデータを作ります。ここでweatherのメンバを日付「.day」、曜日「.week」、最高気温「. Utemp」、最低気温「.Dtemp」とし、以下の表となるようにしてください。ただしポインタ配列でアロー演算子を使ってデータを操作すること。 日付 曜日 最高気温 最低気温 10/1 16.2 14.6 10/2 21.5 13.4 10/3 19.0 10.0 10/4 17.9 13.0 10/5 20.4 12.1 10/6 23.8 15.5 10/7 21.0 14.2

25 #include <stdio.h>
#include <string.h> struct students { char day[10]; char week[10]; double Utemp; double Dtemp; }hi[7]; int main(void) { struct students *phi = hi; strcpy(phi->day, "10/1"); strcpy(phi->week, "日"); phi->Utemp = 16.2; phi->Dtemp = 14.6; strcpy((phi+1)->day, "10/2"); strcpy((phi+1)->week, "月"); (phi+1)->Utemp = 21.5; (phi+1)->Dtemp = 13.4; strcpy((phi+2)->day, "10/3"); strcpy((phi+2)->week, "火"); (phi+2)->Utemp = 19.0; (phi+2)->Dtemp = 10.0; strcpy((phi+3)->day, "10/4"); strcpy((phi+3)->week, "水"); (phi+3)->Utemp = 17.9; (phi+3)->Dtemp = 13.0; strcpy((phi+4)->day, "10/5"); strcpy((phi+4)->week, "木"); (phi+4)->Utemp = 20.4; (phi+4)->Dtemp = 12.1; strcpy((phi+5)->day, "10/6"); strcpy((phi+5)->week, "金"); (phi+5)->Utemp = 23.8; (phi+5)->Dtemp = 15.5; strcpy((phi+6)->day, "10/7"); strcpy((phi+6)->week, "土"); (phi+6)->Utemp = 21.0; (phi+6)->Dtemp = 14.2; for(int i=0; i < 7; i++) printf("日付: %s, 曜日: %s, 最高気温: %4.1f, 最低気温: %4.1f\n", (phi+i)->day, (phi+i)->week, (phi+i)->Utemp, (phi+i)->Dtemp); return 0; }

26 今日の練習問題④ 構造体の初期値として与え、メンバは、生徒番号、各科目点数、平均点、評価で、以下の右表のとおりとする。 また各人の 4科目の平均点を関数として構造体配列を参照渡しで求め、構造体に格納すること。さらに各人の評価を関数として構造体配列を参照渡しで求め、構造体に格納すること。尚、4段階の評価基準は、80点以上‘A‘、70点以上 80点未満’B‘、60点以上 70点未満’C‘、60点未満‘D’として全データを表示させよ 生徒 番号 国語 数学 理科 社会 平均点 評価 1001 85 74 63 90 0.0 '?' 1002 78 65 70 62 1003 89 92 88 76 1004 32 48 66 25 1005 81 98

27 … for (int i = 0; i < 5; i++) { mem[i].ave = average(i, mem);
#include <stdio.h> struct students { int num; int jap; int mat; int sce; int soc; int ave; char sta; }mem[5]; int average(int, struct students *mem); char result(int i, struct students *mem); int main(void) { mem[0].num = 1001; mem[0].jap = 85; mem[0].mat = 74; mem[0].sce = 63; mem[0].soc = 90; mem[1].num = 1002; mem[1].jap = 78; mem[1].mat = 65; mem[1].sce = 70; mem[1].soc = 62; mem[2].num = 1003; mem[2].jap = 89; mem[2].mat = 92; mem[2].sce = 88; mem[2].soc = 76; for (int i = 0; i < 5; i++) { mem[i].ave = average(i, mem); mem[i].sta = result(i, mem); printf("番号:%d, 国語%d, 数学%d, 理科%d, 社会%d, 平均点%d, 評価%c\n", mem[i].num, mem[i].jap, mem[i].mat, mem[i].sce, mem[i].soc, mem[i].ave, mem[i].sta); } return 0; int average(int i, struct students *mem) { return (mem[i].jap + mem[i].mat + mem[i].sce + mem[i].soc) / 4; char result(int i, struct students *mem) { char a; if (mem[i].ave >= 80) { a = 'A'; }else if (mem[i].ave >= 70) { a = 'B'; }else if (mem[i].ave >= 60) { a = 'C'; }else { a = 'D'; return a;

28 図書データを設定する下記のような構造体配列がある。
今日の練習問題⑤ 図書データを設定する下記のような構造体配列がある。 同じ構造の作業用の構造体変数に、図書名、返却予定年月日をend が入力されるまで入力しなさい。 入力した図書が構造体配列にすでに登録されている場合は「貸し出し中」をメッセージ出力し、未登録の場合は構造体配列に登録しなさい。 struct date { int yy; /* 年 */ int mm; /* 月 */ int dd; /* 日 */ }; struct tosyo { char name[100]; /* 図書名 */ struct date henkyaku; /* 返却予定日 */

29 入出力例 図書名、返却予定年月日を入力しなさい。 だからあなたも生きぬいて 2000 7 21 貸し出しOKです。
五体不満足 C言語入門 パソコン辞典 だからあなたも生きぬいて 貸し出し中です。別の本を指定してください。 end だからあなたも生きぬいて 五体不満足 C言語入門 パソコン辞典

30 #include <stdio.h>
#include <string.h> struct date { int yy; int mm; int dd; }; struct tosyo { char name[100]; struct date henkyaku; int main(void){ struct tosyo work = { "", 0, 0, 0 }; struct tosyo rireki[100]; int cnt = 0, i; printf("図書名、返却予定年月日を入力しなさい。(終了条件:Ctrl+Z)\n"); while (scanf("%s %d %d %d", work.name, &work.henkyaku.yy,&work.henkyaku.mm, &work.henkyaku.dd) != EOF) { for (i = 0; i < cnt; i++) { if (strcmp(work.name, rireki[i].name) == 0) { printf("貸し出し中です。別の本を指定してください。\n"); break; } if (i == cnt) { printf("貸し出しOKです。\n"); rireki[i] = work; cnt++; printf("\n図書名、返却予定年月日を入力しなさい。(終了条件:Ctrl+Z)\n"); printf("%-20s %4d.%2d.%2d\n", rireki[i].name, rireki[i].henkyaku.yy, rireki[i].henkyaku.mm, rireki[i].henkyaku.dd); return 0;

31 プログラミング応用

32 マクロ #から始まる命令文 #include

33 ヘッダファイル stdio.hなど、拡張子が「.h」のファイルのことを、ヘッダファイルという。ヘッダファイルはプロトタイプ宣言、構造体、定数の定義などのテキストファイルになっている。これをソースコードに組み込む(( )する)と、それらの宣言や定義を利用できる。 #include <stdio.h> int main(void){ return 0; } stdio.h stdioの宣言や 定義を( )できる

34  ヘッダファイルの種類 ヘッダファイル 処理の種類 stdio.h string.h time.h math.h stdlib.h

35 標準と自作のヘッダファイル #include <ファイル名> #include “ファイル名”
標準関数のヘッダファイルをインクルード 自作のヘッダファイルをインクルード 標準のヘッダファイルと自作のヘッダファイルで( )が違うので注意すること

36 自作のヘッダファイルを作る① sum.c sum.h main関数が書かれてあるファイルの同じファルダに作る
int sum(int min, int max){ int num = 0, i; for(i = min; i < max; i++) num += i; return num; } int sum(int min, int max); main関数が書かれてあるファイルの同じファルダに作る

37 自作のヘッダファイルを作る② main.c エディタによっては自作ヘッダファイル用の設定をしなければならないこともあるので注意!
#include <stdio.h> #include "sum.h" int main(void) { int value; value = sum(50, 100); printf("%d \n", value); return 0; } エディタによっては自作ヘッダファイル用の設定をしなければならないこともあるので注意! 自作したヘッダファイルの関数を使うことができる

38 変数を共有する(エラー)① sum.c sum.h int pub = 100; int sum(int min, int max){
int num = 0, i; for(i = min; i < max; i++) num += i; return num; } int pub; int sum(int min, int max);

39 変数を共有する(エラー)② すでに定義されているとエラーがでる main.c #include <stdio.h>
#include "sum.h" int main(void) { int value; value = sum(50, 100); printf("%d, %d \n", value, pub); return 0; } すでに定義されているとエラーがでる

40 変数を共有する(extern) sum.h externを追加する
extern int pub; int sum(int min, int max); externを追加する 実行すると正常に動作する。このように異なるソースファイルで変数を( )することができる 乱用禁止

41 変数を共有させない(static) エラーで実行できなくなる! sum.c sum.h static int pub;
int sum(int min, int max){ int num = 0, i; pub = 1000; for(i = min; i < max; i++) num += i; return num; } extern int pub; int sum(int min, int max); エラーで実行できなくなる! staticはそのファイルの中でのみ参照できるが、そのファイル内ならば、どこからでも参照できる

42 変数を一切、変更させない(const) エラーで実行できない! sum.c sum.h const int pub;
int sum(int min, int max){ int num = 0, i; pub = 1000; for(i = min; i < max; i++) num += i; return num; } extern int pub; int sum(int min, int max); エラーで実行できない! constは変数の値を変更できなくなる。つまりconstで宣言した変数は定数になる

43 ヘッダファイルで重複を防ぐ sum.h 何度もコンパイルされなくなる
#ifndef _INCLUDE_SUM_ #define _INCLUDE_SUM_ extern int sum(int min, int max); #endif 何度もコンパイルされなくなる #ifndef ~ #endifの中がコンパイルするかどうか指定することで、重複インクルードを防ぐことができる

44 C言語実行までの仕組み

45 マクロ #から始まる命令文 #define

46 不変の値①(#define) 3.14に置き換わる main.c #include <stdio.h>
#define PI 3.14 int main(void) { int r = 5; printf("%f \n", r * r * PI); return 0; } 3.14に置き換わる

47 不変の値②(#define) エラーになる main.c #include <stdio.h> #define PI 3.14
int main(void) { int r = 5; PI = 3; printf("%f \n", r * r * PI); return 0; } エラーになる

48 #defineの書き方 #define LOOPNUM 10 大文字 ( ) セミコロン自体が値になってしまう セミコロンは( )

49 不変の変数enum(定数)① 0,1,2…と定数が代入される #include <stdio.h> enum{ aiu, eo,
kakiku, keko }; int main(void) { printf("%d, %d \n", aiu, eo); printf("%d, %d \n", kakiku, keko); return 0; } 0,1,2…と定数が代入される

50 不変の変数enum(定数)② 別の定数に代入することもできる #include <stdio.h> enum{ aiu,
eo = 5, kakiku, keko = 6 }; int main(void) { printf("%d, %d \n", aiu, eo); printf("%d, %d \n", kakiku, keko); return 0; } 別の定数に代入することもできる

51 マクロ #から始まる命令文 #defineする簡易関数

52 簡易関数①(#define) 実行してみよう! main.c #include <stdio.h>
#define HIKU(x,y) ((x) - (y)) int main(void) { printf("%d \n", HIKU(5,3)); return 0; } 実行してみよう!

53 簡易関数②(#define) 実行してみよう! main.c #include <stdio.h>
#define HIKU(x,y) ((x) - (y)) int main(void) { printf("%d \n", HIKU(5+2,1+3)); return 0; } 実行してみよう!

54 簡易関数③(#define) 違いを確認しよう! main.c #include <stdio.h>
#define HIKU(x,y) (x - y) int main(void) { printf("%d \n", HIKU(5+2,1+3)); return 0; } 違いを確認しよう!

55 簡易関数④(#define) 実行してみよう! main.c #include <stdio.h>
#define PRINTM(X) printf("%d\n", X) int main(void) { PRINTM(10); return 0; } 実行してみよう!

56 ここまでで。 何か質問はありませんか?

57 練習問題① 消費税を計算する関数をtax.cとして外部ファイルとして作り、main.cの中で金額を入力することで消費税の価格と、税込みの金額を表示するプログラムを作成せよ。また二重インクルードを防ぐ処理もすること。

58 練習問題② 前回の練習問題④の関数を自作ヘッダファイルに書き出し、読みだすプログラムを作成せよ。また二重インクルードを防ぐ処理もすること。
前回の練習問題④の関数をマクロの簡易関数として書き出し、読みだすプログラムを作成せよ。

59 練習問題③ kmからマイル(mi)へと、miからkmへの、双方向の単位研鑽を行うプログラムを作成せよ。defineを使い、1miは kmである

60 練習問題④ 円形プールの半径[m]と、入れる水の量[m3]を入力すると水深[m]を表示するプログラムを作成せよ。ただし円の面積を計算する関数はdefineで定義すること

61 練習問題⑤ enumを使い「SUN=1, MON=2, TUE=3, WED=4, THU=5, FRI=6, SAT=7」としてキーボードから数字を入力することで曜日を表示するプログラムを作成せよ。


Download ppt "前回の復習 構造体②."

Similar presentations


Ads by Google