構造体
名前と点数がバラバラだった問題
前章まで、成績管理CLI は学生の名前を char names[3][32]、点数を int scores[3] という 別々の配列 で持っていました。「names[1] の人の点数は scores[1]」という対応は、私たちが頭の中で覚えているだけです。
この持ち方には弱点があります。名前だけを並べ替えたら点数が付いてきません。学生を 1 人削除するときも、両方の配列を同じように操作しないと対応がずれます。ずれてもコンパイルは通るので、間違った成績表が出るまで気づけません。
本当に欲しいのは「名前と点数がくっついた 1 個のかたまり」です。C ではこれを 構造体 といいます。
新しい型を自分で作る
構造体は struct で定義します。
struct Student {
char name[32];
int score;
};これは「Student という設計図を作った」という宣言で、まだ変数は 1 つもできていません。int や double と同じ仲間の 型 が 1 種類増えた、と考えてください。中に並べた name と score を メンバ と呼びます。
注意点が 1 つあります。閉じカッコのうしろの セミコロンが必須 です。関数の定義にはセミコロンが要らないので、ここは混同しやすく、忘れると次の行から見当違いのエラーが並びます。
定義は main より前、#include の下あたりに書きます。main の中で使うより先に、コンパイラが設計図を知っている必要があるからです。
変数を作って初期値を入れる
設計図ができたら、そこから変数を作れます。型の名前は Student ではなく struct Student で、2 語セットです。
struct Student first = {"田中", 82};波カッコの中身は、構造体を定義したときの 並び順 に対応します。1 つ目の "田中" が name、2 つ目の 82 が score に入ります。順番を入れ替えると型が合わずエラーになります。
こうして作った変数は、名前と点数がひとかたまりです。first を関数に渡せば名前も点数も一緒に届きますし、2 人目が欲しければ struct Student second; ともう 1 個作るだけで、配列を 2 本増やす必要はありません。
メンバの中身を取り出すには first.score のようにドットでつなぎます。次回きちんと扱うので、まずは定義して表示するところまでやってみましょう。
要件
- struct Student を name(char 32個の配列) と score(int) の2つのメンバで定義する
- 田中 82点 と 佐藤 90点 の変数を初期値付きで作る
- 「田中 82点」の形で2行表示する
- 最後に「2人の合計は172点です」の形で合計を表示する
入出力例
main("") → "田中 82点
佐藤 90点
2人の合計は172点です"