5.13 構造つきの型
5.13.4 レコード型
レコード型とは一つの型の中に必ずしも同一の型ではない決まった数の成分を持つような型のことであ る. それぞれの成分をフィールド(field)と呼ぶ.
Id: P5.tex,v 1.3 2001-03-11 17:33:43+09 naito Exp
レコード型 ::= record フィールド並び end
フィールド並び ::={ 固定部 {; 可変部 }| 可変部 }{ ;} 固定部 ::= レコード要素 {; レコード要素 }
レコード要素 ::= 名称並び : 型表記
可変部 ::= case 可変要素選択子 of 可変要素 {; 可変要素 } 可変要素選択子 ::={ タグフィールド :} タグ型
タグフィールド ::= 名称
可変要素 ::= 選択定数並び : ( フィールド並び ) タグ型 ::= 順序型名
選択定数並び ::= 選択定数 {, 選択定数 } 選択定数 ::= 定数
固定部も可変部も持たないフィールド並びは, 成分を持たず, 値は空値ただ1種類を持つ. このような フィールド並びは空であるという.
Example 5.13.5 例えば, 固定部のみからなるレコード型は次のようなものである.
record
year : 0..3000 ; month : 1..12 ; day : 1..31 end
これは, フィールドとして,year, month, dayを持ち, それぞれがinteger型の部分範囲型として定義さ れている.
m個の成分を持つ空でないフィールド並びの値は,次のm組である. ただし,Vi はそのフィールド並び のi 番めの成分である.
(V1,· · · , Vm)
可変部を直接に含むフィールド並びは,その可変部に対応した一つの成分を持つ. この成分の値と構造は, その可変部によって定義される.
Example 5.13.6 可変部を含むレコード型は次のようなものである.
type
month_type = 1..12 ; days_type = record
year : 0..3000 ;
case days : month_type of
1,3,5,7,8,10,12 : (days_1 : 1..31) ; 4,6,9,11 : (days_2 : 1..30) ;
2 : (days_3 : 1..28) end
可変部の値は,可変部の選択子の値 kと可変部の有効な可変要素のフィールド並びの値 Xk によって決ま る(k, Xk)である.
Example 5.13.7 固定部と可変部を持つレコード型の例は次のようなものである.
Id: P5.tex,v 1.3 2001-03-11 17:33:43+09 naito Exp
record
x, y : real ; area : real ; case shape of
rectangle : (side1, side2 : real ; skew : angle) ; circle : (diamiter : real)
end
この例では, 「可変要素選択子」で「タグフィールド」を利用していない. この時,xをこの型の変数と すると, x.side1 を利用すると,それは 可変部が rectangleであるとみなされる. 可変部が rectangle の時,diamiterは有効ではない.
レコード型の変数の各フィールドの値は,そのフィールド名を変数名のあとに. を使ってつなぐことによ り得ることができる.
フィールド表記 ::= レコード変数 . フィールド指定部 | フィールド表記名 レコード変数 ::= 変数
フィールド指定部 ::= フィールド名 フィールド名 ::= 名称
ここで,可変部の選択子が不定であれば, 可変部のどの可変要素も有効ではない. また, フィールド名は 変数名とは別の名前空間に属するので, 次のような名前の与え方は間違いではない.
a : record a : real ; b : real ; end ;
b : integer ;
Example 5.13.8 この例は, 固定部と可変部を持つレコード型を定義し,そのフィールドに値を代入して いる.
Id: P5.tex,v 1.3 2001-03-11 17:33:43+09 naito Exp
program record_test ; type
b_year = 1..4 ; m_year = (m1,m2) ; d_year = (d1,d2,d3) ;
b_or_m_or_d = (bachler,master,doctor) ; person = record
name : record
first, family : string ; end ;
id : string ;
case kind : b_or_m_or_d of
bachler : (gakunen_b : b_year) ; master : (gakunen_m : m_year ;
boss_m : string) ;
doctor : (gakunen_d : d_year ; boss_d : string)
end ; var
p : array [1..100] of person ; begin
p[1].name.first := ’Masashi’ ; p[1].name.family := ’Kubo’ ; p[1].id := ’9400001’ ; p[1].kind := doctor ; p[1].gakunen_d := d3 ; p[1].boss_d := ’Prof. Ihara’
end.
また,可変部の指定で,次のようなものは誤りである.
record
case digit : integer of
1 : (S1 : array[1..1] of char) ; 10 : (S2 : array[1..2] of char) ; 100 : (S3 : array[1..3] of char) end
これは,タグフィールドがとびとびの値しかとっていない.
5.13.4.1 レコード型の変数の内部表現
レコード型の変数はメモリ内で,可変部がどのような状態であっても,それを格納するために十分なメモ リ領域が使用される. しかしながら, メモリ内でフィールド並びの順にならんでいるとは限らない.
5.13.4.2 with 文
with文は次のような構文を持つ.
with文 ::= with レコード変数 {, レコード変数 }do 文
これは,指定したレコード変数に対して, そのフィールド名を指定するだけで,各レコード変数のフィー ルドをアクセスするための構文である.
Example 5.13.9 次の代入はExample 5.13.8の例の代入と等価である.
Id: P5.tex,v 1.3 2001-03-11 17:33:43+09 naito Exp
with p[1],name do begin
first := ’Masashi’ ; family := ’Kubo’ ; id := ’9400001’ ; kind := doctor ; gakunen_d := d3 ; boss_d := ’Prof. Ihara’
end
with文中において,レコード変数を変更してはならない.