->
構造体メンバを参照する演算子には既に見た「メンバ演算子」と,もう一つ「ポインタ演算子」があります。ここでは「ポインタ演算子」を見ます。
ポインタ演算子は,構造体へのポインタよりメンバを参照するものです。次の宣言
struct s { int n; char str[12]; } x[20], *p;
におけるオブジェクト x
は構造体 s
型配列,そして p
は構造体 s
型へのポインタです。これに対し,式文
p = x;
が実行されると,ポインタ p
に配列 x[20]
の第1要素のアドレスが代入されます。(配列型の文法を参照。)間接参照すると *p = x[0]
ですが,操作対象の値は x[0]
ではなく,そのメンバ x[0].n
や x[0].str
です。したがって,間接演算子を使った値の参照ができません。そこで,ポインタからメンバを直接参照できる仕組みが必要です。それが「ポインタ演算子」です。
■ポインタ演算子(Pointer Operator)
ポインタ -> メンバ名
例えば,上のケースを使えば,p -> n == x[0].n
が成り立ちます。したがって,
p -> n = 4;
とすれば,x[0].n
に 4
が代入されます。すなわち,式文
x[0].n = 4;
を実行したことと同じことになります。一般的には,構造体変数 x
とメンバ m
,そしてポインタ p == &x
があったとき,
p -> m == x.m
が成り立つことになります。
/* Example 11.11 */ #include <stdio.h> #include <string.h> struct s { char n; char str[12]; } x[20] = { {1, "first"}, {2, "second"}, {3, "third"} }; int main(void) { struct s *p; for (p = x; p -> n != 0; p++) printf("x[%td] %d %s\n", p - x, p -> n, p -> str); p -> n = 4; memcpy(p -> str, "fourth", sizeof(p -> str) - 1); printf("x[%td] %d %s\n", p - x, p -> n, p -> str); return 0; }
この例の for
文は「配列の末尾を探す」の構造体配列版です。繰り返しの条件 p -> n != 0
は,ポインタ p
が現在指しているアドレス(配列 x[i]
のアドレス)のメンバ n
の値が 0
でなければという意味です。また printf
内の p - x
は「ポインタ同士の差」です。実行すると,次のように出力されます。
x[0] 1 first x[1] 2 second x[2] 3 third x[3] 4 fourth
x[3]
に指定した値や文字列が代入されています。