広告
↓発売日:2018年09月22日↓
新品価格 |
「名前」+「電話番号」+「住所」=「電話帳1件のデータ」
「ハンバーガー」+「ポテト」+「コーラ」=「ハンバーガーセット」
「HP」+「MP」+「職業」+「Lv」=「ゲームのキャラ一人分のデータ」
などなど。
このように世の中にはセットで考えた方が便利なものがたくさんあります。
変数もこんな感じでセットのものをひと固まりにできれば便利ですよね。
今回はそんな時に使える構造体(こうぞうたい)について見ていきたいと思います。
まずはセットを作るところから、始めます!
わかりやすいモノで
「名前」+「電話番号」
で電話帳を作ってみます。
struct DENWABOOK{ const char* name; const char* tel; };
こちらになります。まずは
struct DENWABOOK{ }
ここでセットの名前を決めます!
「struct ○○」で「○○という名前のセット」という意味になります!
構造体の名前は大文字で!というのがなんとなく決まってるみたいなので、
ここは空気を読んで大文字で名前をつけます。
次にカッコの中に必要な内容を書きます。
const char* name; const char* tel;
ひとまずポインタ文字列として「名前→*name」と「電話番号→*tel」を内容として決めました!
この内容一つ一つの事を正式にはメンバと言います。
ここまでで「int」や「char」のように「struct DENWABOOK」という構造体変数を作りました、という事になります。
これだけだと構造体変数の種類を作った事にしかならないので、「int」や「char」と同じく変数を宣言しなければなりません。
/*十日目 プログラム1*/ #include <stdio.h> struct DENWABOOK{ const char* name; const char* tel; }; int main(){ struct DENWABOOK no1; struct DENWABOOK no2 = { "田中二郎", "09022222222" }; no1.name = "鈴木一郎"; no1.tel = "09011111111"; printf("電話帳no1 お名前:%s 電話番号:%s\n",no1.name,no1.tel); printf("電話帳no2 お名前:%s 電話番号:%s\n",no2.name,no2.tel); return 0; }
宣言と初期化の例になります。
まずは「int main()」内の最初の部分
struct DENWABOOK no1; struct DENWABOOK no2 = { "田中二郎", "09022222222" };
こちらに注目です!
ここで宣言しております!
「no1」、「no2」というのが変数名です。
少しくどいですが、たとえば「int」で書いてみると
int no1; int no2;
こういう事です。
この「struct DENWABOOK」までが「int」と同じく変数の種類になります。
続いて初期化ですが、宣言とともに一気に初期化する場合はそれぞれの要素を,「」コンマで区切って
struct DENWABOOK no2 = { "田中二郎", "09022222222" };
のようにできます。
宣言した後、別の場所でその一つ一つの内容を確認、変更したりしたい時は
no1.name = "鈴木一郎"; no1.tel = "09011111111";
のように
変数名.内容
と変数名の後に「.」ドットをつければそれぞれの内容を確認できます。
もう一つ初期化と宣言の例をあげてみます。
/*十日目 プログラム2*/ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> struct DENWABOOK{ char name[128]; char tel[128]; }; int main(){ struct DENWABOOK no1; struct DENWABOOK no2 = { "田中二郎", "09022222222" }; strcpy(no1.name,"鈴木一郎"); strcpy(no1.tel,"09011111111"); printf("電話帳no1 お名前:%s 電話番号:%s\n",no1.name,no1.tel); printf("電話帳no2 お名前:%s 電話番号:%s\n",no2.name,no2.tel); return 0; }
内容に文字配列などがある場合で後から内容を変更したい時などは通常の文字配列と同じく
strcpy(no1.name,"鈴木一郎"); strcpy(no1.tel,"09011111111");
「strcpy()」文を使ったり
sprintf(no1.name,"%s","鈴木一郎"); sprintf(no1.tel,"%s","09011111111");
「sprintf()」文を使って内容を変更します。
広告
それではちょっと練習してみましょう。
ロールプレイングゲームのキャラクターごとのデータを考えます。
名前 太郎
職業 戦士
HP 100
MP 0
Lv 30
名前 花子
職業 僧侶
HP 50
MP 100
Lv 28
名前 ポチ
職業 遊び人
HP 30
MP 30
Lv 10
この3人のデータをもとに、構造体を作ってみます。
struct PARTY{ const char* name; const char* job; int hp; int mp; int lv; };
「struct PARTY」という、セットを作ってみました。
それぞれ
名前→const char* name;
職業→const char* job;
HP→int hp;
MP→int mp;
Lv→int lv;
になります。
ではこちらをもとにプログラムを組んでみます。
/*十日目 プログラム3*/ #include <stdio.h> struct PARTY{ const char* name; const char* job; int hp; int mp; int lv; }; int main(){ struct PARTY tarou; struct PARTY hanako; struct PARTY pochi = { "ポチ", "遊び人", 30, 30, 10 }; tarou.name = "太郎"; tarou.job = "戦士"; tarou.hp = 100; tarou.mp = 0; tarou.lv = 30; hanako.name = "花子"; hanako.job = "僧侶"; hanako.hp = 50; hanako.mp = 100; hanako.lv = 28; printf("名前:%s 職業:%s HP:%d MP:%d Lv:%d\n", tarou.name,tarou.job,tarou.hp,tarou.mp,tarou.lv); printf("名前:%s 職業:%s HP:%d MP:%d Lv:%d\n", hanako.name,hanako.job,hanako.hp,hanako.mp,hanako.lv); printf("名前:%s 職業:%s HP:%d MP:%d Lv:%d\n", pochi.name,pochi.job,pochi.hp,pochi.mp,pochi.lv); return 0; }
「struct PARTY」までが変数の種類
内容(メンバ)を見る時は「変数名.内容」をしっかり覚えましょう。
/*十日目 プログラム4*/ #include <stdio.h> struct STUDENT{ char name[128]; int age; }; int main(){ struct STUDENT no1 = { "鈴木一郎", 15 }; struct STUDENT no2; no2 = no1; printf("生徒no1 お名前:%s 年齢:%d\n",no1.name,no1.age); printf("生徒no2 お名前:%s 年齢:%d\n",no2.name,no2.age); return 0; }
同じ種類の構造体同士で簡単に内容を丸ごとコピーできます。
no2 = no1;
これだけで構造体変数「no1」の内容が丸ごと「no2」にコピーされます。
/*十日目 プログラム5*/ #include <stdio.h> struct DENWABOOK{ char name[128]; char tel[128]; }; int main(){ struct DENWABOOK no[3] = { {"鈴木一郎","09011111111"}, {"田中二郎","09022222222"}, {"佐藤三郎","09033333333"} }; int i; for(i=0;i<3;i++){ printf("電話帳no1 お名前:%s 電話番号:%s\n",no[i].name,no[i].tel); } return 0; }
今度は配列の場合です。
まとめて初期化する時は以前2次元配列を初期化したような感じで{}カッコの中に内カッコで分けて初期化できます。
struct DENWABOOK no[3] = { {"鈴木一郎","09011111111"}, {"田中二郎","09022222222"}, {"佐藤三郎","09033333333"} };
各メンバの確認は
no[0].name; no[0].tel;
のようになります。
配列にすればたくさんのデータを扱えるようになりますね!
/*十日目 プログラム6*/ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> struct STUDENT{ char name[128]; int age; }student1,student2; struct STUDENT student3; int main(){ sprintf(student1.name,"%s","鈴木一郎"); student1.age = 15; sprintf(student2.name,"%s","田中二郎"); student2.age = 14; sprintf(student3.name,"%s","佐藤三郎"); student3.age = 13; printf("生徒1 お名前:%s 年齢:%d\n",student1.name,student1.age); printf("生徒2 お名前:%s 年齢:%d\n",student2.name,student2.age); printf("生徒3 お名前:%s 年齢:%d\n",student3.name,student3.age); return 0; }
最後にグローバル変数にする場合を見ていきます。
基本、関数の外で宣言するのは同じなのですが、
struct STUDENT{ char name[128]; int age; }student1,student2;
このように構造体変数を決める時と同時に宣言するようなやり方もあります。
もう一つはいつも通りに
struct STUDENT{ char name[128]; int age; }; struct STUDENT student1;
別々に分けて宣言できます。
この2つのやり方ですが、たぶん後のやり方のように
変数の種類を決める事
と
変数名をつける事
は別にした方が見栄えは良いかと思われます。
構造体は実用的なプログラムではなくてはならない、そしていわゆるオブジェクト指向にも通ずるとても大事な技術です。
何度も練習してここでしっかり基本を覚えましょう!
それでは次回は他の関数への構造体の受け渡しなどについてみていきましょう!
広告
↓発売日:2016年02月29日↓
12歳からはじめる ゼロからのC言語 ゲームプログラミング教室 新品価格 |
↓発売日:2018年06月22日↓
新品価格 |
↓発売日:2018年03月09日↓
新品価格 |
↓発売日:2017年06月14日↓
新品価格 |
↓発売日:2018年05月21日↓
新品価格 |
↓発売日:2017年12月07日↓
新品価格 |
↓発売日:2017年02月08日↓
新・明解C言語で学ぶアルゴリズムとデータ構造 (明解シリーズ) 新品価格 |
↓発売日:2017年09月26日↓
新品価格 |