構造体の使用手順については理解できましたか。
ここでは構造体の使用例として、scanf関数でのデータ入力、構造体の一括代入、構造体の入れ子について説明します。
1. scanf関数を用いてのデータ入力
構造体に scanf関数でデータを入力する場合も通常の変数への入力と変わりありません。
各メンバの型を考えて引数を指定して行ってください。
変数のアドレスをとりだすには、’&’ を変数の前に付け、配列のアドレスをとりだすには、’&’ は不要です。
#include <stdio.h>
struct seiseki { // 構造体の宣言
int no;
char name[20];
double average;
};
int main(void)
{
struct seiseki seito1, seito2[20]; // 構造体の変数と配列の宣言
// 構造体の変数に scanfでデータを入力
scanf("%d", &seito1.no);
scanf("%s", seito1.name);
scanf("%lf", &seito1.average);
// 構造体の配列に scanfでデータを入力
for(int i = 0; i < 3; i++) {
scanf("%d", &seito2[i].no);
scanf("%s", seito2[i].name);
scanf("%lf", &seito2[i].average);
}
// 入力データの確認
printf("no:%d name:%s average:%f\n", seito1.no, seito1.name, seito1.average);
for(int i = 0; i < 3; i++) {
printf("no:%d name:%s average:%f\n",
seito2[i].no, seito2[i].name, seito2[i].average);
}
return 0;
}
【実行結果例】
123 田中 78.4
124 千葉 81.3
125 土田 73.3
126 手塚 68.2
no:123 name:田中 average:78.400000
no:124 name:千葉 average:81.300000
no:125 name:土田 average:73.300000
no:126 name:手塚 average:68.200000
※ 水色字はキーボードからの入力
2. 構造体の一括代入
同一の型を持った構造体は一括して代入が可能です。
#include <stdio.h>
struct seiseki {
int no;
char name[20];
double average;
};
int main(void)
{
struct seiseki seito1 = { 5, "KASAHARA", 83.5 };
struct seiseki seito2, seito3[20];
// 構造体変数の一括代入
seito2 = seito1;
seito3[1] = seito1;
/* seito2 と seito3[1] の各メンバには、
seito1 の内容がそのまま代入された */
printf("seito1 %d %s %.1f\n", seito1.no, seito1.name, seito1.average);
printf("seito2 %d %s %.1f\n", seito2.no, seito2.name, seito2.average);
printf("seito3[1] %d %s %.1f\n", seito3[1].no, seito3[1].name, seito3[1].average);
return 0;
}
【実行結果例】
seito1 5 KASAHARA 83.5
seito2 5 KASAHARA 83.5
seito3[1] 5 KASAHARA 83.5
3. 構造体の入れ子
構造体の中に構造体を入れ子にして宣言することが可能です。
#include <stdio.h>
struct kyuuyo { // 給与
int kihon; // 基本給
int jyutaku; // 住宅手当
int kazoku; // 家族手当
int sikaku; // 資格手当
} kyu;
struct syain_dt { // 社員情報
int no; // 社員番号
char name[20]; // 氏名
char yaku[20]; // 役職
int nensu; // 勤続年数
struct kyuuyo kyu; // 給与
};
構造体の入れ子:
先に宣言した構造体を入れ子にして用いる。
入れ子に用いる構造体は必ず先に宣言すること。

int main(void)
{
struct syain_dt syomu[20]= { // 庶務課
{78027, "神保直樹", "課長", 21, {446780, 50000, 30000, 20000}},
{84004, "相原彰子", "主任", 15, {363640, 50000, 20000, 20000}},
{87022, "本郷幸子", "", 12, {308760, 50000, 10000, 20000}},
{93042, "三上葵", "", 6, {286530, 30000, 0, 10000}},
{95005, "佐々木翠", "", 4, {276700, 0, 0, 20000}},
{99009, "長崎宏美", "", 1, {250140, 0, 0, 0}},
{0, "", "", 0, {0, 0, 0, 0} },
};
for (int i = 0; syomu[i].no != 0; i++) {
printf("%-10s 総支給額 = %d\n",
syomu[i].name,
syomu[i].kyu.kihon + syomu[i].kyu.jyutaku +
syomu[i].kyu.kazoku + syomu[i].kyu.sikaku);
}
return 0;
}
↑
初期化は全てのメンバを順に並べて行う。
メンバの参照はドット演算子(.)を2つ用いて行う。
【実行結果例】
神保直樹 総支給額 = 546780
相原彰子 総支給額 = 453640
本郷幸子 総支給額 = 388760
三上葵 総支給額 = 326530
佐々木翠 総支給額 = 296700
長崎宏美 総支給額 = 250140
〇 演習問題
図書データを設定する下記のような構造体配列がある。同じ構造の作業用の構造体変数に、図書名、返却予定年月日を、返却予定年に0が入力されるまで入力しなさい。
入力した図書が構造体配列にすでに登録されている場合は「貸し出し中」をメッセージ出力し、未登録の場合は構造体配列に登録しなさい。

【実行結果例】
図書名、年月日を入力しなさい。(終了条件:年が0)
星を継ぐもの 2025 6 3
貸し出しOKです。
図書名、年月日を入力しなさい。(終了条件:年が0)
巨人たちの星 2025 6 10
貸し出しOKです。
図書名、年月日を入力しなさい。(終了条件:年が0)
星を継ぐもの 2025 6 15
貸し出し中です。別の本を指定してください。
三体 2025 6 15
貸し出しOKです。
図書名、年月日を入力しなさい。(終了条件:年が0)
0 0 0 0
処理を終了します。
「星を継ぐもの」 2025.06.03
「巨人たちの星」 2025.06.10
「三体」 2025.06.15
※ 水色字はキーボードからの入力
解答例
#include <stdio.h>
#include <string.h>
#define ULIMIT 100 // 配列数上限
struct date { // 日付
int yy; // 年
int mm; // 月
int dd; // 日
};
struct tosyo { // 図書データ
char name[100]; // 図書名
struct date henkyaku; // 返却予定日
};
int main(void)
{
struct tosyo work;
struct tosyo rireki[ULIMIT];
int i, cnt = 0;
printf("図書名、年月日を入力しなさい。(終了条件:年が0)\n");
while (1) {
scanf("%99s %d %d %d", work.name, &work.henkyaku.yy,
&work.henkyaku.mm, &work.henkyaku.dd);
// 返却予定年が0かなら登録終了
if (work.henkyaku.yy == 0) {
printf("処理を終了します。\n");
break;
}
for (i = 0; i < cnt; i++) {
// 貸し出し中
if (strcmp(work.name, rireki[i].name) == 0) break;
}
if (i < cnt) {
printf("貸し出し中です。別の本を指定してください。\n");
continue;
}
// 貸し出しOK
printf("貸し出しOKです。\n");
rireki[cnt++] = work;
// 配列上限なら終了
if (cnt >= ULIMIT) {
printf("登録冊数に達しました。処理を終了します。\n");
break;
}
printf("図書名、年月日を入力しなさい。(終了条件:年が0)\n");
}
for (i = 0; i < cnt; i++) {
printf("「%s」 %4d.%02d.%02d\n", rireki[i].name,
rireki[i].henkyaku.yy, rireki[i].henkyaku.mm, rireki[i].henkyaku.dd);
}
return 0;
}
コメント