出版社のページ → CUTT System:OBJECT PASCAL HANDBOOK ← 目次あり 楽天ブックスへのリンクです。 OBJECT PASCAL HANDBOOK マルチデバイス開発ツールDelphiのためのプログ [ マルコ・カントゥ ] 2016年10月に購入した「OBJECT PASCAL HANDBOOK」(本体価格:6000円の本)を3月5日に読み始めた。 6000円も出して購入したこの本を死蔵させるのは勿体ないと思いこの3月を強化月間として読むことにしました。 この本は大きく三部に分かれている。
3月中に第2部の「OBJECT PASCAL での OPP」の途中まで行きたいと思ってる。→4月になっても第2章の終わりまでしか読めていない・・・。 使用環境は、Windows10 / Delphi 10.2 Starter版(新しいバージョンが出たら毎回更新予定) ↓2018年4月25日に電子書籍版が出る事を知ったので追記↓
デモのソースコードのダウンロード先はこちら >> MarcoDelphiBooks/ObjectPascalHandbook: Object Pascal Handbook demos source code ![]() ![]() フォルダ数[134]とファイル数[647]が多いです。ちなみに解凍(展開)後のサイズは約12MBです。 ↑2018年4月25日追記終わり↑ 気になった事をメモっていこうと思う。 第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'''; グローバル変数の初期化時だけに初期値も一気に宣言できると知った。 var 定数の宣言は変数名と値だけでOKと知った。コンパイラが型を推察してくれるらしい。 const また定数の型を指定したい場合は以下のようにすればOK const Owl’s Perspective さんの解説コメント。型のない定数(const Foo=1)と型のある定数(const Foo: Integer=1)は厳密には違っていて、 リソース文字列定数という特殊な定数があるのを知った。使い道としては様々な言語で使うプログラムを作る時のローカライズに使用するみたい。 resourcestring グローバル変数、ローカル変数というのは他のプログラミング言語にもあるけど、グローバル隠れ変数というのはあるのかな? こういう仕様。他のプログラミング言語だと同じ変数の仕組みがあるとしても名称が違うのかもしれないなぁ~。 Owl’s Perspective さんの解説コメント。変数のカテゴライズ(グローバルとかローカルとか)はC言語の影響で生存期間(プログラムの最初から最後まで、 整数型 = エイリアス整数型
Owl’s Perspective さんの解説コメント。数値の型はサイズが決まっているものについてはInt8/Int16/Int32/Int64、 YouTubeの解説動画か生配信を見て便利だなぁと思った記憶があるけど、Val := Integer.ToString で数値を数字として文字列に代入出来る機能(Integer型ヘルパー)って、どのバージョンから導入されたんだろう? Owl’s Perspective さんの解説コメント。システムで用意されている基本型(Integerなど)に対するレコードヘルパはXE4で導入されたものです。 ToString以外には、ToBoolean、ToHexString(16進数表記)、ToSingle(単精度浮動小数点数型へ変換)、ToDouble(倍精度浮動小数点数型へ変換)、ToExtended(Extended型 浮動小数点数型へ変換)がある。浮動小数点数って数学を使うプログラムを書いたことないから使ったこと無いからイメージが浮かばない・・・。 Val := hoge.Size.ToStringとするとValにhogeという変数が使用するバイト数が代入される。 他にParse、TryParseってあったけど、どういう時に使うのかよく解らないや(´・ω・`) var Dec()、Inc()は数値を増減させる関数で例えばInc(変数名、数値)って書くと数値の分増やせる。数値を加えるとその分増減するというのは今回知った。 var odd()は変数が奇数ならTrueを返す。 var Owl’s Perspective さんの解説コメント。整数型に用意されているParse/TryParseは文字列('1234')を整数(1234)に変換するもので、 オーバーフローチェックをするようにするコンパイラの設定ってここで設定するのかな? ![]() Owl’s Perspective さんの解説コメント。オーバフローチェックを有効にするには コンパイラ指令{$Q+}{$Q-} を使う 解説を読んで把握しました。 ![]() Boolean型の値には'True'と'False'だけが入る。 var 文字型#32未満の制御文字などに使用されて、よく使われる特殊文字
Cher型のヘルパー関数を使うにはusesでCharacterを宣言しないと使えないっとφ(..)メモ。 ユニコードの文字コードの番号(Unicodeポイント)からchr関数で文字を表示する書き方がわからなかった。例えば大文字のQだと[U+0051]なんですが(´・ω・`) Owl's Perspective さんの解説コメントUnicodeのコードポイントを文字にする方法ですが、即値であれば#を前につけるだけです。 一方でコードポイントが変数(16ビット/符号なし)に入っている場合はChar型にキャストします。 浮動小数点型って近似値という事なのでだいたい合っているという数値っていう理解で良いのかな?一部を除いて小数点以下何桁が決まっていないのかな? Owl’s Perspective さんの解説コメント。浮動小数点数についてはWikipediaの浮動小数点数 あたりもさらっと見ておくとよいかもしれません。
Owl’s Perspective さんの解説コメント。Extendedは拡張精度と呼ばれます。Compは昔Int64/UInt64がなかったときの名残なので無視していいかな。 Mathユニットを使うことあるのかなぁ?ゲームアプリを作ろうとしない限り近い将来には使わなそうだけど・・・。 ↓2018年4月追記分↓ ユーザー定義データ型短く書くなら、「名前付きの型と名前無しの型、それぞれ定義出来るが名前付きの型を推奨する。」 部分範囲型type 列挙型通常はenumsと表記される。この型で想定される値のすべてをリストアップする型 現状の知識だとtypeを定義する事ってクラスを定義する以外で使うことがありそうにないけど実際のところどうなんだろ?type 集合型よく使われるのはフォントのスタイルを表現するのに使われている。 type 集合演算子集合演算子には和(+)、差(-)、積(*)、帰属関係(in)といくつか種類がある。 Style := Style + {fsBold}; // 太字化 和(+)、差(-)、積(*)、の3つは見たことあるけど、帰属関係(in)って何だろ? for-inループと関係あるのかな? Include {Style, fsBold}; // 読み込む処理 Owl’s Perspective さんの解説コメント。部分範囲型、列挙型は、いわゆるマジックナンバーを(型の枠組みの中で安全に扱いつつ)なくすために使います。 式と演算子ShowMessage (BoolToStr (3 < 30, True)); // True と表示される。 ↑の書き方がある事を知らなかった。 ちょっと上に書いた「帰属関係(in)って何だろ?」は関係演算子と比較演算子の所に書かれていた。
ポインタのオフセットの加算や減算って何だろう?ポインタの知識が無いから後回しかな? 日付と時刻日付と時刻の情報は初期のPascalには無かった。ObjectPascalになってから追加された型で浮動小数点型を使用している。
日付や時刻に関する関数へのヘルプへのリンク→日付および時刻のサポート - RAD Studio 型キャストと型変換ここの単元?は理解度が低めかな。細かい理屈はいまいち??だから。例えば整数からInt64や浮動小数点型には型変換は可能(プロモート)だけど、その逆(デモート)は許可されていないのは、ビルド時に怒られるので知ってる。 これで第2章は終わった 2018年5月1日 00:42 Owl’s Perspective さんの解説コメント。ポインタは…まぁいろいろありますが、一言で言うと、データの置いてある場所("アドレス")を
by arigayas
| 2018-03-08 10:47
| Delphi Programming
|
Trackback
|
Comments(10)
※このブログはトラックバック承認制を適用しています。
ブログの持ち主が承認するまでトラックバックは表示されません。
![]()
結構なボリュームがありますが頑張ってくださいね。いくつか補足を。
{$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
Like
OBJECT PASCAL に詳しい Owl’s Perspective さん、補足コメントありがとうございます。
数値の型についてはメモっていた途中でコメントを頂きましたね(汗) これからもチビチビと加筆していくのでツッコミをお願いいたします。 ![]()
コメントしようと思ったら禁止ワードに引っかかってるとのこと。おまけに内容消えちゃうし…。多分エキサイト側の不具合か設定ミスじゃないかと
思うんですが、ちょっと萎えてしまいました。ということで一部分だけ。これ以前のところはまた書き直します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は例外をスルーしてプログラムに処理を継続させる(プログラムのエラー処理がそのまま動作する)かを例外の種類毎に選択させるためのものです。 ![]()
気を取り直して。
システムで用意されている基本型(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; (続く) ![]()
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を使います。 (もうちょっとだけ続く) ![]()
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は関数の形式を取っていますが、実際にはコンパイラが直接必要なコードを展開するため"コンパイラマジック"と呼ばれます(昔の呼び方だと"プリミティブ")。 では引き続き頑張ってください。 ![]()
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); ![]()
第2章終了おつかれさまです。
浮動小数点数についてはwikipediaの https://ja.wikipedia.org/wiki/%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0 あたりもさらっと見ておくとよいかもしれません。基本的には小数点以下何桁ということではなく、値全体で何桁の有効桁数を持つか、という理解でいいと思います。あと浮動小数点は整数と特定の(2進数で考えてぴったりの)値は誤差なく表せますが、小数点以下を持つ値は基本的に誤差含みになります。 Extendedは拡張精度と呼ばれます。Compは昔Int64/UInt64がなかったときの名残なので無視していいかな。Currencyは以前は通貨型と呼ばれてたはず。これはいわゆる固定小数点数で、小数点以下が4桁に固定されてます(Int64の値を1/10000して考えるような感じ)。お金の計算には浮動小数点数は適さないけれども、補助通貨単位(円に対する銭やドルに対するセント)を扱わなければならない、という状況のためにあります。 ![]()
部分範囲型、列挙型は、いわゆるマジックナンバーを(型の枠組みの中で安全に扱いつつ)なくすために使います。また集合型とその基本型になる列挙型は、フラグの集まりを簡易に扱うことを可能にすることに使います。
ポインタは…まぁいろいろありますが、一言で言うと、データの置いてある場所("アドレス")を入れるための入れ物の型、です。普通は変数には数値や文字列を入れますが、同じように場所を入れておけるもの、それがポインタです。ポインタの加減算は、入れてあるアドレスの値が加減算される、つまり場所がずれるためオフセット、という表現になります。
Owl's Perspective さん解説コメントありがとうございます。
ページを上下にスクロールさせながら読むのは読みにくいと思ったので 勝手ながらコメントをブログ本文に差し込ませていただきました。 浮動小数点数のWikipediaのページをチラッと見たら「この分量は読み切れる気がしません・・・。」ってなりました(苦笑) ポインタでたまに出る話題として「ポインタのポインタ」がありますが、これはWebのリンクのリンクって言うイメージであってますか? ポインタアドレスが下のようにあって全部のアドレスに変数の値が入っているとして。 0100 0000 Red 0100 0001 Yellow 0100 0002 Green 0100 0003 Cyan Yellowのポインタからマイナス1するとRedのアドレス[0100 0000]になるし、 Yellowのポインタからプラス2するとCyanのアドレス[0100 0003]になるという理解で良いのでしょうか? プログラムでポインタを扱う頃にはもっと理解度が深くなっていれば良いのですが・・・。
| |||||
ファン申請 |
||