氏名と点数がデータとして与えられたとき,各人の名前と平均点を表示する方法を考えよという問題であった。
出席番号 | 名前 | 語学 | 力学 | 平均点 |
1 | 佐藤 | 65 | 71 | ? |
2 | 鈴木 | 84 | 83 | ? |
3 | 高橋 | 74 | 74 | ? |
4 | 田中 | 90 | 90 | ? |
5 | 渡辺 | 87 | 78 | ? |
6 | 伊藤 | 93 | 95 | ? |
これまで習った配列では,同じ型のデータをまとめて扱えたが,この問題のように文字列型と整数型があると,一つの文字列では扱えない。
今日の演習で学ぶ「構造体」は,このように 異なる型のデータをまとめて一つの変数として扱うための手法である。 構造体は,新しい変数の「型」を自分で作り出す役割をする。
(1)既存の変数を組み合わせて,int や float にあたる新しい型を定義する。
(2)定義した型を利用する変数を定義して利用する。
という,二つの段階が必要になる。
構造体を利用するには,まず既存の変数を組み合わせて,新しい「型」の構造体を定義する。
#include <stdio.h>
struct seiseki {
char simei[25];
int ten_1;
int ten_2;
};
void main()
{
....
}
構造体の定義部分(赤色の箇所)記述は,関数の内側にも外側にも記述することができる。
関数の中で宣言すれば,その関数内のみで有効になる。(ローカル変数と同じ)
以降,何度も登場する struct
というキーワードは,「構造体」という意味である。
構造体の中身の変数(ここではsimei
やten_1
など)の要素一つ一つのことを,構造体のメンバと呼ぶ。
これで,新しい変数の「型」であるseiseki
型が定義できた。
(1)まず,定義した構造体型の変数を宣言する。
struct seiseki list2012; /* 新しく定義した seiseki 型の変数,list2012 */
上で定義したseiseki
型が構造体であることを示すために,struct
キーワードを必ず記する。
これで,成績データを格納する変数 list2012
が,使えるようになる。
(2)次に,構造体のメンバに値を代入する方法と,値を参照する方法をマスターしよう。
(2-a)代入する方法。
基本的には,構造体変数名.メンバ変数名 のように,構造体変数の名前と,メンバの変数の名前を .(ピリオド,ドット)で結ぶ。
変数の名前がlist2012
で,メンバ名がsimei, ten_1, ...
なので,
strcpy(list2012.simei, "メイジ"); /* 文字列の代入.下の注を参照! */
list2012.ten_1 = 90;
list2012.ten_2 = 80;
また,変数の定義と同時に初期化するときは,配列の場合と同様に
struct seiseki list2012 = {"メイジ", 90, 80};
と,書くこともできる。
(2-b)次に,構造体変数の各メンバの参照。
printf("氏名 = %s 点数1 = %d ¥n", list2012.simei, list2012.ten_1);
とすることで,値を取り出すことができる.
文字列は,文字型の「配列」なので,
char name[25];
name = "meiji"
これは,エラーになる。では,どうやって文字列に代入するかというと,
char name[20];
name[0] = 'm';
name[1] = 'e';
....
が,正しい手順であるが,文字数が増えると大変である。そこで,C言語では文字列の代入をする関数が用意されている。
#include <stdio.h>
#include <string.h> /* 文字列操作関数用のヘッダファイル */
void main()
{
char name[20];
strcpy(name, "meiji"); /* string copy関数. */
}
成績リストの例では,構造体1つに1人分の名前・成績データなどを格納できた。これを用いて,全員分の名前や点数を一つの変数に保存するために,構造体を配列にすればよさそうである。 構造体変数も,通常の変数同様,配列を宣言することができる。
struct seiseki list2012[100];
この例では,struct seiseki
型の変数を100人分,配列名を list2012
にする,という意味である。
構造体の配列の各要素の,メンバへの代入は,例えば配列の先頭の構造体へは
strcpy(list2012[0].simei, "メイジ"); /* 文字列の代入. */
list2012[0].ten_1 = 90;
list2012[0].ten_2 = 80;
とすることができる。配列の添え字用 [ ] と,構造体用のピリオド「.」の順序に注意!
普通の配列同様,添え字を変化させることにより,構造体の配列すべてのメンバを操作することができる。
配列の宣言と同時に,初期化する場合に限り,
struct seiseki list2012[] = {
{"イクタ",10,20},
{"スルガダイ",5,10},
};
という記述が可能である。
関数に変数を渡すには,値参照とアドレス参照とがあるが,まずは値参照を使ってみる。
#include <stdio.h> struct seiseki { char simei[25]; int ten_1; int ten_2; }; /* 構造体のメンバをすべて表示する関数 */ void disp_all(struct seiseki list) { printf("氏名=%s¥n", list.simei); printf("点数1=%d¥n", list.ten_1); printf("点数2=%d¥n", list.ten_2); } void main() { struct seiseki list2012 = {"メイジ", 90, 80}; disp_all(list2012); /* 関数に構造体を渡す */ }
構造体であることを示すstruct
を記述すること以外は,通常の値参照による関数呼び出しと同じです。
課題1 次に示す生徒の情報を構造体として定義・作成し,各内容を画面に表示するプログラムを作成しなさい。
番号 | 氏名 | 点数 | 成績 |
1 | 小林 | 82 | A |
課題2 次に示す複数の生徒の情報を構造体の配列として作成し,順番に画面に表示するプログラムを作成しなさい。
番号 | 氏名 | 点数 | 成績 |
1 | 石山 | 82 | A |
2 | 松村 | 48 | F |
3 | 中島 | 98 | S |
課題3 前回の課題3を構造体を用いて書き直しなさい。
課題4 前回の課題4を構造体を用いて書き直しなさい。