自分自身の型のメンバを持つ構造体
構造体で、別の構造体型のメンバを持つ構造体を紹介しました。
ここでは自分自身の型のメンバを持つ構造体を解説します。
厳密には「自分自身の型のメンバ」ではなく「自分自身の型のメンバのポインタ」を持つ構造体です。これを自己参照構造体と呼びます。
例えば「struct str」という構造体を定義したとすると、自己参照構造体であればメンバに「struct str* s」を持つということです。
これが何の役に立つかというと、配列ではない別のデータ構造を定義することができます。
具体的には次節のサンプルコードで解説します。
サンプルコード
self-referential_structure_sample.c
#include <stdio.h> struct myArray { int data; struct myArray* after_data; }; void showArrayList(struct myArray d) { printf("%d\n", d.data); if(d.after_data != NULL) showArrayList(*(d.after_data)); } int main(void) { struct myArray d0, d1, d2, d3, d4; d0.data = 10; d1.data = 6; d2.data = 45; d3.data = 0; d4.data = 33; d0.after_data = NULL; d1.after_data = &d0; d2.after_data = &d1; d3.after_data = &d2; d4.after_data = &d3; showArrayList(d4); return 0; }
ポインタ、再帰関数を扱うやや難しいコードですが、頑張って読んでみましょう。
上から順にmyArray構造体、myArray構造体を表示する関数、main()関数となっています。
一つずつ見ていきましょう。
myArray構造体はint型変数dataと、myArray構造体型のポインタafter_dataを持っています。dataは表示したいデータでafter_dataはそのデータの次のデータのアドレスを格納する変数です。
showArrayList()はmyArray構造体全てを表示する関数です。
myArray型の引数dをとり、dのデータを表示し、dのafter_dataすなわち次のデータがあれば再帰呼び出しによってそのデータを表示します。
*【ポインタ名】で指定したポインタの指す値を取り出すことができるので、d.after_dataの指す値、すなわち次のmyArray型のデータを示しています。
main()関数では、myArray型の変数を5つ定義し、それぞれにdataとafter_dataを代入しています。
変数名の前に&をつけると、その変数のアドレスを指します。
そして、最初のデータであるd4を引数としてshowArrayList()を呼び出しています。
このように、あるデータに同じ型のデータのアドレスを持たせることによってデータ同士を連結させることができます。
これを使えば、二分探索木など、様々なデータ構造を定義することができます。