C/C++学習 · 3 min read · Oct 10, 2025

C/C++を段階的に学ぶ - ページ10

10. 段階的C/C++ — Cプログラミング - 構造

構造

| | 1. はじめに

  1. 構造の宣言
  2. 構造変数の定義
  3. 構造変数の初期化
  4. 構造の直接代入
  5. 構造サイズの計算
  6. ネストされた構造
  7. 構造の配列
  8. 構造内の配列
  9. 構造を関数に渡す
  10. 関数から構造を返す
  11. 構造へのポインタ
  12. ポインタを含む構造
  13. 自己参照構造 |

1. はじめに

| | int a[4] = { 3, 4, 5, 6 };                / 有効な式 /
int a[4] = { 3, 4.23, 5, 6 };                / 無効な式 /
int a[4] = { 3, “Siglov”, 5,3}                / 無効な式 / |

なぜ最後の2つの式が無効なのか? 配列は同じ型の値を格納できます。型は同じでなければなりません。一方、構造体はその定義に従って複数の型のデータを保持できます。

| | • 異なるデータ型の1つ以上の変数のグループを単一の名前の下に整理したものを構造体と呼びます
• 異種(異なる)データ型のコレクションを単一の名前の下にグループ化したものを構造体と呼びます
• 構造体は単純な変数のコレクションです。構造体内の変数は異なる型であることができます。構造体内のデータ項目は構造体のメンバーと呼ばれます。 |

2. 構造の宣言

構造体が定義されると、全体のグループは構造体名を通じて参照されます。構造体内に存在する個々のコンポーネントは構造体メンバーと呼ばれ、これらは別々にアクセスして処理できます。

| | |

例:

| | struct date
{
int day;
int month;
int year;
}; | struct student
{
int sno;
char name[20];
int marks;
float avg;
}; |

3. 構造変数の定義

構造変数の定義は、intのような組み込みデータ型を定義するのと同じです。

| | int a;                             /  有効 /
date d;                          / 有効(ただしC++のみ) /
struct date d;                 / CおよびC++の両方で有効 / |

4. 構造変数の初期化

構造体のメンバーは他の変数と同様に初期化できます。これは宣言時または設計時に行うことができます。

| 1. 宣言時の初期化:
struct ddate
{
int day;
int month;
int year;
} d = { 27, 10, 2000 }; | 2. 定義時の初期化:
struct ddate d = { 27, 10, 2000 }; | | 1.
設計時の初期化: ddate d;
d.day = 27;
d.month = 10;
d.year = 2000;
| 4. 実行時の初期化:
scanf(“%d%d%d”, &d.day, &d.month, &d.year); |

例:

| | / 従業員の詳細を受け取り、印刷するプログラムを書く /
/ 73_struct.c /
#include
struct emp
{
int eno;
char name[20];
float sal;
};
int main()
{
struct emp e;

printf(“従業員番号を入力してください    :”); scanf(“%d”, &e.eno);
printf(“従業員名を入力してください       :”); scanf(“%s”, e.name);
printf(“従業員の給与を入力してください      :”); scanf(“%d”, &e.sal);
printf(“\n\n従業員の詳細は次のとおりです…. “);
printf(“%d    %s      %d”, e.eno, e.name, e.sal);
return 0;
} |

5. 構造の直接代入

複数の変数の直接代入は構造体を使用することで可能になります。

| | struct emp a, b = {1001, “Vimal”, 6700.00 };
a = b; / 有効 /
printf(“%d %s %d” , a.eno, a.name, a.sal ); | | | 出力:
1001 Vimal 6700.00 |

6. 構造サイズの計算

C/C++のすべてのデータ型には指定されたサイズがあります。つまり、intは2バイト、floatは4バイトのサイズです。ここでは、構造変数のサイズを見つける方法を示します。

sizeof:- この関数は、指定された変数のサイズを見つけるために使用されます。

| | printf(“%d”, sizeof(int));                           //
printf(“%d”, sizeof(float));                       //
printf(“%d”, sizeof(struct emp));              / emp構造のサイズを表示 / |

7. ネストされた構造

構造内に構造があるものをネストされた構造と呼びます。ネストされた構造メンバーにアクセスするには、呼び出し構造メンバーでドット演算子を2回適用する必要があります。

例:

| | / 従業員構造を使用したネストされた構造を示すプログラム /
/ 74_nested.c /
#include
struct emp
{
int eno;
char name[10];
float sal;
struct                                                    / ネストされた構造  /
{
street char[10];
city char[10];
} addr;
};
int main()
{
struct emp e;
printf(“従業員番号、従業員名、従業員給与、通り、都市を入力してください “);
scanf(“%d%s%d%s%s”, &e.eno, e.name, &e.sal, e.addr.street, e.addr.city );
printf(“\n\n従業員の詳細は次のとおりです   …. “);
printf(“%d%s%d%s%s”, e.eno, e.name, e.sal, e.addr.street, e.addr.city );
return 0;
} |

8. 構造の配列

構造の配列を作成できます。配列はその要素として個々の構造を持ちます。

| | / 従業員の詳細を受け取り、印刷するプログラムを書く /
/ 75_array.c  /
#include
struct emp
{
int eno;
char name[20];
float sal;
};
int main()
{
struct emp e [10];
int i;
for(i = 0; i<10; i++)
{
printf(“従業員番号を入力してください    :”); scanf(“%d”, &e [i].eno);
printf(“従業員名を入力してください       :”); scanf(“%s”, e [i].name);
printf(“従業員の給与を入力してください     :”); scanf(“%d”, &e [i].sal);
}
printf(“\n\n従業員の詳細は次のとおりです…. “);
for(i = 0; i<10; i++)
printf(“%d    %s      %d”, e [i].eno, e [i].name, e [i].sal);
return 0;
} |

上記のプログラムには新しいことはありません。全体のプログラムは、マークされたデータを除いて、単純な構造プログラムと同じです。

9. 構造内の配列

構造内で配列を利用する状況があるかもしれません。構造内で配列を実現する方法は次のとおりです。シンプルなプログラムでのアプローチを示します。

| | / 学生情報を受け取り、印刷するプログラム  /
/ 76_array.c /
#include
struct stud
{
int sno;
char name[10];
int marks[5];                              / 構造内の配列 /
};
int main()
{
struct stud s;
int i;
printf(“学生番号を入力してください  “); scanf(“%d”, &s.sno);
printf(“学生名を入力してください          “); scanf(“%d”, s.name);
for( i = 0; i<3; i++)
{
printf(“学生の成績を入力してください  “); scanf(“%d”, &s.marks[i]);
}
printf(“\n\n学生記録は次のとおりです…. “);
printf(“%d  %s  %d  %d  %d”, s.sno, s.name, s.marks[0], s.marks[1], s.marks[2] );
return 0;
} |

10. 構造を関数に渡す

構造全体を関数の引数として関数呼び出しに送ることができます。構造変数は通常の変数と同様に扱われます。

| | / 構造変数を関数に渡すプログラム /
/ 77_funct.c /
#include
struct emp
{
int eno;
char name[10];
float sal;
};
void display(struct emp temp);
int main()
{
struct emp e;
display(e);
return 0;
}
void display(struct emp temp)
{
printf(“%d  %s  %d”, temp.eno, temp.name, temp.sal );
} |

11. 関数から構造を返す

関数から構造を返すことができます。はい、構造は他の型の変数と同様に関数から返すことができます。

| | / 関数から構造オブジェクトを返す /
/ 78_funct.c /
struct emprec
{
int eno;
char name[10];
};
struct emprec read();
void write(struct emprec t);
int main()
{
struct emprec e;
e = read();
write(e);
return 0;
}
void write(struct emprec t)
{
printf(“\n\n%d  %s”, t.eno, t.name);
}
struct emprec read()
{
struct emprec t;
printf(“従業員番号を入力してください   :”); scanf(“%d”, &t.eno);
printf(“従業員名を入力してください         :”); scanf(“%s”, t.name);
return t;
} |

12. 構造へのポインタ

これまで、構造のメンバーはint、char、float、または構造のようなデータ型であることができることを見てきました。C/C++言語は、構造のメンバーとしてポインタ変数を宣言することも許可しています。ポインタ変数は構造変数のアドレスを格納するためにも使用できます。ポインタは、構造データ型を指すように宣言できます。

| | / 構造へのポインタのプロセスを示すプログラム /
/ 79_pointer.c /
#include
struct employee
{
int eno;
char name[10];
};
struct employee emp;
int main()
{
emp = (struct employee
)malloc(sizeof(emp));
printf(“従業員の詳細を入力してください ..”);
scanf(“%d%s%”, &emp->eno, emp->name);
printf(“\n\n%d   %s”, emp->eno, emp->name);
return 0;
} |

マークされたデータは、構造へのポインタを実装するために不可欠です。
次の文はオプションですが、より良いメモリ管理を行うために利用する方が良いです。
emp = (struct employee * )malloc(sizeof(emp));

13. ポインタを含む構造

ポインタ変数も構造のメンバーとして使用できます。
次のプログラムには、構造のポインタメンバーが含まれています。

| | / ポインタを含む構造の使用を示すプログラム /
/ 80_pointers.c  /
#include
struct
{
int a;
int
b;
} *temp;
int main()
{
int x, y;
x = 20; y = 50;
rk -> a = &x;
rk -> b = &y;

printf(“%d %d “, temp->a, temp->b );
return 0;
} | | | 出力:
20    50 |

14. 自己参照構造

構造は、含まれている同じ構造の型のメンバーを持つことができます。これはポインタを使用することで可能であり、この現象は自己参照構造と呼ばれます。

| | struct emp
{
int eno;
char name[10];
struct emp *e;
}; |

自己参照構造は、主にデータの整理、ソート、要素の検索、要素の挿入、削除などに使用されます。

このアプローチはデータ構造(すなわち、リンクリスト、スタック、キュー、木、グラフ)につながります。

Share: X/Twitter LinkedIn

新しい投稿を受信箱で受け取る

スパムはありません。いつでも購読を解除できます。