対象 | C言語初心者 |
記事概要 | C言語の構造体について記載しています。 |
筆者 | Zuu [ ] C言語歴20年以上。 大手電機メーカーでの製品開発およびマネジメント経験がある現役エンジニアです。 プロジェクトマネージャ、システムアーキテクトなどの資格を保有しています。 |
はじめに
構造体は、「変数」の一種です。変数についての理解が不十分だと感じている場合は、まずは変数について学びましょう。
本サイトでは、以下の記事で変数について説明しています。よろしければご覧ください。
構造体とは?
構造体(こうぞうたい、英: structure)はプログラミング言語におけるデータ型の一つで、1つもしくは複数の値をまとめて格納できる型。それぞれのメンバー(フィールド)に名前が付いている点、またメンバーの型が異なっていてもよい点が配列と異なる。
理解しておきたいポイントは以下の2点です。
- 複数のメンバーに名前をつけて1つにまとめる。
- メンバーの型は異なっていても良い。
例えば、「名前・身長・体重」をまとめて管理したいといった場合に利用します。
やみくもにまとめるのではなく、関連するデータのみをまとめると良い構造体になります。
C言語での構造体の扱い方
構造体は変数の一種なので、使う場合には宣言が必要です。
ただし、構造体の場合は、構造体がどのようなメンバーで構成されているのかをあらかじめ定義しておく必要があります。構造体の定義には、「struct」という構文を使用します。
また、構造体が持っているメンバーへのアクセスには「.」を使用します。
※「変数名.メンバー名」となります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* 構造体の定義 */ struct person { char name[16]; /* 名前 */ int height; /* 身長 */ int weight; /* 体重 */ }; int main(void) { struct person p; /* 構造体変数の宣言(struct personまでが型、pが変数名) */ p.height = 170; /* 構造体のメンバーへの代入 */ p.weight = 64; strcpy(p.name, "Taro"); printf("Name : %s\n", p.name); printf("Height: %d\n", p.height); printf("Weight: %d\n", p.weight); return 0; } |
その他に覚えておきたいこと
構造体の初期化方法
構造体は、変数の一種のため、宣言時に初期化することもできます。
定義したメンバー順に初期値を記述する形となります。
1 |
struct person p = {"Taro", 170, 64}; |
独自の型名の定義方法
構造体は、変数宣言時に「struct 〇〇」とする必要があり、少し煩雑でした。
「struct」を省略して、intなどの型と同じようにする便利な方法があります。
よく使うので是非慣れておきたいですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* 構造体の定義 */ typedef struct person { char name[16]; /* 名前 */ int height; /* 身長 */ int weight; /* 体重 */ } PERSON; int main(void) { PERSON p; /* structを省略でき、intなどの型のように使える */ p.height = 170; /* 構造体のメンバーへの代入 */ p.weight = 64; strcpy(p.name, "Taro"); printf("Name : %s\n", p.name); printf("Height: %d\n", p.height); printf("Weight: %d\n", p.weight); return 0; } |
ポインタを使った構造体へのアクセス方法
※後で説明する「ポインタ」に関連するので、最初は読み飛ばしてもらって、また後で読むというのでも構いません。
構造体が持っているメンバーへのアクセスには「.」を使用すると説明しましたが、「.」を使えないケースがあります。それは、ポインタを使って構造体へアクセスするケースです。
ポインタを使って構造体へアクセスする場合は、「->」を使う必要があります。
通常のアクセスか、ポインタを使ったアクセスかどうかを見極めて、「.」と「->」を使い分けます。混乱しやすい部分なので、しっかり理解しておきましょう。具体的には、以下の部分に注目すると区別できます。
*なし:「.」
*あり:「->」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* 構造体の定義 */ typedef struct person { char name[16]; /* 名前 */ int height; /* 身長 */ int weight; /* 体重 */ } PERSON; void PERSON_print(PERSON *p) { printf("Name : %s\n", p->name); /* ポインタを使ったアクセスのため「->」を使用 */ printf("Height: %d\n", p->height); printf("Weight: %d\n", p->weight); } int main(void) { PERSON p = {"Taro", 170, 64}; PERSON_print(&p); return 0; } |
構造体も配列にできる
構造体は独自の型を定義するものなので、intなどの標準の型と同様に配列として使うことができます。
1 2 3 4 5 6 7 8 9 10 |
int main(void) { PERSON p[2] = {{"Taro", 170, 64}, {"Jiro", 171, 65}}; for (int i = 0; i < 2; i++) { PERSON_print(&p[i]); } return 0; } |
まとめ
- 構造体は、複数のメンバーに名前をつけて1つにまとめる場合に使用する。
- 関連するデータのみをまとめると良い構造体になる。
- 通常のアクセスとポインタを使ったアクセスでメンバーへのアクセス方法が変わる。
- 構造体は、配列としても使用可能。
コメント