はやいもので本連載も,もう第8回目です。前々回,前回とも,C言語の初心者の方には,少し手ごわい内容だったかもしれません。

 今回は一度,入門レベルに戻り,「構造体」というものは何かから説明をはじめます。今回と次回の2回で,構造体の基本,構造体を使うと何が良いのか,動的にメモリーを確保する方法,線形リスト*1へと解説を進めていきます。今回はロール・プレイング・ゲーム(RPG)のようなプログラムも作ってみますので,はじめて本連載を読む方やC言語の入門は勉強したけど構造体やリストまではやらなかったという方も,ぜひ最後までお付き合いいただけたらと思います。

構造体とは関連する情報の固まり

 さて,ずばり構造体とは何でしょう? 構造体とは,C言語において組み込み済みの型*2を複数組み合わせて,新しい型を作る仕組みのことです。複数組み合わせるというと「配列」が頭に浮かびますが,構造体は配列とは違います。

 例えば,int a[6]という配列のコードは,int型の大きさの記憶領域を複数個確保するイメージになります(図1(a))。int a[6]には整数値を六つ記憶することができますね。つまり同じ製品を整然とダンボールに詰めていくのが配列です。

 これに対し,構造体は複数種類の型を組み合わせて,一つの固まりとして扱えるようにするものです。違う製品を数種類詰め合わせたギフトセットのようなものをイメージするとわかりやすいでしょう(図1(b))。

図1●配列と構造体のイメージの違い
図1●配列と構造体のイメージの違い

 もう少しプログラムっぽく考えてみましょうか。例えば,スポーツによる健康なダイエットを目指す「やせよう会」という会の会員情報を管理するプログラムを作成したいとします。会員のデータとして,会員NO,ニックネーム,性別,身長,体重,連絡先電話番号を記憶させたいときに,組み込み型だけを使って表現すると,リスト1のようにいくつも変数を宣言することになるでしょう。変数no,変数nickname,変数weightの間にどんな関係があるのかは,ソースコードを見ただけではわかりません。同一人物の情報であることを示す手掛かりがないからです。


int no;
char nickname;
char sdist;
int age;
float height;
float weight;
char telno[14];
リスト1●組み込み型だけを使った場合

 しかし,人物にしてもモノであっても,それを表現する場合には複数の関連する情報(属性)が必要になるのは当然です。車を表すなら,車種,排気量,何年式かなどの複数の情報が必要になりますよね。そのようにモノを表現するための,関連する情報を一つの固まりとして扱えるようにするC言語の仕組みが構造体なのです。

構造体型の宣言の仕方

 構造体を使うと,リスト1のようにバラバラな情報を,ある人物を表す情報としてグループ化できます。具体的に見てみましょう。リスト2の(1)が,「構造体型(structure type)」の宣言のサンプル・コードです。structキーワードを使って,次のように構造体型を宣言しています。

struct 構造体型名(構造体タグ名) {
 型名 識別子;
 型名 識別子;
 …
}

リスト2●構造体を使ったサンプル・プログラム
リスト2●構造体を使ったサンプル・プログラム
[画像のクリックで拡大表示]

 構造体型の宣言とは,複数の既存の型を組み合わせて,新しい「型」を作ることです。この時点では,memberというヒナ型(テンプレート)が作成されただけで,実際にメモリー上に存在する構造体型変数を宣言するには,

struct member mem1;

とします。これでstruct member型の変数mem1が使用可能になります。リスト2の(2)のように中カッコでくくって変数の宣言と同時に初期化することもできます。構造体の中の項目(この例だとnoやnicknameなど)をメンバーと呼び,メンバーを参照するにはリスト2の(3)のようにドット演算子を使います。つまり,mem1.nicknameとすれば,構造体型変数mem1のnicknameメンバーを参照するわけです。実際にリスト2を実行すると図2のようになります。初期値として与えた値を表示した後,体重(weight)だけを変更して,構造体のメンバーを再表示していますね。

図2●リスト2を実行したところ
図2●リスト2を実行したところ

typedefキーワードで
構造体型に名前を付けられる

 新しい型を作ったといっても,「int no;」と変数を宣言するのと違い,「struct member mem1;」という宣言は説明っぽくて,いかにも後から付け足した感じがします。

 そこでC言語では,typedefというキーワードを使ってデータ型名をプログラマがわかりやすい名前に定義し直すことができます。この機能を使って構造体型にシンプルな名前を付けてみましょう。

 リスト3はtypedefを使って,struct member型にmem_tという名前を付けています。中カッコを閉じた後の「mem_t」の部分です。これで,リスト2の(2)の部分を「mem_t mem1=~(以下同じ)」とすれば,構造体型変数を宣言できるようになります。


typedef struct member{
 int no;
 char nickname[20];
 char sdist;
 int age;
 float height;
 float weight;
 char telno[14];
} mem_t;
リスト3●リスト2の構造体の定義をtypedefを使って変更したコード