C++構造体を実例で徹底解説
C++における構造体とは
構造体は、異なるデータ型の要素をひとまとめに格納するためのC++データ構造です。C++において構造体はユーザー定義データ型です。構造体は、異なるデータ型の項目を単一のデータ型としてグループ化するデータ型を作成します。
例えば:
誰かの情報(名前、国籍、年齢)を格納する必要があるとします。名前、国籍、年齢という変数を別々に作成してデータを格納できます。
しかし、将来的に多くの人の情報を格納する必要が生じるかもしれません。つまり、異なる個人用の変数が作成されることになります。例えば、name1、citizenship1、age1など。これを避けるために構造体を作成するのが良い方法です。
このC++チュートリアルで学ぶ内容:
- C++における構造体とは
- 構造体を使うべき場面
- C++構造体の初期化
- 構造体インスタンスの作成
- 構造体メンバへのアクセス
- 構造体へのポインタ
- 関数引数としての構造体
- C++構造体の制限事項
構造体を使うべき場面
C++で構造体を使う理由:
- 異なるデータ型の要素を1つのデータ型としてまとめて格納する必要がある場合
- C++構造体は参照型ではなく値型です。作成後にデータを変更する意図がない場合に構造体を使用
C++構造体の初期化
C++構造体を作成するには、structキーワードに続けて識別子を使用します。この識別子が構造体の名前になります。C++構造体作成の構文は以下の通り:
構文:
struct struct_name {
// struct members
}
上記構文ではstructキーワードを使用しています。struct_nameが構造体の名前です。
構造体メンバは中括弧内に追加します。これらのメンバはおそらく異なるデータ型に属します。
例:
struct Person {
char name[30];
int citizenship;
int age;
}
上記例では、Personは3つのメンバを持つ構造体です。メンバにはname、citizenship、ageが含まれます。1つのメンバはchar型、残り2つは整数型です。構造体が作成されるだけではメモリは割り当てられません。構造体に変数が追加された時点で初めてメモリが割り当てられます。
構造体インスタンスの作成
上記例ではPersonという構造体を作成しました。構造体変数は以下のように作成できます:
Person p;
pはPerson型の構造体変数です。この変数を使って構造体のメンバにアクセスできます。
構造体メンバへのアクセス
構造体メンバにアクセスするには、構造体のインスタンスとドット(.)演算子を使用します。例えば、構造体Personのメンバageにアクセスするには:
p.age = 27;
構造体のインスタンスpを使って構造体Personのメンバageにアクセスし、その値を27に設定しました。
例1:
#include <iostream>
using namespace std;
struct Person {
int citizenship;
int age;
};
int main(void) {
struct Person p;
p.citizenship = 1;
p.age = 27;
cout << "Person citizenship: " << p.citizenship << endl;
cout << "Person age: " << p.age << endl;
return 0;
}
出力:
コードのスクリーンショット:
コード解説:
- iostreamヘッダをインクルードしてその関数を使用
- std名前空間をインクルードしてクラスを修飾なしで使用
- Personという構造体を作成
- 構造体本体の開始
- citizenshipという整数型の構造体メンバを作成
- ageという整数型の構造体メンバを作成
- 構造体本体の終了
- main()関数を呼び出し、プログラムロジックを本体に記述
- 構造体Personのインスタンスを作成し、pという名前を付ける
- 構造体メンバcitizenshipの値を1に設定
- 構造体メンバageの値を27に設定
- 構造体メンバcitizenshipの値をコンソールにテキストと共に出力
- 構造体メンバageの値をコンソールにテキストと共に出力
- プログラムは正常実行時に値を返す
- main()関数の終了
構造体へのポインタ
構造体を指すポインタを作成することは可能です。これはint、float、doubleなどのネイティブデータ型を指すポインタの作成と似ています。C++のポインタはメモリ位置を格納することに注意してください。
例2:
#include <iostream>
using namespace std;
struct Length {
int meters;
float centimeters;
};
int main() {
Length *ptr, l;
ptr = &l;
cout << "Enter meters: ";
cin >> (*ptr).meters;
cout << "Enter centimeters: ";
cin >> (*ptr).centimeters;
cout << "Length = " << (*ptr).meters << " meters " << (*ptr).centimeters << " centimeters";
return 0;
}
出力:
コードのスクリーンショット:
コード解説:
- iostreamヘッダをインクルード
- std名前空間をインクルード
- Lengthという構造体を作成
- 構造体Lengthの本体開始
- metersという整数型の構造体メンバを作成
- centimetersという整数型の構造体メンバを作成
- 構造体Lengthの本体終了
- main()関数を呼び出し
- main()関数の本体開始
- ポインタ変数*ptrと通常変数lをLength型で作成
- 変数lのアドレスをポインタ変数に格納
- コンソールにメッセージを表示し、ユーザーにmetersの値入力を促す
- キーボードからユーザーが入力した値を読み取り。メンバmetersはポインタ変数経由でアクセス
- コンソールにメッセージを表示し、ユーザーにcentimetersの値入力を促す
- キーボードからユーザーが入力した値を読み取り。メンバcentimetersはポインタ変数経由でアクセス
- ユーザーから読み取った値をコンソールにテキストと共に出力
- プログラムは正常実行時に値を返す
- main()関数の本体終了
関数引数としての構造体
構造体を関数の引数として渡すことができます。これは通常の引数を渡すのと同じ方法で行います。構造体変数も関数に渡せます。構造体メンバの値を表示する必要がある場合などが好例です。これを実演します:
例3:
#include<iostream>
using namespace std;
struct Person {
int citizenship;
int age;
};
void func(struct Person p);
int main() {
struct Person p;
p.citizenship = 1;
p.age = 27;
func(p);
return 0;
}
void func(struct Person p) {
cout << " Person citizenship: " << p.citizenship<<endl;
cout << " Person age: " << p.age;
}
出力:
コードのスクリーンショット:
コード解説:
- iostreamヘッダをインクルード
- std名前空間をインクルード
- Personという構造体を作成
- 構造体Personの本体開始
- Personのメンバを作成。名前はcitizenship、型は整数
- Personのメンバを作成。名前はage、型は整数
- 構造体Personの本体終了
- 構造体Personのインスタンスpを引数として取る関数を作成
- main関数を呼び出し。{はmain()関数本体の開始
- 構造体Personのインスタンスを作成し、pという名前を付ける
- 構造体のインスタンスpを使って構造体メンバ変数citizenshipにアクセスし、値1を代入
- 構造体のインスタンスpを使って構造体メンバ変数ageにアクセスし、値27を代入
- 関数を呼び出し、構造体Personのインスタンスpを引数として渡す
- 関数は正常実行時に値を返す
- main()関数の本体終了
- 関数の本体を作成
- 関数本体の開始
- 構造体メンバcitizenshipの値にアクセスし、他のテキストと共にコンソールに出力
- 構造体メンバageの値にアクセスし、他のテキストと共にコンソールに出力
- 関数本体の終了
C++構造体の制限事項
構造体には以下の制限があります:
- 構造体データ型を組み込みデータ型のように扱うことはできない
+、-などの演算子を構造体変数に使用できない- 構造体はデータ隠蔽をサポートしない。構造体のメンバはスコープに関わらず任意の関数からアクセス可能
- 構造体本体内でstaticメンバを宣言できない
- 構造体内でコンストラクタを作成できない
まとめ:
- 構造体は異なる型のデータ要素を格納するデータ構造
- 配列が同種のデータ要素を格納するのに対し、構造体は異種のデータ要素を格納
- データ要素が値を変更しないことが想定される場合に構造体を使用すべき
- 構造体のメンバはドット(.)演算子でアクセス
- 構造体のインスタンスを作成する必要がある
- C++構造体を作成するには
structキーワードを使用 - 構造体を指すポインタは、通常の型を指すポインタと同様に作成
- 構造体は通常の関数と同じように関数の引数として渡せる
C言語
- C言語 構造体とポインタ: 実践ガイド
- C++演算子を徹底解説:種類、例、サンプルプログラム付き
- C++ do-while文:構文、実践例、ネストしたループ
- C++ switch文をマスター:構文、使い方、実践例
- C++動的配列の確保をマスター:コード例付き実践ガイド
- C++ポインタをマスター:概念、例、実践的応用
- C++ char型をマスター:宣言、ASCII、変換テクニック
- C++演算子オーバーロード:コード例付き実践ガイド
- C++のstd::listをマスターする:構文、関数、実践例
- C++関数を実例で徹底解説:基本から応用まで
- C++ structとclassの違い:構文、特徴、使い分けのベストプラクティス