/*01*/ #include <stdio.h>
/*02*/
/*03*/ struct score{
/*04*/ char name[16];
/*05*/ int math;
/*06*/ int english;
/*07*/ int kei;
/*08*/ };
/*09*/
/*10*/ main()
/*11*/ {
/*12*/ struct score a1;
/*13*/ struct score a2;
/*14*/
/*15*/ printf("名前 数学の点 英語の点 を入力してください。\n");
/*16*/ scanf("%s%d%d", a1.name, &a1.math, &a1.english);
/*17*/ scanf("%s%d%d", a2.name, &a2.math, &a2.english);
/*18*/
/*19*/ a1.kei = a1.math + a1.english;
/*20*/ a2.kei = a2.math + a2.english;
/*21*/
/*22*/ printf("%s の合計点は %d です。\n", a1.name, a1.kei);
/*23*/ printf("%s の合計点は %d です。\n", a2.name, a2.kei);
/*24*/
/*25*/ return 0;
/*26*/ }
構造体とは、関連性のあるデータをひとまとめにして扱うためのものです。データを、グループにまとめてしまおうというのが構造体というわけです。そこでまず、どのようなデータを持つ集まりであるかということを定義します。それが
struct score{
char name[16];
int math;
int english;
int kei;
};
構造体のイメージを示しておきます。
struct 構造体タグ名{
メンバ1;
メンバ2;
:
:
};
以下グループです グループ名は「果物」です{
りんご;
バナナ;
:
:
};
例の構造体では、score (= 得点)という名前の構造体(グループ)の中に、名前を格納するための char 型配列 name、英語の点を格納するための int 型変数 english、数学の点を格納するための int 型変数 math を含めて 1つのデータの集まりとしています。なお、構造体は違うタグ名でいくつでも作ることができます。
その構造体がどのようなデータの集まりであるかは、上に示したとおりです。しかし、実際にその領域がメモリ上に取られた分けではありません。これは「どのようなものかを定義した」にすぎないからです。たとえば「int は整数を入れる型」という具合に、「truct score は name と math と english と kei を入れる型」という感じで型(枠組み)を作ったに過ぎないわけです。そこで、これまで変数を宣言してきたのと同様に変数を宣言してやります。
struct score a1; /* struct 構造体タグ名 変数名 */ struct score a2; score a1; ではダメ 「struct タグ名」 で int のような型と考えればよい。
また、次のように書いてもかまいません。
struct score a1, a2;
構造体の実際の使い方です。いろいろなメンバを持つ構造体変数は作りましたが、その中に収められているメンバに情報(値)を持たせられなければ意味がありません。これらのメンバを参照したり操作したりするにはどうしたらよいのでしょうか。
a1.math /* 変数名.メンバ名 */
&a1.math と &(a1.math) は同じ
一見ややこしそうに思えますが、単に int 型の「a1.math」という変数を扱っているのだと思えばよいでしょう。
構造体も配列にすることができます。
/*01*/ #include <stdio.h>
/*02*/
/*03*/ struct score{
/*04*/ char name[16];
/*05*/ int math;
/*06*/ int english;
/*07*/ int kei;
/*08*/ };
/*09*/
/*10*/ main()
/*11*/ {
/*12*/ struct score a[5];
/*13*/ int i;
/*14*/
/*15*/ printf("名前 英語の点 数学の点 を入力してください。\n");
/*16*/ for(i = 0; i < 5; i++){
/*17*/ scanf("%s%d%d", a[i].name, &a[i].math, &a[i].english);
/*18*/ a[i].kei = a[i].math + a[i].english;
/*19*/ }
/*20*/ putchar('\n');
/*21*/
/*22*/ for(i = 0; i < 5; i++)
/*23*/ printf("%s の合計点は %d です。\n", a[i].name, a[i].kei);
/*24*/
/*25*/ return 0;
/*26*/ }
使い方は見てのとおりです。この例のように複数人のデータを管理したい場合などには有効な方法でしょう。
また、すでに別の構造体が宣言されている場合、ある構造体のメンバにそれを含めることができます。たとえば、担任と学級名、その学級の生徒 30 名のデータ(上で定義した構造体 score)をメンバにもつ kurasu (クラス)という構造体を定義してみましょう。(注:英単語の class は C++ でキーワードになっているので、混同を避けるため使わない。)
struct kurasu{
char teacher[16]; /* 担任の名前 */
char kurasu[16]; /* クラス名 */
struct score student[30]; /* 生徒 30 人のデータ */
};
b1.student[0].math = 80;
/*01*/ #include <stdio.h>
/*02*/
/*03*/ struct score{
/*04*/ char name[16];
/*05*/ int math;
/*06*/ int english;
/*07*/ int kei;
/*08*/ } a1, a2;
/*09*/
/*10*/ main()
/*11*/ {
/*12*/ printf("名前 数学の点 英語の点 を入力してください。\n");
/*13*/ scanf("%s%d%d", a1.name, &a1.math, &a1.english);
/*14*/ scanf("%s%d%d", a2.name, &a2.math, &a2.english);
/*15*/
/*16*/ a1.kei = a1.math + a1.english;
/*17*/ a2.kei = a2.math + a2.english;
/*18*/
/*19*/ printf("%s の合計点は %d です。\n", a1.name, a1.kei);
/*20*/ printf("%s の合計点は %d です。\n", a2.name, a2.kei);
/*21*/
/*22*/ return 0;
/*23*/ }
この list は list-6.1.1 とほとんど変わりません。違う点は、構造体の直後に構造体変数 a1 a2 を宣言していることです。これも正しい方法ですが、この場合は当然グローバル変数になります。