◆◆◆◆アマゾンで購入する◆◆◆

11.構造体と共用体 
           内    容
(1)構造体・・・事始め
(2)構造体の宣言と参照方法
(3)構造体をポインタで参照
(4)共用体
(5)演習


(1)構造体・・・事始め

たとえば,住所録を作るプログラムを作ろうとする場合,
データは,氏名や住所です。

プログラミング言語を離れて考えると,
次のように整理できます。

   address data
name: 諸星和己
age: 20
mail no : 189-0002
address 東村山市久米川町3-59-27
tel no : 042-394-2798


これらのデータを配列で表現すると

  char name [100][19], age[100],
  mail_no[100][9], address[100][31],
  tel_no[100][15]

のように表現して,
もちろんプログラムも書けますが,
せっかく概念的な意味で整理したのに,
これらの間の意味的なつながりが
無視されてしまっています。

また,最初の添え字で
個人を識別しているということは,
プログラマだけが分かっており,
プログラム上は明確ではありません。

Cでは,上記で整理した概念と同一の形態で
データ構造を表現できます。

これを,「構造体」といいます。

(2)構造体の宣言と参照方法

構造体を宣言するには,
たとえば,次のように宣言します。

[宣言1]
   typedef struct
{
  char name [19];
  int age;
  char mail_no[9];
  char address[31];
  char tel_no[15];
} address_data;
address_data data[100];
address_data a, b

または,構造体とする変数/配列が
ひとつだけのとき,

[宣言2]
   struct address_data
{
  char name [19];
  int age;
  char mail_no[9];
  char address[31];
  char tel_no[15];
} data[100];

とします。

ただし,宣言1の方が柔軟性がありますので,
宣言1の書き方をお勧めします。

これらのデータを参照するには,
以下のように記述します。

[参照方法]
   a.age=20;
data[15].age=22;
data[17].tel_no="03-3397-5530";

(3)構造体をポインタで参照

構造体をポインタで参照するには,
構造体のポインタであることを宣言します。

たとえば,住所データのポインタであることを
宣言するには,

  address_data *pdata;

と宣言します。


配列dataの先頭アドレスを設定するには,

   pdata = data;

とします。

以下は,3番目のデータのageに
整数値22を設定する代入文です。

  (*(data+3)).age = 22;

ただし,これでは括弧の数が多いので,
次のような省略形で記述することができます。

   (data+3)->age = 22;




次のようなプログラムを作って,
表示を確認してみよう。
[確認のための例題]
   #include "stdafx.h"
/* 構造体のタイプ宣言 */
typedef struct
{
 char name [19];
 int age;
 char mail_no[9];
 char address[31];
 char tel_no[15];
} address_data;

/* 関数のプロトタイプ宣言 */
void print_array_data( int i);
void print_pointer_data(address_data *pdat);

/* 構造体の配列宣言 */
static address_data data[3]
={ {"多 摩 淳 子", 22,
     "189-0001",
     "東京都東村山市秋津町5-23-4",
     "042-394-1125" },
  {"中 野 圭 子", 21,
    "164-8012",
    "東京都中野区本町5-83-12",
    "03-3382-1635" },
  {"菊 池 涼 子", 18,
    "153-1023",
    "東京都中央区築地2-6-33",
    "03-3544-5678" } };

int main(int argc, char* argv[])
{
 /*住所データのポインタであることを宣言*/
 address_data *pdata;

 /*配列先頭の次のアドレスをpdataとする*/
 pdata = data+1;
 print_array_data(2);
 print_pointer_data(pdata);
}
void print_array_data(int i)
{
 printf("\n");
 printf("\n氏名 : %-19s ( %3d )", data[i].name , data[i].age );
 printf("\n住所 : 〒%-9s %-41s" , data[i].mail_no,
                       data[i].address);

 printf("\n電話 : %-15s" , data[i].tel_no);
}

void print_pointer_data(address_data *pdat)
{
  printf("\n");
  printf("\n氏名 : %-19s ( %3d )", pdat->name , pdat->age );
  printf("\n住所 : 〒%-9s %-41s" , pdat->mail_no,
                        pdat->address);

  printf("\n電話 : %-15s", pdat->tel_no);
}

(4)共用体

変数の型にはサイズがありました。
大きなサイズの変数を小さなサイズのデータに
小分けして使う方法を共用体といいます。

まず,構造体に似た宣言を行います。

  union eqdt
  {
    char ch[4] ;
    short sint[2];
    long lint;
  } dt;

これは,dtという変数がch, sint,lintから
構成されるという意味ではありません。

dtという入れ物を文字型chとして4個入れ,
単長整数sintとして2個入れて
用いるという意味ですので,
誤解がないようにしてください。


参照や設定のときは,

   dt.lint = 0;
   x = dt.ch[2];

のように書きます。

色々な変数で, 同じような共用を行う場合,

 union eqdt
 {
   char ch[4] ;
   short sint[2];
   long lint;
 };

と仮宣言しておき,

  union eqdt dt1;
  union eqdt dt2;

のように宣言します。

(5)演 習

次の宣言があり,

 union eqdt
 {
   char ch[4] ;
   short sint[2];
   long lint;
 } dt;

以下のような代入文が実行されたとき,

   dt.ch[0] = 0x01;
   dt.ch[1] = 0x02;
   dt.ch[2] = 0x03;
   dt.ch[3] = 0x04;

dt.lintの内容を

   %x

の形式で表示するプログラムを
作って下さい。



 1.C言語の誕生

 2.C言語の仲間たち

 3.新しい言語をすばやく覚えるには

 4.Cでプログラミング

 5.データの入れ物 変数の考え方

 6.注釈・定数

 7.プログラムの実行順序

 8.配列

 9.C言語特有の代入文・制御構造

10.関数の話

11.構造体と共用体

12.ビット演算

13.プログラムの場所をポインタで

14.ファイルの入出力

15.色々な便利な方法