6.1. 構造体
構造体は、分散したデータを一つにまとめる事ができる型である。
例として、traP メンバーの名簿を考えよう。
今この講習に居るメンバーの traP ID、学籍番号、学年 の情報がほしいとする。
これらをプログラムで扱うとき、素朴には以下のように個別に変数を宣言すればよい。
string trap_id, student_id;
int grade;
しかし、複数人分の情報を扱いたかったり、関数に渡したかったりするときにやや不便である。
例として、2人のメンバーの情報が完全に一致するか(同一か)を判定するプログラムを以下に記す。
#include <string>
#include <iostream>
using namespace std;
// 引数が長すぎる……
bool equals(
string trap_id1, string student_id1, int grade1,
string trap_id2, string student_id2, int grade2
) {
return trap_id1 == trap_id2
&& student_id1 == student_id2
&& grade1 && grade2;
}
int main() {
// 宣言が長すぎる……
string trap_id1, student_id1, trap_id2, student_id2;
int grade1, grade2;
cin >> trap_id1 >> student_id1 >> grade1
>> trap_id2 >> student_id2 >> grade2;
if (equals(
trap_id1, student_id1, grade1,
trap_id2, student_id2, grade2
)) {
cout << "same" << endl;
} else {
cout << "not same" << endl;
}
}
これはあまりに長い。 配列を使えば宣言はそれぞれの変数でまとめることはできるが、できれば学生情報は一つの変数にまとめたい。
ここで、複数の変数をまとめてひとつの値として扱える構造体 (struct) を導入し、構造体の 型 を定義する。
TIP
他の言語などではクラスやオブジェクトなどと呼ばれる。
用語
- 構造体に属する変数はメンバ変数 (member variable) と呼ばれている。
- ある構造体の型を持った値は、その構造体のインスタンス (instance) と呼ばれる。
構造体を用いると、コードは以下のようになる。
#include <iostream>
#include <string>
using namespace std;
struct Member {
string trap_id, student_id;
int grade;
};
bool equals(Member member1, Member member2) {
return member1.trap_id == member2.trap_id &&
member1.student_id == member2.student_id &&
member1.grade == member2.grade;
}
int main() {
Member zer0star{"zer0-star", "22BXXXXX", 2};
Member hoshimiya{"hoshimiya", "99B99999", 99999};
if (equals(zer0star, hoshimiya)) {
cout << "same" << endl;
} else {
cout << "not same" << endl;
}
}
少し見やすくなったように感じないだろうか?
struct Member {
string trap_id, student_id;
int grade;
};
この部分で構造体 Member
を定義している。構造体 Member
は以下の3つのメンバ変数を持つ。
string
型のtrap_id
string
型のstudent_id
int
型のgrade
宣言は以下のように対応する。
Member zer0star{"zer0-star", "22BXXXXX", 2};
Member hoshimiya{"hoshimiya", "99B99999", 99999};
これは省略されているが、先頭から順に trap_id = "zer0-star"
, student_id = "22BXXXXX"
, grade = 2
とするという宣言である。
次に、構造体を使用する方を見てみよう。equals
関数の実装は以下のとおり。
bool equals(Member member1, Member member2) {
return member1.trap_id == member2.trap_id &&
member1.student_id == member2.student_id &&
member1.grade == member2.grade;
}
関数の引数として、 int
型などと同様に Member
型を受け取ることができる。 Member
型の変数1つを渡すのは、 trap_id
student_id
grade
の3変数を渡したことと同じになる。
Member
型の各変数にアクセスするには、 member.trap_id
のように、 .
で変数名とメンバ変数を繋げれば良い。
このようにしたあとは、以下のように構造体を使って equals
を使用することができる。
if (equals(zer0star, hoshimiya)) {
cout << "same" << endl;
} else {
cout << "not same" << endl;
}
なんだか仰々しいものに見えるかもしれないが、本質的には複数の変数をまとめて、わかりやすくなるように取り扱っているだけである。