3.12 構造つきの型
3.12.4 レコード 型
レコード 型とは一つの型の中に必ずしも同一の型ではない決まった数の成分を持つような型のことであ る. それぞれの成分をフィールド (field)と呼ぶ.
レコード 型 ::= record フィールド 並び end
フィールド 並び ::={ 固定部 {; 可変部 }| 可変部 }{ ;} 固定部 ::= レコード 要素 {; レコード 要素 }
レコード 要素 ::= 名称並び : 型表記
可変部 ::= case 可変要素選択子 of 可変要素 {; 可変要素 } 可変要素選択子 ::={ タグフィールド :} タグ型
タグフィールド ::= 名称
可変要素 ::= 選択定数並び : ( フィールド 並び ) タグ型 ::= 順序型名
選択定数並び ::= 選択定数 {, 選択定数 } 選択定数 ::= 定数
固定部も可変部も持たないフィールド 並びは, 成分を持たず, 値は空値ただ1種類を持つ. このような フィールド 並びは空であるという.
Example 3.12.5 例えば,固定部のみからなるレコード 型は次のようなものである.
record
year : 0..3000 ; month : 1..12 ; day : 1..31 end
これは, フィールド として, year, month, dayを持ち, それぞれがinteger型の部分範囲型として定義さ れている.
m個の成分を持つ空でないフィールド 並びの値は,次のm組である. ただし,Viはそのフィールド 並び のi番めの成分である.
(V1,· · ·, Vm)
可変部を直接に含むフィールド 並びは,その可変部に対応した一つの成分を持つ. この成分の値と構造は, その可変部によって定義される.
Example 3.12.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 3.12.7 固定部と可変部を持つレコード 型の例は次のようなものである.
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 3.12.8 この例は, 固定部と可変部を持つレコード 型を定義し,そのフィールド に値を代入して いる.
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
これは,タグフィールド がとびとびの値しかとっていない.
3.12.4.1 レコード 型の変数の内部表現
レコード 型の変数はメモリ内で,可変部がどのような状態であっても,それを格納するために十分なメモ リ領域が使用される. しかしながら,メモリ内でフィールド 並びの順にならんでいるとは限らない.
3.12.4.2 with 文
with文は次のような構文を持つ.
with文 ::= with レコード 変数 {, レコード 変数 }do 文
これは,指定したレコード 変数に対して, そのフィールド 名を指定するだけで,各レコード 変数のフィー ルド をアクセスするための構文である.
Example 3.12.9 次の代入はExample 3.12.8の例の代入と等価である.
with p[1],name do begin
first := ’Masashi’ ; family := ’Kubo’ ; id := ’9400001’ ; kind := doctor ; gakunen_d := d3 ; boss_d := ’Prof. Ihara’
end
with文中において,レコード 変数を変更してはならない.