約1年半前に購入した「OBJECT PASCAL HANDBOOK」を読み始めた。

出版社のページ → CUTT System:OBJECT PASCAL HANDBOOK ← 目次あり


2016年10月に購入した「OBJECT PASCAL HANDBOOK」(本体価格:6000円の本)を3月5日に読み始めた。
買ってから一度2、3日ぐらいで30ページぐらいを寝る前に読んだんですが、
パソコンで全く試さずに読んでいたら、記述されている事が気になりストレスになってしまって読むのを止めてしまいました。

6000円も出して購入したこの本を死蔵させるのは勿体ないと思いこの3月を強化月間として読むことにしました。
あと今年の誕生日に「独習PHP 第3版」を買ったのもある。「OBJECT PASCAL HANDBOOK」を読み終えたら「独習PHP 第3版」をやるつもり。

この本は大きく三部に分かれている。

  1. 基礎 [第1章~第6章]
  2. OBJECT PASCAL での OPP [第7章~第13章]
  3. 高度な機能 [第14章~第18章]

3月中に第2部の「OBJECT PASCAL での OPP」の途中まで行きたいと思ってる。

使用環境は、Windows10 / Delphi 10.2 Starter版(新しいバージョンが出たら毎回更新予定)






気になった事をメモっていこうと思う。

第1章で気になった事は、ソースコードにデバッグ用ビルドのみに動くコンパイラ指令「{$IFDEF DEBUG} と {$ENDIF} で囲う」を書いたことはあったけど、これ以外にコンパイラ指令の1つに(あまり使われないらしいけど)

{$INCLUDE XXX}

と言うのがあるのを初めて知った。

Owl’s Perspective さんの解説コメント。
{$INCLUDE XXXX} あるいは {$I XXXX} はファイルXXXXをこの場所に読み込む(置き換える)というものですが、
例えばツールなどで自動生成したファイルをソースコードの一部として使うなどのような場合に使われます。

第2章ではPascalでは、文字列を変数に代入するにはシングルクォテーション記号「'」で囲って

string := '文字列ですよ';

と書くのだけど、著者の名前(シングルクォテーション記号「'」も付けた状態)を変数に代入する場合には

string := 'Marco Cantu''';

正規表現で「\」を表現したい時の\\みたいにシングルクォテーションを重ねる必要があるのは面白いなと思った。

また、ダイアログボックス等で文字列を途中で改行したい場合に「#13#10」と入れていたけど、「sLineBreak」と入れれば改行されると知った。

string := 'Marco' + sLineBreak + 'Cantu''';
b0003577_17405985.png

グローバル変数の初期化時だけに初期値も一気に宣言できると知った。

var
Value: Integer = 10;
flag: Boolean = True;

定数の宣言は変数名と値だけでOKと知った。コンパイラが型を推察してくれるらしい。

const
Value = 1000;
Pi = 3.1415;
Name = 'アンナ';

また定数の型を指定したい場合は以下のようにすればOK

const
Value: Integer = 1000;

リソース文字列定数という特殊な定数があるのを知った。使い道としては様々な言語で使うプログラムを作る時のローカライズに使用するみたい。

resourcestring
strName = 'アンナ';

begin
ShowMessage(strName);
end;

グローバル変数、ローカル変数というのは他のプログラミング言語にもあるけど、グローバル隠れ変数というのはあるのかな?
オイラの理解で書くと複数のファイル[A、B、C]で書かれたソースコードがあるとする。
ファイルAで宣言されたグローバル隠れ変数にはファイルAに書かれた手続きや関数からアクセス出来るけど、ファイルBやCからはファイルAのグローバル隠れ変数にはアクセスできない。

こういう仕様。他のプログラミング言語だと同じ変数の仕組みがあるとしても名称が違うのかもしれないなぁ~。

整数型 = エイリアス整数型

  • 8ビット
    ShortInt = Int8
    -128から127
    Byte UInt8
    0から255
  • 16ビット
    SmallInt = Int16
    -32Kから32K
    Word = UInt16
    0から64K
  • 32ビット
    Integer = Int32
    -2GBから2GB
    Cardinal = UInt32
    0から4GB
  • 64ビット
    Int64
    -922京から922京
    UInt64
    0から1844京:16エクサバイト
  • プラットフォームによってサイズが変わる型
    NativeInt、NativeUInt、LargeInt
    プラットフォームが32ビットプラットフォームなら32ビットの整数型と同じサイズになるし、
    64ビットプラットフォームなら64ビットの整数型と同じサイズになる。

YouTubeの解説動画か生配信を見て便利だなぁと思った記憶があるけど、Val := Integer.ToString で数値を数字として文字列に代入出来る機能(Integer型ヘルパー)って、どのバージョンから導入されたんだろう?


ToString以外には、ToBoolean、ToHexString(16進数表記)、ToSingle(単精度浮動小数点数型へ変換)、ToDouble(倍精度浮動小数点数型へ変換)、ToExtended(Extended型 浮動小数点数型へ変換)がある。浮動小数点数って数学を使うプログラムを書いたことないから使ったこと無いからイメージが浮かばない・・・。

Val := hoge.Size.ToStringとするとValにhogeという変数が使用するバイト数が代入される。 他にParse、TryParseってあったけど、どういう時に使うのかよく解らないや(´・ω・`)
一応動くソースコードを書けたけど。

var
_64bit : Integer;
num : string;
begin
_64bit := 123456;
num := '98765';

ShowMessage('バイトサイズ:' + _64bit.Size.ToString);

_64bit := num.Parse(num.ToInteger).ToInteger;
ShowMessage('Parse:' + _64bit.ToString);
end;

Dec()、Inc()は数値を増減させる関数で例えばInc(変数名、数値)って書くと数値の分増やせる。数値を加えるとその分増減するというのは今回知った。

var
IncInc : Integer
IncInc : = 0;
Inc(IncInc); // IncInc は1になる。
Inc(IncInc , 10); // IncInc は11になる。
Dec(IncInc); // IncInc は10になる。
Dec(IncInc , 10); // IncInc は0になる。

odd()は変数が奇数ならTrueを返す。
Low()は最小値、High()は最大値。Pred、Succ、Ordはよく解らなかったので後回しにする。

var
str : string;
str := Low(Int8).ToString; // -128
str := Low(Integer).ToString; // -2147483648

str := High(Int8).ToString; // 127
str := High(Integer).ToString; // 2147483647

オーバーフローチェックをするようにするコンパイラの設定ってここで設定するのかな?

b0003577_21440977.png

Boolean型の値には'True'と'False'だけが入る。

var
checkFlg: Boolean;
begin

checkFlg := True;
ShowMessage( checkFlg.ToString ); // -1 と表示される ←メモにあったMicrosoftのCOMおよびOLEオートメーションとの互換性のため-1という事かな?
ShowMessage( checkFlg.ToInteger.ToString ); // 1 と表示される
end;

文字型#32未満の制御文字などに使用されて、よく使われる特殊文字

  • #8 : バックスペース
    • テキストエディタで文字を1文字ずつ消していく演出に使うのかな?と思ったけど、それだけの為にこの特殊文字があるのは変だと思ってググってみた。
      バックスペースキーが入力された時の判定などに使うようだ。
      →1文字ずつ消していく演出を試しに作ってみよう。
  • #9 : タブ文字
  • #10 : 改行
  • #13 : キャリッジリターン
  • $27 : エスケープ

Cher型のヘルパー関数を使うにはusesCharacterを宣言しないと使えないっとφ(..)メモ。

ユニコードの文字コードの番号(Unicodeポイント)からchr関数で文字を表示する書き方がわからなかった。例えば大文字のQだと[U+0051]なんですが(´・ω・`)

Owl's Perspective さんの解説コメント
Unicodeのコードポイントを文字にする方法ですが、即値であれば#を前につけるだけです。
var
S: String;
begin
S := #$0041 + #$0042; // U+0041(A) + U+0042(B)
一方でコードポイントが変数(16ビット/符号なし)に入っている場合はChar型にキャストします。
var
W1: UInt16;
W2: UInt16;
S: String;
begin
W1 := $0041;
W2 := $0042;
S := Char(W1) + Char(W2);

浮動小数点型って近似値という事なのでだいたい合っているという数値っていう理解で良いのかな?一部を除いて小数点以下何桁が決まっていないのかな?

Single - 単精度浮動小数点型 4バイト。
他のプログラミング言語ではfloatと呼ばれることがある。
var
sl : Single;
begin
sl := 0.5 * 0.2;
show(sl.ToString); // 0.100000001490116
Doubleだと計算結果はちゃんと0.1になる。
Double - 倍精度浮動小数点型 8バイト。
良く使用される。
Extended - ??? 10バイト。
この型を使用できないプラットフォームもある。Win64ではDoubleと同じ精度に引き下げられる。
他のプログラミング言語ではlong doubleと呼ばれることがある。
Comp - ??? 8バイト。
大きな整数(18桁まで)を正確に表現したい時に使う。
Currency - ??? 8バイト(64bit)。
小数点以下4桁に固定されている。通貨計算を処理するために追加された。

Mathユニットを使うことあるのかなぁ?ゲームアプリを作ろうとしない限り近い将来には使わなそうだけど・・・。


[PR]

by arigayas | 2018-03-08 10:47 | Delphi Programming | Trackback | Comments(7)
トラックバックURL : https://arigayas.exblog.jp/tb/28179761
トラックバックする(会員専用) [ヘルプ]
※このブログはトラックバック承認制を適用しています。 ブログの持ち主が承認するまでトラックバックは表示されません。
Commented by Owl’s Perspective at 2018-03-10 21:27 x
結構なボリュームがありますが頑張ってくださいね。いくつか補足を。

{$INCLUDE XXXX} あるいは {$I XXXX} はファイルXXXXをこの場所に読み込む(置き換える)というものですが、例えばツールなどで自動生成した
ファイルをソースコードの一部として使うなどのような場合に使われます。

型のない定数(const Foo=1)と型のある定数(const Foo: Integer=1)は厳密には違っていて、型のない定数はコンパイル時にその値が埋め込まれるのに
対して、型のある定数は実際にその型で書き換えられない領域が確保され、指定された値がここに格納される、ということになっています。

変数のカテゴライズ(グローバルとかローカルとか)はC言語の影響で生存期間(プログラムの最初から最後まで、ブロックに入ったときから出たときまで)と
スコープ(プログラム全体から見える、そのファイルからのみ見える、そのブロックからのみ見える)がごっちゃになってしまっていますが、
グローバル隠れ変数(生存期間がプログラムの最初から最後まで、スコープはそのファイルからのみ見える)は一般的にファイルローカル変数と呼ばれていると
思います。

数値の型はサイズが決まっているものについてはInt8/Int16/Int32/Int64、UInt8/UInt16/UInt32/UInt64のほうがサイズがはっきりしていて
いいと思います(SmallIntとShortIntのどっちが大きいとか覚えてられないので)。

それでは引き続きObject Pascal Handbookをお楽しみくださいw
Commented by arigayas at 2018-03-10 21:57
OBJECT PASCAL に詳しい Owl’s Perspective さん、補足コメントありがとうございます。
数値の型についてはメモっていた途中でコメントを頂きましたね(汗)

これからもチビチビと加筆していくのでツッコミをお願いいたします。
Commented by Owl's Perspective at 2018-03-16 15:13 x
コメントしようと思ったら禁止ワードに引っかかってるとのこと。おまけに内容消えちゃうし…。多分エキサイト側の不具合か設定ミスじゃないかと
思うんですが、ちょっと萎えてしまいました。ということで一部分だけ。これ以前のところはまた書き直しますw

オーバフローチェックを有効にするにはコンパイラ指令{$Q+}{$Q-}
http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%95%E3%83%AD%E3%83%BC%E3%81%AE%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%EF%BC%88Delphi%EF%BC%89
を使う(ソースコード上の特定の区間を指定する場合)か、メインメニュー→プロジェクト→オプションでプロジェクトオプションを表示し、
左側のツリーでDelphiコンパイラ→コンパイルで表示されるコンパイルオプションページの実行時エラー
http://docwiki.embarcadero.com/RADStudio/Tokyo/ja/%EF%BC%BB%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%EF%BC%BD#.EF.BC.BB.E5.AE.9F.E8.A1.8C.E6.99.82.E3.82.A8.E3.83.A9.E3.83.BC.EF.BC.BD.E3.82.AA.E3.83.97.E3.82.B7.E3.83.A7.E3.83.B3
のところにあるオーバフローチェックを有効にします。

ちなみにデバッガオプションのところにある例外の設定は、例外が発生したときに先にデバッガ(IDE)で捕捉してエラー処理の部分をデバッグをできるようにするか、
IDEは例外をスルーしてプログラムに処理を継続させる(プログラムのエラー処理がそのまま動作する)かを例外の種類毎に選択させるためのものです。
Commented by Owl's Perspective at 2018-03-19 16:39 x
気を取り直して。

システムで用意されている基本型(Integerなど)に対するレコードヘルパはXE4で導入されたものです。また整数型に用意されているParse/TryParseは文字列('1234')を整数(1234)に変換するもので、StrToInt/TryStrToInt関数に対応しています。

var
S: String;
I: Integer;
begin
S := '1234';
I := Integer.Parse(S); // Iに1234が入る

S := 'ABCD';
I := Integer.Parse(S); // EConvertErrorが発生

S := 'ABCD';
if Integer.TryParse(S,I) = False then
begin
// TryParseがFalseを返す→変換できなかった
end
else
begin
// TryParseがTrueを返す→変換できた(Iに代入されている)
end;
(続く)
Commented by Owl's Perspective at 2018-03-19 16:41 x
Low/Highは(Pred/Succも)整数型だけではなく順序型に属している型、例えば列挙型にも使用できます。

type
TFoo = (Bar, Baz, Foobar);

var
Foo: TFoo;
begin
Foo := Low(TFoo); // Bar
Foo := High(TFoo); // Foobar

Pred/Succはpredecessor/successorの略で、順序型で現在の値の1つ前、1つ後を示す値を返します。上記の列挙型TFooで、

var
Foo := Low(TFoo); // Bar
Foo := Succ(Foo); // Baz
Foo := Succ(Foo); // Foobar
Foo := Pred(Foo); // Baz

こんな感じです。列挙型は-1/+1する、ということが直接的にできないので、代わりにPred/Succを使います。
(もうちょっとだけ続く)
Commented by Owl's Perspective at 2018-03-19 16:42 x
Ordはorderの略で、順序型の値が実際の値としていくつなのかを返します。これは整数型と代入互換性がないAnsiChar/WideChar/Char型や、列挙型に対して使って、一種の型キャストのように働きます。

var
I: Integer;
C: Char;
Foo: TFoo;
begin
C := 'A';
// I := C; // エラー
I := Ord(C); // Iは65(0x41)
Foo := Baz;
// I := Foo; // エラー
I := Ord(Foo); // Iは1(Barが0、Bazが1、Foobarが2)

Object PascalはCなどの言語と比較して型に厳密で、不用意に代入が行われないようにこのようなものが用意されています。

なおLow/High、Pred/Succ、Dec/Inc、Ordは関数の形式を取っていますが、実際にはコンパイラが直接必要なコードを展開するため"コンパイラマジック"と呼ばれます(昔の呼び方だと"プリミティブ")。

では引き続き頑張ってください。
Commented by Owl's Perspective at 2018-03-22 15:00 x
Unicodeのコードポイントを文字にする方法ですが、即値であれば#を前につけるだけです。
var
S: String;
begin
S := #$0041 + #$0042; // U+0041(A) + U+0042(B)
一方でコードポイントが変数(16ビット/符号なし)に入っている場合はChar型にキャストします。
var
W1: UInt16;
W2: UInt16;
S: String;
begin
W1 := $0041;
W2 := $0042;
S := Char(W1) + Char(W2);
<< 2018年4月からのアニメ 2018年1月からのアニメ >>