
はじめてのC言語 | 第16回
はじめに
前回は、関数と配列の受け渡しを学びました。
今回は、C言語の「構造体」を学びます。
構造体を使うと、複数の値を1つのまとまりとして扱えます。
たとえば、学生の名前、年齢、点数を1つのデータとしてまとめることができます。
この回の目的は次の5点です。
- 構造体が何をするための仕組みかを理解する
structを使った型の作り方を学ぶ- メンバへのアクセス方法を覚える
- 構造体を関数に渡す基本を確認する
- 構造体の配列を扱う基本を学ぶ
構造体とは何か
構造体は、複数の値を1つにまとめるための仕組みです。
配列は同じ型の値をまとめますが、構造体は異なる型の値をまとめることができます。
たとえば学生の情報を扱う場合、次のような値が必要になることがあります。
- 名前
- 年齢
- 点数
これらを別々の変数で管理すると、データが増えたときに扱いにくくなります。
構造体を使うと、これらを1つのまとまりとして扱えます。
構造体を定義する
構造体は struct を使って定義します。
struct Student {
char name[20];
int age;
int score;
};この定義では、Student という構造体を作っています。
中には、name age score という3つのメンバがあります。
構造体を使って表示する
ソースコード
struct_basic.c という名前で保存します。
#include <stdio.h>
struct Student {
char name[20];
int age;
int score;
};
int main(void) {
struct Student s = {"Alice", 20, 85};
printf("%s\n", s.name);
printf("%d\n", s.age);
printf("%d\n", s.score);
return 0;
}実行手順
1. 作業ディレクトリに移動する
cd ~/Desktop2. コンパイルする
clang struct_basic.c -o struct_basic3. 実行する
./struct_basic実行結果:
Alice
20
85コードの読み方
struct Student
struct Student {
char name[20];
int age;
int score;
};これは構造体の定義です。struct Student という型を作っています。
struct Student s
struct Student s = {"Alice", 20, 85};これは、struct Student 型の変数 s を作っています。"Alice" が name、20 が age、85 が score に入ります。
s.name
printf("%s\n", s.name);構造体の中の値にアクセスするときは、. を使います。s.name は、構造体変数 s の name メンバを表します。
メンバに代入する
構造体のメンバには、あとから値を代入できます。
#include <stdio.h>
#include <string.h>
struct Student {
char name[20];
int age;
int score;
};
int main(void) {
struct Student s;
strcpy(s.name, "Bob");
s.age = 19;
s.score = 92;
printf("%s %d %d\n", s.name, s.age, s.score);
return 0;
}実行結果:
Bob 19 92文字列の代入に注意する
name は char 配列です。
そのため、あとから文字列を入れるときに次のようには書けません。
s.name = "Bob";文字列をコピーするには、前回学んだ strcpy を使います。
strcpy(s.name, "Bob");構造体を関数に渡す
構造体は関数に渡すこともできます。
#include <stdio.h>
struct Student {
char name[20];
int age;
int score;
};
void print_student(struct Student s) {
printf("%s %d %d\n", s.name, s.age, s.score);
}
int main(void) {
struct Student s = {"Alice", 20, 85};
print_student(s);
return 0;
}実行結果:
Alice 20 85関数の引数として渡せる
print_student は、struct Student 型の値を受け取る関数です。
void print_student(struct Student s)このように書くことで、構造体の中の複数の値をまとめて関数に渡せます。
構造体の配列
構造体は配列にすることもできます。
複数人の学生情報を扱う場合に便利です。
#include <stdio.h>
struct Student {
char name[20];
int age;
int score;
};
int main(void) {
struct Student students[3] = {
{"Alice", 20, 85},
{"Bob", 19, 92},
{"Carol", 21, 78}
};
int i;
for (i = 0; i < 3; i++) {
printf("%s %d %d\n", students[i].name, students[i].age, students[i].score);
}
return 0;
}実行結果:
Alice 20 85
Bob 19 92
Carol 21 78students[i].name
students[i] は、構造体配列の i 番目の要素です。
その中の name メンバにアクセスするため、students[i].name と書きます。
構造体配列を関数に渡す
前回学んだ配列の受け渡しと同じように、構造体配列も関数に渡せます。
#include <stdio.h>
struct Student {
char name[20];
int age;
int score;
};
void print_students(struct Student students[], int size) {
int i;
for (i = 0; i < size; i++) {
printf("%s %d %d\n", students[i].name, students[i].age, students[i].score);
}
}
int main(void) {
struct Student students[3] = {
{"Alice", 20, 85},
{"Bob", 19, 92},
{"Carol", 21, 78}
};
print_students(students, 3);
return 0;
}実行結果:
Alice 20 85
Bob 19 92
Carol 21 78構造体配列を関数に渡す場合も、要素数を一緒に渡します。
関数側では、配列の要素数を自動では判断できないためです。
初心者がつまずきやすい点
struct Student まで含めて型名である
この段階では、型名は Student だけではなく struct Student です。
struct Student s;typedef を使うと短く書けますが、この回では基本の struct Student という書き方を使います。
メンバアクセスには .使う
構造体変数のメンバにアクセスするときは . を使います。
s.score = 90;s->score という書き方もありますが、これは構造体ポインタを扱うときに使います。
この回では、まず . を使う形を理解します。
文字列メンバに直接代入しない
char name[20]; のような配列メンバには、あとから = で文字列を代入できません。
文字列をコピーするときは strcpy を使います。
よくあるエラー
error: must use ‘struct’ tag to refer to type ‘Student’
原因: struct Student と書くべきところを Student だけで書いています。
対処: この回では struct Student と書きます。
正しい例:
struct Student s;error: array type ‘char[20]’ is not assignable
原因: char 配列のメンバに = で文字列を代入しています。
対処: strcpy を使います。
誤った例:
s.name = "Bob";正しい例:
strcpy(s.name, "Bob");実行結果がおかしい
原因: 構造体配列を処理するときに、要素数を間違えている可能性があります。
対処: 配列の要素数とループ条件を確認します。
練習用コード
商品情報を表示する
#include <stdio.h>
struct Product {
char name[20];
int price;
};
int main(void) {
struct Product p = {"Pen", 120};
printf("%s %d\n", p.name, p.price);
return 0;
}構造体配列から合計点を求める
#include <stdio.h>
struct Student {
char name[20];
int age;
int score;
};
int sum_scores(struct Student students[], int size) {
int i;
int sum = 0;
for (i = 0; i < size; i++) {
sum += students[i].score;
}
return sum;
}
int main(void) {
struct Student students[3] = {
{"Alice", 20, 85},
{"Bob", 19, 92},
{"Carol", 21, 78}
};
printf("%d\n", sum_scores(students, 3));
return 0;
}実行結果:
255まとめ
今回のポイントは次のとおりです。
- 構造体は複数の値を1つのまとまりとして扱う仕組みである
- 構造体は
structを使って定義する - 構造体の中の値をメンバと呼ぶ
- メンバにアクセスするときは
.を使う - 構造体は関数に渡せる
- 構造体は配列として複数まとめて扱える
- 構造体配列を関数に渡すときも要素数を一緒に渡す
この回では、構造体の基本を学びました。
構造体を使うと、名前、年齢、点数のような複数の値を1つのデータとして扱えます。
次回予告
次は、ファイル入出力の基本を学びます。
データを画面に表示するだけでなく、ファイルに保存したり、ファイルから読み込んだりすることができるようになります。


