C の構造体は、異なるタイプの項目を 1 つのタイプにグループ化するために使用できるユーザー定義のデータ型です。の 構造体のキーワード C プログラミング言語で構造を定義するために使用されます。構造内の項目はその メンバー また、任意の有効なデータ型を使用できます。
ディレクトリの名前を変更する
C 構造体宣言
プログラムで構造体を使用する前に、C で構造体を宣言する必要があります。構造体の宣言では、そのメンバー変数をそのデータ型とともに指定します。 struct キーワードを使用すると、次の構文を使用して C で構造体を宣言できます。
構文
struct structure_name { data_type member_name1; data_type member_name1; .... .... };> 上記の構文は構造テンプレートまたは構造プロトタイプとも呼ばれ、宣言内の構造にはメモリが割り当てられません。
C 構造体の定義
プログラムで構造体を使用するには、そのインスタンスを定義する必要があります。これは、構造体タイプの変数を作成することで実現できます。次の 2 つの方法を使用して構造体変数を定義できます。
1. 構造体テンプレートを使用した構造体変数宣言
struct structure_name { data_type member_name1; data_type member_name1; .... .... } variable1, varaible2, ... ;> 2. 構造体テンプレート後の構造体変数宣言
// structure declared beforehand struct structure_name variable1, variable2 , .......;>
構造体のメンバーにアクセスする
構造体のメンバーにアクセスするには、 ( . ) ドット演算子。
構文
structure_name.member1; strcuture_name.member2;>
構造体へのポインターがある場合は、アロー演算子を使用してメンバーにアクセスすることもできます。
構造体のメンバーを初期化する
構造体のメンバー ありえない 宣言で初期化されます。たとえば、次の C プログラムはコンパイルに失敗します。
struct Point { int x = 0; // COMPILER ERROR: cannot initialize members here int y = 0; // COMPILER ERROR: cannot initialize members here };> 上記のエラーの理由は簡単です。データ型が宣言されると、そのデータ型にはメモリが割り当てられません。メモリは変数の作成時にのみ割り当てられます。
構造体のメンバーは次の 3 つの方法で初期化できます。
- 代入演算子の使用。
- イニシャライザリストの使用。
- 指定された初期化子リストを使用します。
1. 代入演算子を使用した初期化
struct structure_name str; str.member1 = value1; str.member2 = value2; str.member3 = value3; . . .>
2. Initializer Listを使用した初期化
struct structure_name str = { value1, value2, value3 };> このタイプの初期化では、値は構造テンプレートで宣言された順序で割り当てられます。
3. 指定イニシャライザリストを使用した初期化
指定された初期化を使用すると、構造体のメンバーを任意の順序で初期化できます。この機能は C99 標準に追加されました。
struct structure_name str = { .member1 = value1, .member2 = value2, .member3 = value3 };> 指定された初期化は C でのみサポートされており、C++ ではサポートされていません。
C の構造体の例
次の C プログラムは、構造体の使用方法を示しています。
C
// C program to illustrate the use of structures> #include> > // declaring structure with name str1> struct> str1 {> >int> i;> >char> c;> >float> f;> >char> s[30];> };> > // declaring structure with name str2> struct> str2 {> >int> ii;> >char> cc;> >float> ff;> } var;>// variable declaration with structure template> > // Driver code> int> main()> {> >// variable declaration after structure template> >// initialization with initializer list and designated> >// initializer list> >struct> str1 var1 = { 1,>'A'>, 1.00,>'techcodeview.com'> },> >var2;> >struct> str2 var3 = { .ff = 5.00, .ii = 5, .cc =>'a'> };> > >// copying structure using assignment operator> >var2 = var1;> > >printf>(>'Struct 1:
i = %d, c = %c, f = %f, s = %s
'>,> >var1.i, var1.c, var1.f, var1.s);> >printf>(>'Struct 2:
i = %d, c = %c, f = %f, s = %s
'>,> >var2.i, var2.c, var2.f, var2.s);> >printf>(>'Struct 3
i = %d, c = %c, f = %f
'>, var3.ii,> >var3.cc, var3.ff);> > >return> 0;> }> |
>
>出力
Struct 1: i = 1, c = A, f = 1.000000, s = techcodeview.com Struct 2: i = 1, c = A, f = 1.000000, s = techcodeview.com Struct 3 i = 5, c = a, f = 5.000000>
構造体の typedef
の typedef キーワードは、既存のデータ型の別名を定義するために使用されます。構造体では、構造体名とともに struct キーワードを使用して変数を定義する必要があります。場合によっては、これによりコードの長さと複雑さが増加します。 typedef を使用して、構造体の新しい短い名前を定義できます。
例
C
// C Program to illustrate the use of typedef with> // structures> #include> > // defining structure> struct> str1 {> >int> a;> };> > // defining new name for str1> typedef> struct> str1 str1;> > // another way of using typedef with structures> typedef> struct> str2 {> >int> x;> } str2;> > int> main()> {> >// creating structure variables using new names> >str1 var1 = { 20 };> >str2 var2 = { 314 };> > >printf>(>'var1.a = %d
'>, var1.a);> >printf>(>'var2.x = %d'>, var2.x);> > >return> 0;> }> |
>
>出力
var1.a = 20 var2.x = 314>
入れ子構造
C 言語では、ある構造体を別の構造体にメンバーとして挿入できます。このプロセスはネスティングと呼ばれ、そのような構造はネスト構造と呼ばれます。ある構造を別の構造にネストする方法は 2 つあります。
1. 埋め込み構造のネスト
このメソッドでは、ネストされる構造体も親構造体の内部で宣言されます。
例
文字列配列c
struct parent { int member1; struct member_str member2 { int member_str1; char member_str2; ... } ... }> 2. 個別構造のネスト
このメソッドでは、2 つの構造体が別々に宣言され、メンバー構造体が親構造体内にネストされます。
例
struct member_str { int member_str1; char member_str2; ... } struct parent { int member1; struct member_str member2; ... }> ここで注意すべき点の 1 つは、構造体の宣言は常に構造体のメンバーとしての定義の前に存在する必要があるということです。たとえば、 以下の宣言は無効です struct mem は親構造体内で宣言されるときには定義されないためです。
struct parent { struct mem a; }; struct mem { int var; };> ネストされたメンバーへのアクセス
次に示すように、同じ ( . ) ドット演算子を 2 回使用することで、ネストされたメンバーにアクセスできます。
str_parent.str_child .member;>
構造体のネストの例
C
// C Program to illustrate structure nesting along with> // forward declaration> #include> > // child structure declaration> struct> child {> >int> x;> >char> c;> };> > // parent structure declaration> struct> parent {> >int> a;> >struct> child b;> };> > // driver code> int> main()> {> >struct> parent var1 = { 25, 195,>'A'> };> > >// accessing and printing nested members> >printf>(>'var1.a = %d
'>, var1.a);> >printf>(>'var1.b.x = %d
'>, var1.b.x);> >printf>(>'var1.b.c = %c'>, var1.b.c);> > >return> 0;> }> |
>
>出力
var1.a = 25 var1.b.x = 195 var1.b.c = A>
C の構造体ポインター
他の変数と同様に、構造体を指すポインターを定義できます。このようなポインタは一般に次のように呼ばれます。 構造体ポインター 。構造体ポインタが指す構造体のメンバーには、 ( -> ) 矢印演算子。
構造体ポインタの例
C
// C program to illustrate the structure pointer> #include> > // structure declaration> struct> Point {> >int> x, y;> };> > int> main()> {> >struct> Point str = { 1, 2 };> > >// p2 is a pointer to structure p1> >struct> Point* ptr = &str;> > >// Accessing structure members using structure pointer> >printf>(>'%d %d'>, ptr->x、ptr->y);>> > >return> 0;> }> |
>
>出力
1 2>
自己参照構造
C の自己参照構造体は、それ自体と同じ型への参照を含む構造体です。つまり、同じ構造体型を指す型ポインタのメンバーが含まれています。
自己参照構造の例
struct structure_name { data_type member1; data_type member2; struct structure_name* str; }> C
// C program to illustrate the self referential structures> #include> > // structure template> typedef> struct> str {> >int> mem1;> >int> mem2;> >struct> str* next;> }str;> > // driver code> int> main()> {> >str var1 = { 1, 2, NULL };> >str var2 = { 10, 20, NULL };> > >// assigning the address of var2 to var1.next> >var1.next = &var2;> > >// pointer to var1> >str *ptr1 = &var1;> > >// accessing var2 members using var1> >printf>(>'var2.mem1: %d
var2.mem2: %d'>, ptr1->次->mem1、>> > >return> 0;> }> |
>
>出力
var2.mem1: 10 var2.mem2: 20>
このような種類の構造は、リンク リストやツリーなどのノードを定義するなど、さまざまなデータ構造で使用されます。
C 構造体のパディングとパッキング
技術的には、C の構造体のサイズは、そのメンバーのサイズの合計である必要があります。しかし、それはほとんどの場合には当てはまらないかもしれません。その理由は構造パディングにあります。
構造体のパディング 構造内に複数の空のバイトを追加して、メモリ内のデータ メンバーを自然に配置するという概念です。これは、構造内のさまざまなデータ メンバーを取得するための CPU 読み取りサイクルを最小限に抑えるために行われます。
状況によっては、空のバイトを削除して構造体をしっかりとパックする必要があることがあります。そのような場合に私たちが使用するのは、 構造パッキング。 C 言語では、構造体のパッキングに次の 2 つの方法が提供されます。
- #pragma Pack(1) の使用
- __attribute((packed))__ の使用
構造体のパディングとパッキングの例
C
// C program to illustrate structure padding and packing> #include> > // structure with padding> struct> str1 {> >char> c;> >int> i;> };> > struct> str2 {> >char> c;> >int> i;> } __attribute((packed)) __;>// using structure packing> > // driver code> int> main()> {> > >printf>(>'Size of str1: %d
'>,>sizeof>(>struct> str1));> >printf>(>'Size of str2: %d
'>,>sizeof>(>struct> str2));> >return> 0;> }> |
>
>出力
Size of str1: 8 Size of str2: 5>
見てわかるように、構造体のパッキングが実行されると、構造体のサイズが変化します。
構造体のパディングとパッキングについて詳しくは、この記事を参照してください。ビット フィールドは、構造体のメンバーの長さをビット単位で指定するために使用されます。メンバーの最大長がわかっている場合は、ビット フィールドを使用してサイズを指定し、メモリ消費を削減できます。
ビットフィールドの構文
struct structure_name { data_type member_name : width_of_bit-field; };> ビットフィールドの例
C
エフムービーズ
// C Program to illustrate bit fields in structures> #include> > // declaring structure for reference> struct> str1 {> >int> a;> >char> c;> };> > // structure with bit fields> struct> str2 {> >int> a : 24;>// size of 'a' is 3 bytes = 24 bits> >char> c;> };> > // driver code> int> main()> {> >printf>(>'Size of Str1: %d
Size of Str2: %d'>,> >sizeof>(>struct> str1),>sizeof>(>struct> str2));> >return> 0;> }> |
>
>出力
Size of Str1: 8 Size of Str2: 4>
ご覧のとおり、ビット フィールドを使用してメンバー「a」の最大サイズを定義すると、構造体のサイズが減少します。
C での構造体の使用
C 構造体は次の目的で使用されます。
- この構造体を使用して、言語に存在しない日付、時刻、複素数などの複雑なデータ型を作成するために使用できるカスタム データ型を定義できます。
- また、大量のデータをさまざまなフィールドに保存できるデータ整理にも使用できます。
- 構造は、ツリー、リンク リストなどのデータ構造を作成するために使用されます。
- 関数から複数の値を返すために使用することもできます。
C 構造体の制限
C 言語では、構造体は、さまざまなタイプのデータをまとめてパックする方法を提供します。構造は、論理的に関連するデータ項目のグループを処理するのに役立つツールです。ただし、C 構造体にもいくつかの制限があります。
- メモリ消費量の増加: 構造体のパディングが原因です。データ隠蔽なし: C 構造体ではデータ隠蔽は許可されません。構造体のメンバーには、構造体のスコープ内のどこにいても、任意の関数からアクセスできます。構造内の関数: C 構造では構造内の関数が許可されないため、関連する関数を提供できません。静的メンバー: C 構造体の本体内に静的メンバーを含めることはできません。 Structure でのコンストラクションの作成: C の Structure は、Structure 内にコンストラクターを持つことができません。
関連記事
- C 構造と C++ 構造
