構造体型の定義 では、構造体の一部になっているメンバーを記述します。構造体型の定義には、struct キーワードと、その後に続くオプションの ID (構造体タグ) および中括弧で囲まれたメンバーのリストが含まれています。
構造データ型の宣言は、次の形式を持ちます。
>>-struct--+-identifier--------------------------+------------->< | .-----------. | | V | | '-+------------+--{----member--;-+--}-' '-identifier-'
ID (タグ) が後に続くキーワード struct は、データ型に名前を付けます。タグの名前を与えない場合は、そのタグを参照するすべての変数定義を、 データ型の宣言内に入れる必要があります。
構造体宣言 は、宣言が中括弧で囲まれたメンバーのリストを持っていないということを除けば、 構造体定義と同じ形式です。 構造体定義は、構造体データ型の宣言と同じ形式を持ちますが、セミコロンで終了します。
構造体メンバーの定義
メンバーのリストで、構造体に保管できる値の説明と構造体データ型が提供されます。 C では、構造体メンバーは、「関数からの戻り T」(型によっては T)、不完全型、可変的に変更される型、 および void を除く、任意の型をとります。不完全型は構造体メンバーとして許可されないため、構造体 型はメンバーとしてそれ自身のインスタンスを含むことはできませんが、それ自身のインスタンス を指すポインターを含むことはできます。
構造体メンバーの定義は、変数宣言の形式になっています。構造体メンバーの名前は、 単一構造体内で固有でなければなりませんが、同じメンバー名は、同じスコープ内で定義された別の構造体型で使用でき、さらに、変数、関数、または型名と同じ名前であっても構いません。ビット・フィールドを表さないメンバーは、任意の データ型にすることができ、型修飾子 volatile または const のいずれかの型で修飾することができます。結果は、左辺値です。ただし、型修飾子のないビット・フィールドは、構造体メンバーとして 宣言することができます。ビット・フィールドは、名前がない場合は初期化には関与せず、初期化が終わると不定値を持ちます。
コンポーネントの適切な位置合わせを可能にするために、 ホールまたは埋め込みを構造体レイアウト内の連続メンバー間に置くことができます。
フレキシブルな配列メンバー
複数の名前付きメンバーを持つ構造体の最後のエレメントは、不完全な配列型となる ことができます。これを 柔軟な配列メンバー と呼びます。
柔軟な配列メンバー は、複数の名前付きメンバーを持つ構造のエレメントです。 柔軟な配列メンバーは、構造体などの最後のエレメントで、 不完全な配列型である必要があります。
>>-array_identifier[ ]-----------------------------------------><
例えば、b は struct foo の柔軟な配列メンバーです。
struct foo{ int a; char b[]; };struct foo のサイズは 4 です。struct foo は、 別の struct または配列のメンバーにすることはできません。
配列添え字がゼロの場合、配列メンバーはゼロ・エクステント配列 と見なされます。
>>-array_identifier[0]-----------------------------------------><
前記の例で b がゼロ・エクステント配列として宣言される場合、 struct foo のサイズは 4 のままですが、次の例のように、struct foo は 別の struct または配列のメンバーとすることができます。
struct bar{ struct foo zearray; };
普通、柔軟な配列メンバーは無視されます。 ただし、これは以下の 2 つの場合に認識されます。
2 番目の場合、アクセスしているオブジェクトよりも構造体を大きくすることのない最長の 配列に、メンバーが置き換えられたかのように振る舞います。配列のオフセットは、柔軟な配列メンバーの オフセットと同じままです。置換配列にエレメントがない場合、振る舞いはエレメントが 1 つあ る場合のように見えますが、そのエレメントにはアクセスできず、それを通過する ポインターも作成できません。以下の例で、d は構造体 struct s の柔軟な配列メンバーです。
// Assuming the same alignment for all array members, struct s { int n; double d[]; }; struct ss { int n; double d[1]; };
式 offsetof(struct s, d) および offsetof(struct ss, d) は、同じ値 sizeof(struct s) を持ちます。
関連参照