プログラミング学習 Day 4:データ型、オブジェクト・Class

2025年11月5日

今回はHLP言語が内蔵するデータ型、データ構造の説明です。

PASCALは他の言語に比べて以下のような充実したデータ型を内蔵しています。

Integer(整数型


Integer: 通常 32-bit
ShortInt, SmallInt, LongInt
Int64(または int64、Int64)
64ビット符号付き整数
範囲: −9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807 (−2^63 .. 2^63−1)
サイズ: 8 バイト
Byte
8ビット符号なし整数(多くの言語で)
範囲: 0 .. 255
サイズ: 1 バイト

var
a: Integer;
b: Int64;
c: Byte;
begin
a := 42;
b := 1_000_000_000_000;
c := 255;
 end;

浮動小数点

Single:単精度浮動小数点(32-bit、IEEE 754 単精度)
Double:倍精度浮動小数点(64-bit、IEEE 754 倍精度)
Currency:ドル金額
var
s: Single;
d: Double;
z: Currency;

begin
s := 1.234567; // single 精度で格納(有効桁約7桁)
d := 1.234567890123; // double 精度(有効桁約15桁)
Writeln(Format('s = %.8f, d = %.12f', [s, d]));
z := 12.34; // Currency
end;


■テキスト

Char, String: 文字、テキスト

var

  c: Char;

  s: string;

  ss: ShortString;

begin

  c := ‘A’;

  s := ‘今日は晴れです’; // UnicodeString の場合は UTF-16/UTF-8 実装に依存

  ss := ‘Hi’; // ShortString

end;

■その他

列挙型:オブジェクトの列挙
type TColor = (white, red, yellow, blue);
部分域型:「基底型の値域のうち連続した区間」を型
type
Age = 0..150;
SmallPercent = 0..100;
UpperChar = 'A'..'Z';


集合型:列挙子を要素とする
type
TColor = (white, red, yellow, blue);
TWeekday = (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
TSmall = 1..10;
TWeekSet = set of TWeekday;
TWeek = set of (Mon..Sun);

■レコード

レコード型(record):record は構造体。メソッドやコンストラクタを持てる。

type
TPoint = record
X, Y: Integer;
constructor Create(AX, AY: Integer);
function DistanceTo(const P: TPoint): Double;
end;
___________________________________________



■オブジェクト・Calss

前回にも少し説明しましたが、データ構造のもっともすすんだものはオブジェクト指向の構造です。
例を使って定義してみます。

前回で説明した「花」に戻ります。
花というオブジェクトは、名前と季節と色を属性とします。


PASCALを使って定義すると、

花の名前はStringで任意ですが、seasonとcolorは決められた中のものしか使えないように設計します。
このオブジェクトに内包される機能をProcedureFunctionで記述します。
つまり、オブジェクトという卵の中にProcedureとFunctionが閉じられていて、それ以外で卵にアクセスしないように守られています。色に定義されていないBlackやGrayは使えません。

■PASCALの例

program flower;

type
TSeason = (spring, summer, fall, winter);
TColor = (white, red, yellow, blue);

const
SeasonNames: array[TSeason] of string = ('spring', 'summer', 'fall', 'winter');
ColorNames: array[TColor] of string = ('white', 'red', 'yellow', 'blue');

type
TFlower = record
private
FName: string;
FColor: TColor;
FSeason: TSeason;
public
constructor Create(const AName: string; AColor: TColor; ASeason: TSeason);
procedure SetName(const AName: string);
procedure SetColor(AColor: TColor);
procedure SetSeason(ASeason: TSeason);

function GetName: string;
function GetColor: TColor;
function GetSeason: TSeason;

function ToString: string;
end;


constructor TFlower.Create(const AName: string; AColor: TColor; ASeason: TSeason);
begin
FName := AName;
FColor := AColor;
FSeason := ASeason;
end;

procedure TFlower.SetName(const AName: string);
begin
FName := AName;
end;

procedure TFlower.SetColor(AColor: TColor);
begin
FColor := AColor;
end;

procedure TFlower.SetSeason(ASeason: TSeason);
begin
FSeason := ASeason;
end;

function TFlower.GetName: string;
begin
Result := FName;
end;

function TFlower.GetColor: TColor;
begin
Result := FColor;
end;

function TFlower.GetSeason: TSeason;
begin
Result := FSeason;
end;

function TFlower.ToString: string;
begin
Result := Format('Name: %s, Color: %s, Season: %s',
[FName, ColorNames[FColor], SeasonNames[FSeason]]);
end;

end.

■Pythonのデータ構造とClass

Pythonのもつデータ型はPASCALに比べて少なくて以下です。
ただし、変数にデータ型を事前に定義しないので、実行時に値を代入するときにしか
その変数はどのようなデータ型を持つのかわかりません。
str(文字列)
int
float
list
tuple
dictionary

詳細は添付にある教科書を参照してください。
PythonのClassを使った花のオブジェクトを定義をしてみます。
(PASCALのClassを使った花の定義は参考にあげています)


flower_class.py
#!/usr/bin/env python3
from enum import Enum, auto
#auto() は値の自動割り当て。クラス内で順に 1,2,... が割り当てられる
from typing import List, Optional

class Season(Enum):
SPRING = auto()
SUMMER = auto()
FALL = auto()
WINTER = auto()

def __str__(self) -> str:
return self.name.lower()


class Color(Enum):
WHITE = auto()
RED = auto()
YELLOW = auto()
BLUE = auto()

def __str__(self) -> str:
return self.name.lower()


class Flower:

def __init__(self, name: str, color: Color, season: Season) -> None:
self._name = name
self._color = color
self._season = season

# properties
@property
def name(self) -> str:
return self._name

@name.setter
def name(self, v: str) -> None:
if not isinstance(v, str):
raise TypeError("name must be a str")
v = v.strip()
if v == "":
raise ValueError("name must not be empty")
self._name = v

@property
def name(self) -> str:
return self._name

@name.setter
def name(self, v: str) -> None:
self._name = v

@property
def color(self) -> Color:
return self._color

@color.setter
def color(self, v: Color) -> None:
self._color = v

@property
def season(self) -> Season:
return self._season

@season.setter
def season(self, v: Season) -> None:
self._season = v



花のClassである Flowerを使ってGardenを定義します。

class Garden:

def __init__(self) -> None:
self._flowers: List[Flower] = []

def add_flower(self, flower: Flower) -> None:
if flower is None:
return
self._flowers.append(flower)

def count(self) -> int:
return len(self._flowers)

def get_flower(self, index: int) -> Flower:
return self._flowers[index]
def remove_at(self, index: int) -> None:
if index < 0 or index >= len(self._flowers):
raise IndexError("index out of range")

del self._flowers[index]

def clear(self) -> None:
self._flowers.clear()

def list_flowers(self) -> None:
print(f"Garden contents (count={self.count()}):")
if self.count() == 0:
print(" (empty)")
return

■IS-A

今度は、PASCALを使ってIS-Aと呼ばれるClassの階層構造の例を挙げます。
学校や企業や組織の中に所属する従業員、学生、部長などを表現するときに、ます、共通するClassとして
人の定義を行います。それによって、組織や抽象化の階層を表現できます。
一番上位の人(Person)のClass定義をやります。
その後、SubClassとして先生、学生、スタッフなどの定義をします。


program PersonClass;

type
TPerson = class
private
FName: string;
FAge: Integer;
public
constructor Create(const AName: string; AAge: Integer);
destructor Destroy;

procedure Greet;
function IsAdult: Boolean;

property Name: string read FName write FName;
property Age: Integer read FAge write FAge;
end;


{TPerson}

constructor TPerson.Create(const AName: string; AAge: Integer);
begin
inherited Create;
FName := AName;
FAge := AAge;
WriteLn('TPerson.Create: ', FName);
end;

destructor TPerson.Destroy;
begin
WriteLn('TPerson.Destroy: ', FName);
inherited Destroy;
end;

procedure TPerson.Greet;
begin
WriteLn(Format(' My name is %s and I am %d years old.', [FName, FAge]));
end;

function TPerson.IsAdult: Boolean;
begin
Result := FAge >= 18;
end;

{サンプルのメイン}

var
p: TPerson;
begin
p := TPerson.Create(Masa', 30);
try
p.Greet;
WriteLn('Is adult: ', BoolToStr(p.IsAdult, True));
p.Name := 'Masa Matsuo';
p.Age := 31;
p.Greet;
finally
p.Free;
end;
end.

■参考

PASCALによる花のClassの例

program FlowerClass;

uses
  SysUtils;

type
  TSeason = (spring, summer, fall, winter);
  TColor  = (white, red, yellow, blue);

const
  SeasonNames: array[TSeason] of string = ('spring', 'summer', 'fall', 'winter');
  ColorNames: array[TColor] of string = ('white', 'red', 'yellow', 'blue');

type
  TFlower = class
  private
    FName: string;
    FColor: TColor;
    FSeason: TSeason;
  public
    constructor Create(const AName: string; AColor: TColor; ASeason: TSeason); virtual;
    destructor Destroy;
    procedure SetName(const AName: string);
    function GetName: string;
    procedure SetColor(AColor: TColor);
    function GetColor: TColor;
    procedure SetSeason(ASeason: TSeason);
    function GetSeason: TSeason;

    function Describe: string; virtual;
    function BloomInfo: string; virtual;

    property Name: string read GetName write SetName;
    property Color: TColor read GetColor write SetColor;
    property Season: TSeason read GetSeason write SetSeason;
  end;

constructor TFlower.Create(const AName: string; AColor: TColor; ASeason: TSeason);
begin
  inherited Create;
  FName := AName;
  FColor := AColor;
  FSeason := ASeason;
end;

destructor TFlower.Destroy;
begin
  inherited Destroy;
end;

procedure TFlower.SetName(const AName: string);
begin
  FName := AName;
end;

function TFlower.GetName: string;
begin
  Result := FName;
end;

procedure TFlower.SetColor(AColor: TColor);
begin
  FColor := AColor;
end;

function TFlower.GetColor: TColor;
begin
  Result := FColor;
end;

procedure TFlower.SetSeason(ASeason: TSeason);
begin
  FSeason := ASeason;
end;

function TFlower.GetSeason: TSeason;
begin
  Result := FSeason;
end;

function TFlower.Describe: string;
begin
  Result := Format('Name: %s, Color: %s, Season: %s',
    [FName, ColorNames[FColor], SeasonNames[FSeason]]);
end;

function TFlower.BloomInfo: string;
begin
  Result := Format('%s blooms in %s.', [FName, SeasonNames[FSeason]]);
end;


end.

著者:松尾正信
株式会社京都テキストラボ代表取締役