構造体

構造体


サイト全体の目次

稿


稿

構造体

このセクションのソース

/*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*/ }

list-6.1.1-03

構造体とは、関連性のあるデータをひとまとめにして扱うためのものです。データを、グループにまとめてしまおうというのが構造体というわけです。そこでまず、どのようなデータを持つ集まりであるかということを定義します。それが

struct score{
        char name[16];
        int math;
        int english;
        int kei;
};

という部分です。ここで struct と書くと次に来るものが構造体の宣言であることを示します。その後にくる score は構造体タグと呼ばれ、その構造体(つまりデータの集まり、グループ)につけられる名前で、自由に付けることができます。そして、その構造体にどのようなデータが含まれているかを次の「 { } 」内に書きます。また、それらのデータはメンバと呼ばれます。そして、関数やブロックと違って「 { } 」の後ろに「;」を付けるのを忘れないで下さい。

構造体のイメージを示しておきます。

struct 構造体タグ名{
    メンバ1;
    メンバ2;
      :
      :
};

以下グループです グループ名は「果物」です{
    りんご;
    バナナ;
      :

      :
};

例の構造体では、score (= 得点)という名前の構造体(グループ)の中に、名前を格納するための char 型配列 name、英語の点を格納するための int 型変数 english、数学の点を格納するための int 型変数 math を含めて 1つのデータの集まりとしています。なお、構造体は違うタグ名でいくつでも作ることができます。

list-6.1.1-12

その構造体がどのようなデータの集まりであるかは、上に示したとおりです。しかし、実際にその領域がメモリ上に取られた分けではありません。これは「どのようなものかを定義した」にすぎないからです。たとえば「int は整数を入れる型」という具合に、「truct score は name と math と english と kei を入れる型」という感じで型(枠組み)を作ったに過ぎないわけです。そこで、これまで変数を宣言してきたのと同様に変数を宣言してやります。

struct score a1;    /* struct 構造体タグ名 変数名 */
struct score a2;
score a1; ではダメ
「struct タグ名」 で int のような型と考えればよい。

また、次のように書いてもかまいません。

struct score a1, a2;

普通の変数の宣言と同じ要領ですね。これで変数 a1、a2 はそれぞれ構造体 score なる型として宣言されました。そして、変数 a1、a2 はその支配下に score で宣言されたメンバを持っているのです(当然a1 のメンバと a2 のメンバはそれぞれ独立しています)。

6.1.1-16

構造体の実際の使い方です。いろいろなメンバを持つ構造体変数は作りましたが、その中に収められているメンバに情報(値)を持たせられなければ意味がありません。これらのメンバを参照したり操作したりするにはどうしたらよいのでしょうか。

a1.math    /* 変数名.メンバ名 */

これで a1 変数のメンバ math を操作することができます。scanf ではアドレスを引数で渡すので &(a1.math) としてアドレスを渡してやるのですが、演算順位によりカッコは省略することができます。(メンバ name は配列ですからもともと &name[0] を意味します。)
&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*/ }

(untitled)

使い方は見てのとおりです。この例のように複数人のデータを管理したい場合などには有効な方法でしょう。

また、すでに別の構造体が宣言されている場合、ある構造体のメンバにそれを含めることができます。たとえば、担任と学級名、その学級の生徒 30 名のデータ(上で定義した構造体 score)をメンバにもつ kurasu (クラス)という構造体を定義してみましょう。(注:英単語の class は C++ でキーワードになっているので、混同を避けるため使わない。)

struct kurasu{
    char teacher[16];    /* 担任の名前 */
    char kurasu[16];    /* クラス名 */
    struct score student[30];    /* 生徒 30 人のデータ */
};

このとき、構造体変数として「struct kurasu b1」が宣言されたとしましょう。この中に入っている構造体変数 student[i] のメンバには次のようにしてアクセスします。
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*/ }

(untitled)

この list は list-6.1.1 とほとんど変わりません。違う点は、構造体の直後に構造体変数 a1 a2 を宣言していることです。これも正しい方法ですが、この場合は当然グローバル変数になります。


読み込み中・・・
10秒待っても表示が変わらない場合、次の理由が考えられます。
・Javascript が無効になっています。
・検索エンジンのキャッシュを見ています。
サイトホームへ / 上位ページへ / ページトップへ / PAROFトレンドショッピングへ
Copyright (C) 2010 totobon all right reserved.