複数のデータをまとめて扱うには配列を用いましたが、配列では同じ型のデータしかまとめて扱う事はできません。
実際にプログラムを組んでいると、異なる型のデータをまとめて扱いたい場合がしばしばあります。 たとえば、学生の成績を扱うときに、int型の学生番号と、char型配列の氏名と、double型の点数をまとめて扱えれば便利だと思いませんか。
実は、この章で学習する「構造体」は幾つかの異なる型のデータをまとめて 1つのデータ型として扱うものなのです。
1. 構造体の使用手順
サンプルプログラムを見ながら構造体の使用手順を説明します。
#include <stdio.h>
// (1) 構造体の型枠の宣言
struct seiseki {
int no; // 学生番号
char name[20]; // 氏名
double average; // 平均値
};
int main(void)
{
// (2) 構造体の宣言
// (3) 構造体の初期化
struct seiseki seito1 = {5, "KASAHARA", 83.5};
struct seiseki seito2[20] = {
{1, "SAKURAI", 78.6},
{2, "NAGANO", 57.3},
{3, "TAKESHITA", 66.4},
};
// (4) 構造体の参照
printf("%d %s %5.1f\n\n",seito1.no,seito1.name,seito1.average);
for(int i = 0; i < 3; i++) {
printf("%d %s %5.1f\n", seito2[i].no, seito2[i].name, seito2[i].average);
}
return 0;
}
【実行結果例】
5 KASAHARA 83.5
1 SAKURAI 78.6
2 NAGANO 57.3
3 TAKESHITA 66.4
(1) 構造体の型枠の宣言
まず、複数のデータ(メンバと呼びます)をまとめて1つの構造体の型枠を宣言します。
この宣言は単に構造体の型を作ったにすぎず、領域の割当ては行われていません。
(書き方)
struct タグ名 {
データ型 メンバ名;
};
// 例
struct seiseki {
int no;
char name[20];
double average;
};
(2) 構造体の宣言
(1)で作った「型枠」を使って実際にデータを宣言し、メモリ上に領域を確保します。
構造体は「構造体の変数」として 1つの構造体を扱う事も出来ますし、複数の構造体をまとめて「構造の体配列」として扱う事も出来ます。
(書き方)
struct タグ名 変数名の並び;
struct seiseki seito1; // 例1
struct seiseki seito2[20]; // 例2
例1.構造体の変数の例
eiseki という構造をもつ seito1 という「変数」を宣言

例2.構造体の配列の例
seiseki という構造をもつ seito2 という「配列」を宣言

(3) 構造体の初期化
構造体は一般の変数や配列同様、(2)の宣言時に合わせて初期化を行うことが出来ます。
構造体の変数の初期化
{ } の間に、各メンバ名をカンマで区切って記述。
struct seiseki seito1 = {5, "KASAHARA", 83.5};
構造体の配列の初期化
各配列要素ごとに、{ } で区切って記述。
struct seiseki seito2[20] = {
{1, "SAKURAI", 78.6},
{2, "NAGANO", 57.3},
{3, "TAKESHITA", 66.4},
};
(4) 構造体の参照
構造体の各メンバは、「構造体変数名. メンバ名」のようにピリオド(.)を用いて指定します。
この(.)を「ドット演算子」と呼びます。
構造体の変数の参照
printf("%d %s %5.1f\n\n", seito1.no, seito1.name, seito1.average);
構造体の配列の参照
for(int i = 0; i < 3; i++) {
printf("%d %s %5.1f\n", seito2[i].no, seito2[i].name, seito2[i].average);
}
〇 演習問題
問1
次に示す社員情報を構造体として作成し、内容を表示して確認せよ。
尚、データ表示は個数ではなく汎用性を考えて、社員番号「0」まで繰返して行うこと。
社員番号 | 氏名 | 役職 | 勤続年数 | 給与 |
---|---|---|---|---|
78027 | “神保直樹” | “課長” | 21 | 546780 |
84004 | “相原彰子” | “主任” | 15 | 453640 |
87022 | “本郷幸子” | “” | 12 | 388760 |
93042 | “三上葵” | “” | 6 | 326530 |
95005 | “佐々木翠” | “” | 4 | 296700 |
99009 | “長崎宏美” | “” | 1 | 250140 |
0 | “” | “” | 0 | 0 |
【実行結果例】 社員番号 氏名 役職 勤続年数 給与 78027 神保直樹 課長 21 546780 84004 相原彰子 主任 15 453640 87022 本郷幸子 12 388760 93042 三上葵 6 326530 95005 佐々木翠 4 296700 99009 長崎宏美 1 250140
問2
次の仕様に従って、生徒の科目得点から平均点と評価を求め、出力フォームのように画面表示するプログラムを作成しなさい。
プログラムに組み込むデータについては、構造体の初期値として与え、メンバは、生徒番号、各科目点数、平均点、評価で、次のとおりとすること。
生徒番号 国語 数学 理科 社会 平均点 評価 1001 85 74 63 90 0.0 ‘?’ 1002 78 65 70 62 0.0 ‘?’ 1003 89 92 88 76 0.0 ‘?’ 1004 32 48 66 25 0.0 ‘?’ 1005 92 76 81 98 0.0 ‘?’ 処理手順は、次のとおりとすること。
- 各人の 4科目の平均点を求め、構造体に格納すること。
- 各人の評価を求め、構造体に格納すること。尚、4段階の評価基準は、次のとおりとすること。
平均点 評価 80点以上 ‘A’ 70点以上 80点未満 ‘B’ 60点以上 70点未満 ‘C’ 60点未満 ‘D’ - 結果を出力フォームに従って表示すること。
【実行結果例】 番号 国語 数学 理科 社会 平均 評価 1001 85 74 63 90 78.00 B 1002 78 65 70 62 68.75 C 1003 89 92 88 76 86.25 A 1004 32 48 66 25 42.75 D 1005 92 76 81 98 86.75 A
解答例
// 問1
#include <stdio.h>
struct syain_dt { // 社員情報構造体
int no; // 社員番号
char name[20]; // 氏名
char yaku[20]; // 役職
int nensu; // 勤続年数
int kihon; // 給与
};
int main(void)
{
struct syain_dt syomu[20]= { // 庶務課
{78027, "神保直樹", "課長", 21, 546780},
{84004, "相原彰子", "主任", 15, 453640},
{87022, "本郷幸子", "", 12, 388760},
{93042, "三上葵", "", 6, 326530},
{95005, "佐々木翠", "", 4, 296700},
{99009, "長崎宏美", "", 1, 250140},
{0, "", "", 0, 0 },
};
printf("社員番号 氏名 役職 勤続年数 給与\n");
for (int i = 0; syomu[i].no != 0; i++) {
printf("%5d %-12s %5s %6d %10d\n",
syomu[i].no, syomu[i].name, syomu[i].yaku,
syomu[i].nensu, syomu[i].kihon);
}
return 0;
}
// 問2
#include <stdio.h>
#define NINZU 5 // 学生の人数
#define KAMOKU 4 // 科目数
struct seiseki { // 成績データ
int no; // 学生番号
int ten[4]; // 点数
double avg; // 平均点
char hyouka; // 評価
};
int main(void)
{
struct seiseki mycls[NINZU] = {
{1001, 85, 74, 63, 90, 0.0, '?'},
{1002, 78, 65, 70, 62, 0.0, '?'},
{1003, 89, 92, 88, 76, 0.0, '?'},
{1004, 32, 48, 66, 25, 0.0, '?'},
{1005, 92, 76, 81, 98, 0.0, '?'},
};
printf("番号 国語 数学 理科 社会 平均 評価\n");
for (int i = 0; i < NINZU; i++ ) {
// 平均点を求める
for (int j = 0; j < KAMOKU; j++) {
mycls[i].avg = mycls[i].avg + mycls[i].ten[j];
}
mycls[i].avg = mycls[i].avg / KAMOKU;
// 評価を求める
if (mycls[i].avg < 60.0)
mycls[i].hyouka = 'D';
else if (mycls[i].avg < 70.0)
mycls[i].hyouka = 'C';
else if (mycls[i].avg < 80.0)
mycls[i].hyouka = 'B';
else
mycls[i].hyouka = 'A';
}
// 結果の表示
for (int i = 0; i < NINZU; i++ ) {
printf("%4d %4d %4d %4d %4d %8.2f %c\n",
mycls[i].no, mycls[i].ten[0], mycls[i].ten[1],
mycls[i].ten[2], mycls[i].ten[3],
mycls[i].avg, mycls[i].hyouka);
}
return 0;
}
コメント