C++スコーラ

構造体

最終更新:

cschola

- view
管理者のみ編集可

構造体

今回は構造体について説明します。構造体とは、変数をまとめて新しい変数型を自分で作る機能です。
変数は箱のようなもの説明しましが、構造体は「変数の箱」をまとめて入れることのできる「大きな箱」と思ってください。

第1項 型枠宣言と宣言

構造体は作らないと(型枠の大きさを決めないと)使えません。 構造体を作るときは次のようにします。
struct 構造体型名 {メンバ};
※メンバとは構造体の中で宣言される変数です。 
構造体は作った場所より下で宣言することで使うことができます。 
関数の中で作った場合はその関数の中でしか使えないので注意しましょう。
#include <stdio.h>

//プレイヤーの構造体
struct tPlayer{
	char name[64];	// 名前
	int HP;		// 体力
	int MP;		// 魔力 
};

int main(){
	tPlayer taro = {"taro",240, 110}; // tPlayer型のtaroの宣言と初期化

	printf("名前:%s,HP:%d,MP:%d\n",taro.name,taro.HP,taro.MP);

	return 0;
}
構造体は変数と同じように宣言。
こうして宣言されたものを「構造体変数」と呼びます。
構造体の初期化はいくつかの方法があります。
宣言と同時に初期化する場合は { } を使って , で区切ることで初期化できます。
tPlayer taro = {"taro",240, 110};
構造体変数として宣言した後に 構造体変数名.メンバ = 数値 とすることで初期化することもできます。
taro.HP = 60;  // 体力を60に変更

構造体の存在意義

構造体とは、「複数の要素を持ったオブジェクト」を定義する際に使われます。
RPGのキャラクターを例にしてみましょう。
1つのキャラクターは、それぞれ「name」「HP」「MP」「STR」という要素を持っているとします。
変数で表現するならこうなるでしょう。
char name[64]; // 名前
int HP;        // 体力
int MP;        // 魔力
int STR;       // 攻撃力
キャラクターが1人なら問題無いですが、キャラクター1つが増えるごとに要素の数だけ変数の数も増えてしまいます。
// キャラ1
char name1[64]; // 名前
int HP1;        // 体力
int MP1;        // 魔力
int STR1;       // 攻撃力
// キャラ2
char name2[64]; // 名前
int HP2;        // 体力
int MP2;        // 魔力
int STR2;       // 攻撃力
// キャラ3
char name3[64]; // 名前
int HP3;        // 体力
int MP3;        // 魔力
int STR3;       // 攻撃力
これは非常に面倒くさいし、管理もしづらいです。
キャラクターの要素を追加する際もキャラクター数分追加することになってしまいます。
では、構造体で書いてみましょう
// キャラクター構造体
struct Charcter{
	char name[64]; // 名前
	int HP;        // 体力
	int MP;        // 魔力
	int STR;       // 攻撃力
};

int main(){
	// キャラクターの実体作成
	Charcter hasegawa = { "長谷川" , 120, 20, 82};
	Charcter karasawa = { "唐沢" , 10, 999, 1};
	Charcter slime = { "スライム" , 50, 0, 35};

	return 0;
}
構造体であれば、キャラクター数を増やしても構造体の実体が1つ増えるだけなので非常にすっきりします。
キャラクターの要素を追加する場合も構造体に変数を追加するだけなので簡単にできます。

配列

構造体変数も配列として宣言することができます。 構造体配列などと呼びます。
// 敵構造体
struct tEnemy{
	char name[64];	// 名前
	int HP;		// 体力
	int MP;		// 魔力 
};

int main(){

	tEnemy enemy[5] = {{"slime",10, 2},
			   {"trent",100, 180},
			   {"bat",60, 40},
			   {"wolf",180, 30},
			   {"bird",90, 10}};

	for(int i = 0; i < 5; i++){
		printf("名前:%s,HP:%d,MP:%d\n",enemy[i].name,enemy[i].HP,enemy[i].MP);
	}
	return 0;
}

関数

関数の中で構造体を使うこともできます。 ※関数は構造体を作った位置より下に書く。
前項の例の表示部分を関数にまとめて書き直したものです。
// 敵構造体
struct tEnemy{
	char name[64];	// 名前
	int HP;		// 体力
	int MP;		// 魔力 
};

// 敵の内容を表示する関数
void EnemyOutput(tEnemy enemy){
	printf("名前:%s,HP:%d,MP:%d\n",enemy.name,enemy.HP,enemy.MP);
}

int main(){

	tEnemy enemy[5] = {{"slime",10, 2},
			   {"trent",100, 180},
			   {"bat",60, 40},
			   {"wolf",180, 30},
			   {"bird",90, 10}};

	for(int i = 0; i < 5; i++) EnemyOutput(enemy[i]);

	return 0;
}
表示されるものは前項と同じです。
関数の戻り値に構造体を使うこともできます。
// 敵構造体
struct tEnemy{
	char name[64];	// 名前
	int HP;		// 体力
	int MP;		// 魔力 
};

// 敵の内容を表示する関数
void EnemyOutput(tEnemy enemy){
	printf("名前:%s,HP:%d,MP:%d\n",enemy.name,enemy.HP,enemy.MP);
}

// 敵の内容を入力して初期化する関数
tEnemy EnemyInput(){	
	tEnemy g;

	printf("敵の名前を入力してください。\n");

	scanf_s("%s",g.name,64);

	printf("敵のHPを入力してください。\n");

	scanf_s("%d",&g.HP);

	printf("敵のMPを入力してください。\n");

	scanf_s("%d",&g.MP);

	return g;
}

int main(){

	tEnemy enemy;

	enemy = EnemyInput();

	EnemyOutput(enemy);

	return 0;
}

練習問題

次のような構造体とそれを用いたプログラムを作ってください。
第1問
 名前、身長、体重 をメンバとして持つ人間構造体を作り、それを初期化して表示する。
第2問
  人間構造体を配列数3の構造体配列として宣言してユーザーからの入力で初期化し、身長で降順に並べ表示する。
目安箱バナー