[前へ]   [目次へ]   [次へ]

構造体型オブジェクトの使い方(1)(C/C++)


今回は構造体型のオブジェクトを利用する方法についてです。

構造体型のオブジェクトも通常の変数と同様、作成した時点では中身は不定の状態になっています。
また、複数のオブジェクトや変数をまとめたものであるため、使う時には個々の名前を指定する必要があります。

そこで、 . 演算子(構造体メンバ参照、優先16、結合→)と
-> 演算子(構造体ポインタ参照、優先16、結合→)が登場します。

これらは構造体型やクラス型に含まれる中身を指定するために用います。
. 演算子は左辺に構造体型またはクラス型のオブジェクトか参照を、
-> 演算子は左辺に構造体型またはクラス型のオブジェクトへのポインタ(絶対ID)を取り、
右辺に「中身の名前」を取ります。

この「中身の名前」は構造体やクラスを定義する時に
中身のオブジェクトや変数に付けた名前で、ソース上で直接、かつ固定的に指定します。
これらの演算子の右辺に文字列変数などは使えません。

例:構造体の使い方
<  1>
<  2>
<  3>
<  4>
<  5>
<  6>
<  7>
<  8>
<  9>
< 10>
< 11>
< 12>
< 13>
< 14>
< 15>
< 16>
< 17>
< 18>
< 19>
< 20>
< 21>
< 22>
< 23>
#include <stdio.h>
#include <string.h>

struct ABC{
   
int a;
   
char b[10];
   
int c;
};

int main(void){
   
struct ABC d;//構造体型オブジェクト d を定義
   
   
d.a=10;//(1)
   
strcpy(d.b,"あいう");//(2)
   
d.c=20;//(3)
   
   
printf("d.a=%d\n",d.a);
   printf(
"d.b=%s\n",d.b);
   printf(
"d.c=%d\n",d.c);
   
   getchar();
//終了待ち
   
return 0;
実行結果:
d.a=10
d.b=あいう
d.c=20


それでは実行を追跡してみます。

10行、 main 関数から始まり、(1)13行目です。

この時点までを実行した時の状況の一例
実体ID(絶対)実体の型保持値所属
0x0012FF6CABC[構造体]main(d,line 11)
0x0012FF6Cint不定(未初期化)main(d.a,line 11)
0x0012FF70char[10]不定(未初期化)main(d.b,line 11)
0x0012FF7Cint不定(未初期化)main(d.c,line 11)
mainブロック 確保位置ID:0x0012FF6C

A B C D E
d . a = 10


通し記号種別
AABC[構造体]オブジェクト(d)
B演算子(.)(特殊、その他、優先16、結合→)
Ca識別名
D演算子(=)(2項、算術、優先2、結合←)
Eint10定数
優先順位より演算子B(構造体メンバ選択、オブジェクトAから識別名C)から処理されます。
ここで識別名C(a)が左辺である構造体ABCの中に定義されていない場合、コンパイルエラーになります。

この演算により、オブジェクトA(d)から識別名C(a)の名前の変数が取り出されます。

A      B C
vtemp1 = 10


通し記号種別
Aint&不定(未初期化)一時変数(参照先:d.a)
B演算子(=)(2項、算術、優先2、結合←)
Cint10定数
これは今まで通り普通に代入されます。

この時点までを実行した時の状況の一例
実体ID(絶対)実体の型保持値所属
0x0012FF6CABC[構造体]main(d,line 11)
0x0012FF6Cint10main(d.a,line 11)
0x0012FF70char[10]不定(未初期化)main(d.b,line 11)
0x0012FF7Cint不定(未初期化)main(d.c,line 11)
mainブロック 確保位置ID:0x0012FF6C

続いて、(2)14行です。

A      B C D E   F        B'
strcpy ( d . b , "あいう" )


通し記号種別
Achar*(*)(char*,const char*)0x004014C0関数(strcpy)
B演算子( () )(その他、優先16、結合→)
CABC[構造体]オブジェクト(d)
D演算子(.)(特殊、その他、優先16、結合→)
Eb識別名
Fconst char[7]"あいう"文字列定数
B'演算子Bの終点
演算子Bの関数呼び出しを行うために、式C〜Eを先に解決します。
ここは先ほどと同じ要領で、識別名E(b)の名前の変数が取り出されます。

A      B C        D        B'
strcpy ( vtemp1 , "あいう" )


通し記号種別
Achar*(*)(char*,const char*)0x004014C0関数(strcpy)
B演算子( () )(その他、優先16、結合→)
Cchar(&)[10]不定(未初期化)一時変数(参照先:d.b)
Dconst char[7]"あいう"文字列定数
B'演算子Bの終点
演算子Bにより strcpy 関数が呼び出され、配列Cに配列Dの文字列がコピーされます。

この時点までを実行した時の状況の一例
実体ID(絶対)実体の型保持値所属
0x0012FF6CABC[構造体]main(d,line 11)
0x0012FF6Cint10main(d.a,line 11)
0x0012FF70char[10]"あいう"main(d.b,line 11)
0x0012FF7Cint不定(未初期化)main(d.c,line 11)
mainブロック 確保位置ID:0x0012FF6C

続いて、(3)15行です。
13行と同じ手順で進みます。

A B C D E
d . c = 20


通し記号種別
AABC[構造体]オブジェクト(d)
B演算子(.)(特殊、その他、優先16、結合→)
Cc識別名
D演算子(=)(2項、算術、優先2、結合←)
Eint20定数
優先順位より演算子B(構造体メンバ選択、オブジェクトAから識別名C)から処理されます。

この演算により、オブジェクトA(d)から識別名C(c)の名前の変数が取り出されます。

A      B C
vtemp1 = 20


通し記号種別
Aint&不定(未初期化)一時変数(参照先:d.c)
B演算子(=)(2項、算術、優先2、結合←)
Cint20定数
これも今まで通り普通に代入されます。

この時点までを実行した時の状況の一例
実体ID(絶対)実体の型保持値所属
0x0012FF6CABC[構造体]main(d,line 11)
0x0012FF6Cint10main(d.a,line 11)
0x0012FF70char[10]"あいう"main(d.b,line 11)
0x0012FF7Cint20main(d.c,line 11)
mainブロック 確保位置ID:0x0012FF6C

この後の printf 関数による表示でも、同様の手順で構造体内の変数が表示されます。


さて、今回のように1個しか構造体型のオブジェクトを作成しない場合、あまり意味が見出せません。
そもそも構造体は同じデータの集合を表現するためのものなので、複数あって初めて役に立つものです。
次回は、構造体の役に立つ使い方の基本についての予定です。

[前へ]   [目次へ]   [次へ]

プログラミング講座 総合目次

最終更新 2012/04/06