構造体のメンバに自己へのポインタが入っている構造体を「自己参照型構造体」(自己参照構造体,Self-Referential Structure)と言います。例えば,次のようなケースです。
struct s { int n; struct s *p; };
このような構造体に対し,
struct s x, *a;
と宣言すると,構造体変数 x
は int
型変数 n
と 構造体 s
型へのポインタ p
の2つのメンバを持ちます。したがって,
a = &x;
とした場合,
a -> p
は x.p
への参照となります。そして,
x.p -> n
は x.n
を参照することになります。
/* Example 11.12 */ #include <stdio.h> struct s { int n; struct s *p; } x, *a; int main(void) { a = &x; a -> n = 1; printf("(1) x.n = %d\t[%p]\n", x.n, &x.n); printf("(2) x.p \t[%p] -> ", x.p); a -> p = a; printf("[%p]\n", x.p); x.p -> n = 2; printf("(3) x.n = %d\t[%p]\n", x.n, &x.n); return 0; }
実行結果です。
(1) x.n = 1 [0x20a8] (2) x.p [0x0] -> [0x20a8] (3) x.n = 2 [0x20a8]
角括弧内はアドレスです。NULLポインタであった x.p
を a -> p = a
で x
のアドレスを指定し(出力 2),ポインタ演算子でメンバ n
に値 2
を代入しています。この結果,x.n
の値が 1
から 2
に変化している様子が出力 (1) と出力 (3) の比較で分かります。
自己参照型である利点は,次に見る「リスト型データ構造」や応用編でみる「二分木」の方で活用されます。