パスカル-クイックガイド

Pascalは、1970年代初頭にNiklausWirthによって最初に開発された汎用の高級言語です。体系的な分野としてプログラミングを教え、信頼性が高く効率的なプログラムを開発するために開発されました。

PascalはAlgolベースの言語であり、Algolの多くの構成要素が含まれています。Algol60はPascalのサブセットです。Pascalは、いくつかのデータ型とプログラミング構造を提供します。Pascalプログラムを理解して維持するのは簡単です。

パスカルは、さまざまな理由で教育および学術分野で人気が高まっています。

  • 簡単に学べる。
  • 構造化言語。
  • 透過的で効率的で信頼性の高いプログラムを作成します。
  • さまざまなコンピュータープラットフォームでコンパイルできます。

Pascal言語の機能

Pascalには次の機能があります-

  • パスカルは強く型付けされた言語です。
  • 広範なエラーチェックを提供します。
  • 配列、レコード、ファイル、セットなどのいくつかのデータ型を提供します。
  • さまざまなプログラミング構造を提供します。
  • 関数とプロシージャを通じて構造化プログラミングをサポートします。
  • オブジェクト指向プログラミングをサポートします。

パスカルについての事実

  • Pascal言語は、フランスの数学者であり、コンピューター開発のパイオニアであるBlaisePascalにちなんで名付けられました。

  • Niklaus Wirthは、1970年にオリジナルのPascalプログラミング言語の開発を完了しました。

  • Pascalは、Algolプログラミング言語のブロック構造化スタイルに基づいています。

  • Pascalは、体系的な分野としてプログラミングを教えるのに適した言語として開発されました。その実装は、信頼性と効率性の両方を備えています。

  • ISO 7185パスカル規格は、1983年に最初に発行されました。

  • Pascalは、AppleLisaおよびMacの初期の開発に使用された主要な高レベル言語でした。

  • 1986年にAppleComputerは最初のObjectPascal実装をリリースし、1993年にPascal標準委員会はPascalのオブジェクト指向拡張を公開しました。

Pascalを使用する理由

Pascalを使用すると、プログラマーは複雑な構造化データ型を定義し、リスト、ツリー、グラフなどの動的で再帰的なデータ構造を構築できます。Pascalは、レコード、列挙、サブ範囲、動的に割り当てられた変数などの機能と、関連するポインターおよびセットを提供します。

Pascalでは、ネストされたプロシージャ定義を任意のレベルの深さにすることができます。これは、基本的な概念に基づいた体系的な分野としてプログラミングを学ぶための優れたプログラミング環境を本当に提供します。

Pascalの最も驚くべき実装の中には次のものがあります-

  • Skype
  • トータルコマンダー
  • TeX
  • Macromedia Captivate
  • アップルリサ
  • さまざまなPCゲーム
  • 組み込みシステム

一般的に使用できるPascalコンパイラとインタプリタがいくつかあります。これらの中には-

  • Turbo Pascal − CP / M、CP / M-86、DOS、Windows、MacintoshでPascalプログラムを実行するためのIDEとコンパイラを提供します。

  • Delphi− Object Pascalを実行するためのコンパイラを提供し、32ビットおよび64ビットのWindowsオペレーティングシステム、および32ビットのMac OSXおよびiOS用のネイティブコードを生成します。Embarcaderoは、LinuxおよびAndroidオペレーティングシステムのサポートを構築することを計画しています。

  • Free Pascal−PascalおよびObjectPascalプログラムを実行するための無料のコンパイラです。Free Pascalコンパイラは、Linux、Windows、OS / 2、FreeBSD、Mac OS X、DOS、およびその他のいくつかのプラットフォーム向けの32ビットおよび64ビットのTurboPascalおよびDelphi互換のPascalコンパイラです。

  • Turbo51 − Turbo Pascal 7構文を備えた、8051ファミリのマイクロコントローラ用の無料のPascalコンパイラです。

  • Oxygene −.NETおよびMonoプラットフォーム用のObjectPascalコンパイラです。

  • GNU Pascal (GPC) −GNUコンパイラコレクションのフロントエンドで構成されるPascalコンパイラです。

これらのチュートリアルでは、FreePascalを使用します。次のリンクから、オペレーティングシステム用のFreePascalをダウンロードできます。FreePascalをダウンロード

LinuxへのFreePascalのインストール

Free PascalのLinuxディストリビューションには、次の3つの形式があります。

  • a tar.gz バージョン、個別のファイルとしても利用可能。

  • a .rpm (Red Hat Package Manager)バージョン。

  • a .deb (Debian)バージョン。

.rpmバージョンのインストールコード::

rpm -i fpc-X.Y.Z-N.ARCH.rpm

ここで、XYZは.rpmファイルのバージョン番号であり、ARCHはサポートされているアーキテクチャ(i386、x86_64など)の1つです。

Debianバージョン(Ubuntuなど)のインストールコード-

dpkg -i fpc-XXX.deb

ここで、XXXは.debファイルのバージョン番号です。

詳細については、以下をお読みください:無料のPascalインストールガイド

Macに無料のPascalをインストールする

Mac OS Xを使用している場合、Free Pascalを使用する最も簡単な方法は、AppleのWebサイトからXcode開発環境をダウンロードし、簡単なインストール手順に従うことです。Xcodeをセットアップすると、FreePascalコンパイラを使用できるようになります。

WindowsへのFreePascalのインストール

Windowsの場合、Windowsインストーラーsetup.exeをダウンロードします。これは通常のインストールプログラムです。インストールするには、次の手順を実行する必要があります-

  • ディレクトリを選択します。

  • インストールするパッケージのパーツを選択します。

  • オプションで、.ppまたは.pas拡張子をFree PascalIDEに関連付けることを選択します。

詳細については、以下をお読みください:無料のPascalインストールガイド

テキストエディタ

これは、プログラムの入力に使用されます。いくつかのエディターの例には、Windowsメモ帳、OS Editコマンド、Brief、Epsilon、EMACS、vimまたはviが含まれます。

テキストエディタの名前とバージョンは、オペレーティングシステムによって異なる場合があります。たとえば、メモ帳はWindowsで使用され、vimまたはviはWindowsだけでなくLinuxまたはUNIXでも使用できます。

エディタで作成するファイルはソースファイルと呼ばれ、プログラムのソースコードが含まれています。Pascalプログラムのソースファイルには、通常、拡張子が付けられています。.pas

プログラミングを開始する前に、テキストエディタが1つあり、コンピュータプログラムを作成し、ファイルに保存し、コンパイルして、最後に実行するのに十分な経験があることを確認してください。

Pascalプログラミング言語の基本的な構成要素を学習する前に、次の章で参照できるように、最小限のPascalプログラム構造を見てみましょう。

Pascalプログラムの構造

Pascalプログラムは、基本的に次の部分で構成されています-

  • プログラム名
  • コマンドを使用します
  • 型宣言
  • 一定の宣言
  • 変数宣言
  • 関数宣言
  • 手続き宣言
  • メインプログラムブロック
  • 各ブロック内のステートメントと式
  • Comments

すべてのPascalプログラムには、通常、見出しステートメント、宣言、および実行部分が厳密にこの順序であります。次の形式は、Pascalプログラムの基本的な構文を示しています-

program {name of the program}
uses {comma delimited names of libraries you use}
const {global constant declaration block}
var {global variable declaration block}

function {function declarations, if any}
{ local variables }
begin
...
end;

procedure { procedure declarations, if any}
{ local variables }
begin
...
end;

begin { main program block starts}
...
end. { the end of main program block }

Pascal HelloWorldの例

以下は、「Hello、World!」という単語を出力する単純なPascalコードです。−

program HelloWorld;
uses crt;

(* Here the main program block starts *)
begin
   writeln('Hello, World!');
   readkey;
end.

これにより、次の結果が生成されます-

Hello, World!

上記のプログラムのさまざまな部分を見てみましょう-

  • プログラムの最初の行 program HelloWorld; プログラムの名前を示します。

  • プログラムの2行目 uses crt; はプリプロセッサコマンドであり、実際のコンパイルに進む前にcrtユニットを含めるようコンパイラに指示します。

  • beginステートメントとendステートメントで囲まれた次の行は、メインプログラムブロックです。パスカルのすべてのブロックは、begin ステートメントと endステートメント。ただし、メインプログラムの終了を示すendステートメントの後には、セミコロン(;)ではなくピリオド(。)が続きます。

  • ザ・ begin メインプログラムブロックのステートメントは、プログラムの実行が開始される場所です。

  • 内の行 (*...*) コンパイラによって無視され、追加するために配置されています comment プログラムで。

  • 声明 writeln('Hello, World!');Pascalで使用可能なwriteln関数を使用して、「Hello、World!」というメッセージを表示します。画面に表示されます。

  • 声明 readkey;ユーザーがキーを押すまで表示を一時停止できます。これはcrtユニットの一部です。ユニットはパスカルの図書館のようなものです。

  • 最後のステートメント end. プログラムを終了します。

Pascalプログラムのコンパイルと実行

  • テキストエディタを開き、上記のコードを追加します。

  • ファイルをhello.pasとして保存します

  • コマンドプロンプトを開き、ファイルを保存したディレクトリに移動します。

  • コマンドプロンプトでfpchello.pasと入力し、Enterキーを押してコードをコンパイルします。

  • コードにエラーがない場合、コマンドプロンプトで次の行に移動し、次の行が生成されます。 hello 実行可能ファイルと hello.o オブジェクトファイル。

  • 今、入力します hello コマンドプロンプトでプログラムを実行します。

  • 画面に「HelloWorld」が印刷されているのを確認でき、プログラムはいずれかのキーを押すまで待機します。

$ fpc hello.pas Free Pascal Compiler version 2.6.0 [2011/12/23] for x86_64 Copyright (c) 1993-2011 by Florian Klaempfl and others Target OS: Linux for x86-64 Compiling hello.pas Linking hello 8 lines compiled, 0.1 sec $ ./hello
Hello, World!

無料のpascalコンパイラを確認してください fpc がパスにあり、ソースファイルhello.pasを含むディレクトリで実行していること。

Pascalプログラムの基本構造を見てきましたので、Pascalプログラミング言語の他の基本的な構成要素を理解するのは簡単です。

変数

変数定義は、で始まるブロックに配置されます var キーワードの後に​​、次のように変数の定義が続きます。

var
A_Variable, B_Variable ... : Variable_Type;

Pascal変数は、関数のコード本体の外部で宣言されています。つまり、 begin そして end ペアですが、プロシージャ/関数の定義後、 beginキーワード。グローバル変数の場合、それらはプログラムヘッダーの後に定義されます。

機能/手順

パスカルでは、 procedure 実行される命令のセットであり、戻り値はなく、 functionは戻り値のあるプロシージャです。機能/手順の定義は次のようになります-

Function Func_Name(params...) : Return_Value;
Procedure Proc_Name(params...);

コメント

複数行コメントは、中括弧とアスタリスクで囲まれています(* ... *)。Pascalでは、中括弧{...}で囲まれた1行のコメントを使用できます。

(* This is a multi-line comments
   and it will span multiple lines. *)

{ This is a single line comment in pascal }

大文字と小文字の区別

Pascalは大文字と小文字を区別しない言語です。つまり、どちらの場合でも変数、関数、プロシージャを記述できます。変数A_Variableと同様に、a_variableとA_VARIABLEはPascalでは同じ意味を持ちます。

パスカルステートメント

パスカルプログラムはステートメントで構成されています。各ステートメントは、プログラムの明確なジョブを指定します。これらのジョブには、宣言、割り当て、データの読み取り、データの書き込み、論理的な決定、プログラムフロー制御の転送などがあります。

例-

readln (a, b, c);
s := (a + b + c)/2.0;
area := sqrt(s * (s - a)*(s-b)*(s-c));
writeln(area);

パスカルの予約語

Pascalのステートメントは、予約語と呼ばれる特定のPascalワードを使用して設計されています。たとえば、words、program、input、output、var、real、begin、readline、writeline、endはすべて予約語です。

以下は、Pascalで利用可能な予約語のリストです。

そして アレイ ベギン 場合 const
div 行う 至るまで そうしないと 終わり
ファイル にとって 関数 後藤 もし
ラベル モッド なし ない
または パック 手順 プログラム
記録 繰り返す セットする その後
タイプ まで var 一方

Pascalの文字セットと識別子

Pascal文字セットは次のもので構成されます-

  • すべて大文字(AZ)

  • すべて小文字(az)

  • すべての数字(0〜9)

  • 特殊記号-+ * /:= 、。;。()[] = {} `空白

変数や定数、タイプ、関数、プロシージャ、レコードなどのPascalプログラムのエンティティには、名前または識別子があります。識別子は、文字で始まる文字と数字のシーケンスです。識別子に特別な記号や空白を使用しないでください。

エンティティのデータ型は、エンティティに関連付けられている意味、制約、可能な値、操作、機能、およびストレージのモードを示します。

整数型、実数型、ブール型、および文字型は、標準データ型と呼ばれます。データ型は、スカラー、ポインター、および構造化データ型に分類できます。スカラーデータ型の例は、整数、実数、ブール、文字、サブ範囲、および列挙型です。構造化データ型はスカラー型で構成されています。たとえば、配列、レコード、ファイル、セットなどです。ポインタのデータ型については後で説明します。

Pascalのデータ型

Pascalのデータ型は、次の図に次のように要約できます。

型宣言

型宣言は、識別子のデータ型を宣言するために使用されます。型宣言の構文は次のとおりです。

type-identifier-1, type-identfier-2 = type-specifier;

たとえば、次の宣言では、変数daysとageを整数型、yesとtrueをブール型、nameとcityを文字列型、feesとexpensesを実数型として定義しています。

type
days, age = integer;
yes, true = boolean;
name, city = string;
fees, expenses = real;

整数型

次の表に、ObjectPascalで使用されるストレージサイズと値の範囲を含む標準の整数型の詳細を示します。

タイプ 最小 最大 フォーマット
整数 -2147483648 2147483647 符号付き32ビット
枢機卿 0 4294967295 符号なし32ビット
Shortint -128 127 符号付き8ビット
Smallint -32768 32767 署名された16ビット
ロンギント -2147483648 2147483647 符号付き32ビット
Int64 -2 ^ 63 2 ^ 63-1 署名された64ビット
バイト 0 255 符号なし8ビット
0 65535 符号なし16ビット
ロングワード 0 4294967295 符号なし32ビット

定数

定数を使用すると、プログラムが読みやすくなり、プログラムの最初の1か所に特別な量を保持するのに役立ちます。Pascalでは、数値、論理、文字列、および文字の定数を使用できます。プログラムの宣言部分で定数を宣言するには、const 宣言。

定数型宣言の構文は次のとおりです-

const
Identifier = contant_value;

以下は定数宣言のいくつかの例です-

VELOCITY_LIGHT = 3.0E=10;
PIE = 3.141592;
NAME = 'Stuart Little';
CHOICE = yes;
OPERATOR = '+';

すべての定数宣言は、変数宣言の前に指定する必要があります。

列挙型

列挙データ型はユーザー定義のデータ型です。リストに値を指定できます。列挙型のデータ型では、代入演算子と関係演算子のみが許可されます。列挙型データ型は次のように宣言できます-

type
enum-identifier = (item1, item2, item3, ... )

以下は、列挙型宣言のいくつかの例です-

type
SUMMER = (April, May, June, July, September);
COLORS = (Red, Green, Blue, Yellow, Magenta, Cyan, Black, White);
TRANSPORT = (Bus, Train, Airplane, Ship);

列挙型のドメインにアイテムがリストされる順序は、アイテムの順序を定義します。たとえば、列挙型SUMMERでは、4月が5月より前になり、5月が6月より前になります。列挙型識別子のドメインは、数値定数または文字定数で構成することはできません。

サブレンジタイプ

サブレンジタイプを使用すると、変数は特定の範囲内にある値を想定できます。たとえば、有権者の年齢が18〜100の場合、ageという名前の変数を次のように宣言できます。

var
age: 18 ... 100;

次のセクションでは、変数宣言について詳しく見ていきます。型宣言を使用してサブ範囲型を定義することもできます。サブレンジタイプを宣言するための構文は次のとおりです-

type
subrange-identifier = lower-limit ... upper-limit;

以下は、サブレンジ型宣言のいくつかの例です-

const
P = 18;
Q = 90;
type
Number = 1 ... 100;
Value = P ... Q;

サブレンジタイプは、すでに定義されている列挙型のサブセットから作成できます。たとえば、-

type
months = (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec);
Summer = Apr ... Aug;
Winter = Oct ... Dec;

変数は、プログラムが操作できるストレージ領域に付けられた名前に他なりません。Pascalの各変数には特定のタイプがあり、変数のメモリのサイズとレイアウトを決定します。そのメモリ内に保存できる値の範囲。変数に適用できる一連の操作。

変数の名前は、文字、数字、および下線文字で構成できます。文字またはアンダースコアで始まる必要があります。パスカルはnot case-sensitive、したがって、大文字と小文字はここでは同じ意味です。前の章で説明した基本タイプに基づいて、次の基本変数タイプがあります-

Pascalの基本変数

シニア番号 タイプと説明
1

Character

通常、1オクテット(1バイト)。これは整数型です。

2

Integer

マシンの整数の最も自然なサイズ。

3

Real

単精度浮動小数点値。

4

Boolean

真または偽の論理値を指定します。これも整数型です。

5

Enumerated

ユーザー定義リストを指定します。

6

Subrange

値が範囲内にある変数を表します。

7

String

文字の配列を格納します。

Pascalプログラミング言語では、他のさまざまなタイプの変数を定義することもできます。これについては、ポインター、配列、レコード、セット、ファイルなどの後続の章で説明します。この章では、基本的な変数タイプのみを学習します。

Pascalでの変数宣言

Pascalプログラムで使用する前に、すべての変数を宣言する必要があります。すべての変数宣言の後にvarキーワードが続きます。宣言は変数のリストを指定し、その後にコロン(:)とタイプが続きます。変数宣言の構文は次のとおりです。

var
variable_list : type;

ここで、typeは、文字、整数、実数、ブール値、または任意のユーザー定義データ型などを含む有効なPascalデータ型である必要があり、variable_listは、コンマで区切られた1つ以上の識別子名で構成できます。いくつかの有効な変数宣言をここに示します-

var
age, weekdays : integer;
taxrate, net_income: real;
choice, isready: boolean;
initials, grade: char;
name, surname : string;

前のチュートリアルでは、Pascalで型を宣言できることを説明しました。タイプは、名前または識別子で識別できます。このタイプは、そのタイプの変数を定義するために使用できます。例えば、

type
days, age = integer;
yes, true = boolean;
name, city = string;
fees, expenses = real;

これで、そのように定義された型を変数宣言で使用できるようになりました-

var
weekdays, holidays : days;
choice: yes;
student_name, emp_name : name;
capital: city;
cost: expenses;

宣言とvar宣言の違いに注意してください。型宣言は、整数、実数などの型のカテゴリまたはクラスを示しますが、変数指定は、変数が取ることができる値の型を示します。Pascalの宣言とCのtypedefを比較できます。最も重要なことは、変数名は、変数の値が格納されるメモリの場所を参照することです。これは型宣言ではそうではありません。

Pascalでの変数の初期化

変数には、コロンと等号の後に定数式が続く値が割り当てられます。値を割り当てる一般的な形式は次のとおりです。

variable_name := value;

デフォルトでは、Pascalの変数はゼロで初期化されません。ゴミの値が含まれている場合があります。したがって、プログラム内の変数を初期化することをお勧めします。変数は、宣言で初期化(初期値を割り当てる)できます。初期化の後にはvar キーワードと初期化の構文は次のとおりです-

var
variable_name : type = value;

いくつかの例は-

age: integer = 15;
taxrate: real = 0.5;
grade: char = 'A';
name: string = 'John Smith';

これまでに説明したさまざまなタイプの変数を利用する例を見てみましょう。

program Greetings;
const
message = ' Welcome to the world of Pascal ';

type
name = string;
var
firstname, surname: name;

begin
   writeln('Please enter your first name: ');
   readln(firstname);
   
   writeln('Please enter your surname: ');
   readln(surname);
   
   writeln;
   writeln(message, ' ', firstname, ' ', surname);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Please enter your first name:
John
Please enter your surname:
Smith
Welcome to the world of Pascal John Smith

列挙型変数

整数、実数、ブール値などの単純な変数タイプの使用方法を見てきました。ここで、列挙型の変数を見てみましょう。これは、次のように定義できます。

var
var1, var2, ...  : enum-identifier;

列挙型を宣言したら、その型の変数を宣言できます。例えば、

type
months = (January, February, March, April, May, June, July, August, September, October, November, December);
Var
m: months;
...
M := January;

次の例は、概念を示しています-

program exEnumeration;
type
beverage = (coffee, tea, milk, water, coke, limejuice);

var
drink:beverage;

begin
   writeln('Which drink do you want?');
   drink := limejuice;
   
   writeln('You can drink ', drink);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Which drink do you want?
You can drink limejuice

サブレンジ変数

サブレンジ変数は次のように宣言されます-

var
subrange-name : lowerlim ... uperlim;

サブレンジ変数の例は次のとおりです。

var
marks: 1 ... 100;
grade: 'A' ... 'E';
age: 1 ... 25;

次のプログラムは、概念を示しています-

program exSubrange;
var
marks: 1 .. 100;
grade: 'A' .. 'E';

begin
   writeln( 'Enter your marks(1 - 100): ');
   readln(marks);
   
   writeln( 'Enter your grade(A - E): ');
   readln(grade);
   
   writeln('Marks: ' , marks, ' Grade: ', grade);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Enter your marks(1 - 100): 
100
Enter your grade(A - E):
A
Marks: 100 Grade: A

定数は、プログラムの実行中に変更されないままのエンティティです。Pascalでは、次のタイプの定数のみを宣言できます-

  • 通常のタイプ
  • タイプを設定する
  • ポインタタイプ(ただし、許可される値はNilのみです)。
  • 実際のタイプ
  • Char
  • String

定数の宣言

定数を宣言するための構文は次のとおりです-

const
identifier = constant_value;

次の表に、いくつかの有効な定数宣言の例を示します。

Real type constant

シニア番号 定数タイプと例
1

Ordinal(Integer)type constant

valid_age = 21;

2

Set type constant

母音=(A、E、I、O、U)のセット;

3

Pointer type constant

P = NIL;

4

e = 2.7182818;

speed_light = 3.0E + 10;

5

Character type constant

演算子= '+';

6

String type constant

大統領= 'ジョニーデップ';

次の例は、概念を示しています-

program const_circle (input,output);
const
PI = 3.141592654;

var
r, d, c : real;   {variable declaration: radius, dia, circumference}

begin
   writeln('Enter the radius of the circle');
   readln(r);
   
   d := 2 * r;
   c :=  PI * d;
   writeln('The circumference of the circle is ',c:7:2);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Enter the radius of the circle
23
The circumference of the circle is 144.51

プログラムの出力ステートメントのフォーマットを確認してください。変数cは、小数点以下7桁と2桁の合計桁数でフォーマットされます。Pascalでは、数値変数を使用したこのような出力フォーマットが可能です。

演算子は、特定の数学的または論理的操作を実行するようにコンパイラーに指示する記号です。Pascalでは、次のタイプの演算子を使用できます-

  • 算術演算子
  • 関係演算子
  • ブール演算子
  • ビット演算子
  • 演算子を設定します
  • 文字列演算子

算術演算子、リレーショナル演算子、ブール演算子、およびビット演算子について1つずつ説明します。集合演算子と文字列操作については後で説明します。

算術演算子

次の表は、Pascalでサポートされているすべての算術演算子を示しています。変数を想定A 10と変数を保持します B 20を保持し、次に−

例を表示

オペレーター 説明
+ 2つのオペランドを追加します A + Bは30を与えます
- 最初のオペランドから2番目のオペランドを減算します A-Bは-10を与えます
* 両方のオペランドを乗算します A * Bは200を与えます
/ 分子を分母で割る B / Aは2を与えます
モジュラス演算子と整数除算後の余り B%Aは0を与えます

関係演算子

次の表は、Pascalでサポートされているすべての関係演算子を示しています。変数を想定A 10と変数を保持します B 20を保持し、次に−

例を表示

オペレーター 説明
= 2つのオペランドの値が等しいかどうかをチェックし、等しい場合は条件が真になります。 (A = B)は真ではありません。
<> 2つのオペランドの値が等しいかどうかをチェックし、値が等しくない場合は、条件が真になります。 (A <> B)は真です。
>> 左のオペランドの値が右のオペランドの値より大きいかどうかをチェックし、大きい場合は条件が真になります。 (A> B)は正しくありません。
< 左のオペランドの値が右のオペランドの値よりも小さいかどうかをチェックし、小さい場合は条件が真になります。 (A <B)は真です。
> = 左のオペランドの値が右のオペランドの値以上であるかどうかをチェックし、そうである場合は、条件が真になります。 (A> = B)は正しくありません。
<= 左のオペランドの値が右のオペランドの値以下であるかどうかをチェックし、そうである場合は、条件が真になります。 (A <= B)は真です。

ブール演算子

次の表は、Pascal言語でサポートされているすべてのブール演算子を示しています。これらの演算子はすべてブールオペランドで機能し、ブール結果を生成します。変数を想定A 真で可変である B falseを保持し、その後−

例を表示

オペレーター 説明
そして ブールAND演算子と呼ばれます。両方のオペランドが真の場合、条件は真になります。 (AとB)は誤りです。
その後 AND演算子に似ていますが、コンパイラが論理式を評価する順序を保証します。左から右および右のオペランドは、必要な場合にのみ評価されます。 (A、次にB)は偽です。
または ブールOR演算子と呼ばれます。2つのオペランドのいずれかが真の場合、条件は真になります。 (AまたはB)は真です。
またはそうでなければ これはブールORに似ていますが、コンパイラが論理式を評価する順序を保証します。左から右および右のオペランドは、必要な場合にのみ評価されます。 (AまたはB)は真です。
ない ブールNOT演算子と呼ばれます。オペランドの論理状態を逆にするために使用されます。条件がtrueの場合、LogicalNOT演算子はそれをfalseにします。 (AとB)は真ではありません。

ビット演算子

ビット単位の演算子はビットを処理し、ビットごとの演算を実行します。これらの演算子はすべて整数オペランドで機能し、整数の結果を生成します。ビット単位と(&)、ビット単位または(|)、およびビット単位ではない(〜)の真理値表は次のとおりです。

p q p&q p | q 〜p 〜q
0 0 0 0 1 1
0 1 0 1 1 0
1 1 1 1 0 0
1 0 0 1 0 1

A = 60の場合を想定します。およびB = 13; 現在、バイナリ形式では次のようになります-

A = 0011 1100

B = 0000 1101

-----------------

A&B = 0000 1100

A ^ B = 0011 0001

〜A = 1100 0011

Pascalでサポートされているビット演算子を次の表に示します。変数Aが60を保持し、変数Bが13を保持すると仮定すると、次のようになります。

例を表示

オペレーター 説明
バイナリAND演算子は、両方のオペランドに存在する場合、結果にビットをコピーします。 (A&B)は12、つまり00001100を与えます
| バイナリOR演算子は、いずれかのオペランドに存在する場合、ビットをコピーします。 (A | B)は61を与えます。これは00111101です。
バイナリOR演算子は、いずれかのオペランドに存在する場合、ビットをコピーします。それと同じ| オペレーター。 (A!B)は61を返します。これは00111101です。
Binary Ones Complement Operatorは単項であり、ビットを「反転」させる効果があります。 (〜A)は-61を返します。これは、符号付き2進数のため、2の補数形式の11000011です。
<< バイナリ左シフト演算子。左のオペランドの値は、右のオペランドで指定されたビット数だけ左に移動します。 << 2は240、つまり11110000になります
>> バイナリ右シフト演算子。左のオペランドの値は、右のオペランドで指定されたビット数だけ右に移動します。 >> 2は15になります。これは00001111です。

Pascalの実装が異なれば、ビット演算子が異なることに注意してください。ただし、ここで使用したコンパイラであるFree Pascalは、次のビット演算子をサポートしています。

演算子 操作
ない ビット単位ではありません
そして ビットごとのAND
または ビットごとのOR
xor ビット単位の排他的論理和
shl 左にビット単位でシフト
shr ビット単位で右にシフト
<< 左にビット単位でシフト
>> ビット単位で右にシフト

パスカルでのオペレーターの優先順位

演算子の優先順位は、式内の用語のグループ化を決定します。これは、式の評価方法に影響します。特定の演算子は他の演算子よりも優先されます。たとえば、乗算演算子は加算演算子よりも優先されます。

たとえば、x = 7 + 3 * 2; ここでは、演算子*の優先順位が+よりも高いため、xには20ではなく13が割り当てられます。したがって、最初に3 * 2が乗算され、次に7に加算されます。

ここでは、優先順位が最も高い演算子がテーブルの上部に表示され、優先順位が最も低い演算子が下部に表示されます。式内では、優先順位の高い演算子が最初に評価されます。

例を表示

オペレーター 優先順位
〜、ではなく、 最高
*、/、div、mod、および、&
|、!、+、-、または、
=、<>、<、<=、>、> =、
またはそれ以外の場合、 最低

意思決定構造では、プログラマーは、プログラムによって評価またはテストされる1つ以上の条件と、条件が真であると判断された場合に実行される1つまたは複数のステートメント、およびオプションで、条件が真である場合に実行される他のステートメントを指定する必要があります。 falseと判断されます。

以下は、ほとんどのプログラミング言語に見られる典型的な意思決定構造の一般的な形式です。

Pascalプログラミング言語は、次のタイプの意思決定ステートメントを提供します。詳細を確認するには、次のリンクをクリックしてください。

シニア番号 ステートメントと説明
1 if-thenステートメント

アン if - then statement ブール式とそれに続く1つ以上のステートメントで構成されます。

2 If-then-elseステートメント

アン if - then statement オプションの後に続くことができます else statement、ブール式がfalseの場合に実行されます。

3 ネストされたifステートメント

あなたは1つを使用することができます if または else if 別の内部のステートメント if または else if ステートメント。

4 ケースステートメント

A case ステートメントを使用すると、値のリストに対して変数が等しいかどうかをテストできます。

5 ケース-elseステートメント

それはに似ています if-then-else ステートメント。ここでは、else 用語は次の case statement

6 ネストされたcaseステートメント

あなたは1つを使用することができます case 別の内部のステートメント case ステートメント。

コードのブロックを数回実行する必要がある場合があります。一般に、ステートメントは順番に実行されます。関数の最初のステートメントが最初に実行され、次に2番目のステートメントが実行されます。

プログラミング言語は、より複雑な実行パスを可能にするさまざまな制御構造を提供します。

ループステートメントを使用すると、ステートメントまたはステートメントのグループを複数回実行できます。以下は、ほとんどのプログラミング言語でのループステートメントの一般的な形式です。

Pascalプログラミング言語は、ループ要件を処理するために次のタイプのループ構造を提供します。詳細を確認するには、次のリンクをクリックしてください。

シニア番号 ループの種類と説明
1 while-doループ

指定された条件が真である間、ステートメントまたはステートメントのグループを繰り返します。ループ本体を実行する前に条件をテストします。

2 for-doループ

一連のステートメントを複数回実行し、ループ変数を管理するコードを省略します。

3 繰り返し-ループまで

whileステートメントと同様ですが、ループ本体の最後で条件をテストする点が異なります。

4 ネストされたループ

1つ以上のループを別のwhile、for、またはループまで繰り返すことができます。

ループ制御ステートメント

ループ制御ステートメントは、実行を通常のシーケンスから変更します。実行がスコープを離れると、そのスコープで作成されたすべての自動オブジェクトが破棄されます。

Pascalは、次の制御ステートメントをサポートしています。詳細を確認するには、次のリンクをクリックしてください。

シニア番号 制御ステートメントと説明
1 breakステートメント

を終了します loop または case ステートメントを実行し、ループまたはケースステートメントの直後のステートメントに実行を転送します。

2 ステートメントを続ける

ループに本体の残りの部分をスキップさせ、繰り返す前にすぐにその状態を再テストします。

3 gotoステートメント

ラベル付きステートメントに制御を移します。プログラムでgotoステートメントを使用することはお勧めしませんが。

サブプログラム

サブプログラムは、特定のタスクを実行するプログラムユニット/モジュールです。これらのサブプログラムを組み合わせて、より大きなプログラムを形成します。これは基本的に「モジュラーデザイン」と呼ばれます。サブプログラムは、呼び出し側プログラムと呼ばれるサブプログラム/プログラムによって呼び出すことができます。

Pascalは2種類のサブプログラムを提供します-

  • Functions −これらのサブプログラムは単一の値を返します。

  • Procedures −これらのサブプログラムは値を直接返しません。

関数

A function一緒にタスクを実行するステートメントのグループです。すべてのPascalプログラムには、プログラム自体である少なくとも1つの関数があり、最も些細なプログラムはすべて、追加の関数を定義できます。

機能 declaration関数の名前、戻り値の型、およびパラメーターについてコンパイラーに通知します。機能definition 関数の実際の本体を提供します。

Pascal標準ライブラリは、プログラムが呼び出すことができる多数の組み込み関数を提供します。たとえば、関数AppendStr() 2つの文字列、関数を追加します New() 変数やその他多くの関数にメモリを動的に割り当てます。

関数の定義

パスカルでは、 functionfunctionキーワードを使用して定義されます。関数定義の一般的な形式は次のとおりです。

function name(argument(s): type1; argument(s): type2; ...): function_type;
local declarations;

begin
   ...
   < statements >
   ...
   name:= expression;
end;

Pascalの関数定義は、関数で構成されています header、 地元 declarations と機能 body。関数ヘッダーは、キーワード関数とname関数に与えられます。これが関数のすべての部分です-

  • Arguments−引数は、呼び出し側プログラムと関数IDの間のリンクを確立し、仮パラメーターとも呼ばれます。パラメータはプレースホルダーのようなものです。関数が呼び出されると、パラメーターに値を渡します。この値は、実際のパラメーターまたは引数と呼ばれます。パラメータリストは、関数のパラメータのタイプ、順序、および数を参照します。このような正式なパラメータの使用はオプションです。これらのパラメーターには、標準データ型、ユーザー定義データ型、またはサブ範囲データ型があります。

    関数ステートメントに表示される仮パラメーターのリストは、単純変数または添え字付き変数、配列または構造化変数、またはサブプログラムである可能性があります。

  • Return Type−すべての関数は値を返す必要があるため、すべての関数にタイプを割り当てる必要があります。ザ・function-type関数が返す値のデータ型です。標準のユーザー定義のスカラー型またはサブレンジ型の場合がありますが、構造化型にすることはできません。

  • Local declarations −ローカル宣言とは、ラベル、定数、変数、関数、およびプロシージャの宣言を指します。これらは、関数の本体にのみ適用されます。

  • Function Body−関数本体には、関数の機能を定義するステートメントのコレクションが含まれています。予約語のbeginとendで常に囲む必要があります。これは、すべての計算が行われる関数の一部です。次のタイプの代入ステートメントが必要です-name := expression;関数名に値を割り当てる関数本体内。この値は、関数の実行時に返されます。本文の最後のステートメントは、終了ステートメントである必要があります。

以下は、pascalで関数を定義する方法を示す例です。

(* function returning the max between two numbers *)
function max(num1, num2: integer): integer;

var
   (* local variable declaration *)
   result: integer;

begin
   if (num1 > num2) then
      result := num1
   
   else
      result := num2;
   max := result;
end;

関数宣言

機能 declaration関数名と関数の呼び出し方法についてコンパイラーに指示します。関数の実際の本体は個別に定義できます。

関数宣言には次の部分があります-

function name(argument(s): type1; argument(s): type2; ...): function_type;

上記で定義した関数max()の場合、以下は関数宣言です。

function max(num1, num2: integer): integer;

あるソースファイルで関数を定義し、その関数を別のファイルで呼び出す場合は、関数宣言が必要です。このような場合、関数を呼び出すファイルの先頭で関数を宣言する必要があります。

関数の呼び出し

関数を作成するときに、関数が何をしなければならないかを定義します。関数を使用するには、その関数を呼び出して定義されたタスクを実行する必要があります。プログラムが関数を呼び出すと、プログラムの制御は呼び出された関数に移されます。呼び出された関数は定義されたタスクを実行し、そのreturnステートメントが実行されるか、最後のendステートメントに到達すると、プログラム制御をメインプログラムに戻します。

関数を呼び出すには、必要なパラメーターを関数名と一緒に渡す必要があります。関数が値を返す場合は、戻り値を保存できます。以下は、使用法を示す簡単な例です-

program exFunction;
var
   a, b, ret : integer;

(*function definition *)
function max(num1, num2: integer): integer;
var
   (* local variable declaration *)
   result: integer;

begin
   if (num1 > num2) then
      result := num1
   
   else
      result := num2;
   max := result;
end;

begin
   a := 100;
   b := 200;
   (* calling a function to get max value *)
   ret := max(a, b);
   
   writeln( 'Max value is : ', ret );
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Max value is : 200

Procedures は、単一の値を返す代わりに、結果のグループを取得できるようにするサブプログラムです。

手順の定義

Pascalでは、プロシージャは procedureキーワード。プロシージャ定義の一般的な形式は次のとおりです。

procedure name(argument(s): type1, argument(s): type 2, ... );
   < local declarations >
begin
   < procedure body >
end;

手順 definition パスカルでは、 header、 地元 declarationsbody手順の。プロシージャヘッダーはキーワードで構成されますprocedureプロシージャに付けられた名前。手順のすべての部分は次のとおりです-

  • Arguments−引数は、呼び出し側プログラムとプロシージャーIDの間のリンクを確立し、仮パラメーターとも呼ばれます。プロシージャ内の引数のルールは、関数のルールと同じです。

  • Local declarations −ローカル宣言は、ラベル、定数、変数、関数、およびプロシージャの宣言を指します。これらは、プロシージャの本体にのみ適用されます。

  • Procedure Body−プロシージャ本体には、プロシージャの機能を定義するステートメントのコレクションが含まれています。予約語のbeginとendで常に囲む必要があります。これは、すべての計算が行われる手順の一部です。

以下は、findMin()と呼ばれるプロシージャのソースコードです。この手順では、4つのパラメーターx、y、z、およびmを取り、最初の3つの変数の最小値をmという名前の変数に格納します。変数mは渡されますreference (参照による引数の受け渡しについては、少し後で説明します)−

procedure findMin(x, y, z: integer; var m: integer); 
(* Finds the minimum of the 3 values *)

begin
   if x < y then
      m := x
   else
      m := y;
   
   if z <m then
      m := z;
end; { end of procedure findMin }

手順の宣言

手順 declarationプロシージャ名とプロシージャの呼び出し方法についてコンパイラに通知します。手順の実際の本体は個別に定義できます。

プロシージャ宣言の構文は次のとおりです。

procedure name(argument(s): type1, argument(s): type 2, ... );

注意してください name of the procedure is not associated with any type。上記で定義されたプロシージャfindMin()の場合、以下は宣言です。

procedure findMin(x, y, z: integer; var m: integer);

プロシージャの呼び出し

プロシージャを作成するときに、プロシージャが実行する必要があることを定義します。プロシージャを使用するには、そのプロシージャを呼び出して、定義されたタスクを実行する必要があります。プログラムがプロシージャを呼び出すと、プログラム制御は呼び出されたプロシージャに移されます。呼び出されたプロシージャは、定義されたタスクを実行し、最後の終了ステートメントに達すると、制御を呼び出し側プログラムに戻します。

プロシージャを呼び出すには、以下に示すように、プロシージャ名とともに必要なパラメータを渡すだけです。

program exProcedure;
var
   a, b, c,  min: integer;
procedure findMin(x, y, z: integer; var m: integer); 
(* Finds the minimum of the 3 values *)

begin
   if x < y then
      m:= x
   else
      m:= y;
   
   if z < m then
      m:= z;
end; { end of procedure findMin }  

begin
   writeln(' Enter three numbers: ');
   readln( a, b, c);
   findMin(a, b, c, min); (* Procedure call *)
   
   writeln(' Minimum: ', min);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Enter three numbers:
89 45 67
Minimum: 45

再帰的サブプログラム

プログラムまたはサブプログラムが別のサブプログラムを呼び出す可能性があることを確認しました。サブプログラムがそれ自体を呼び出すとき、それは再帰呼び出しと呼ばれ、プロセスは再帰と呼ばれます。

概念を説明するために、数値の階乗を計算してみましょう。数nの階乗は次のように定義されます-

n! = n*(n-1)!
   = n*(n-1)*(n-2)!
      ...
   = n*(n-1)*(n-2)*(n-3)... 1

次のプログラムは、それ自体を再帰的に呼び出すことにより、指定された数値の階乗を計算します。

program exRecursion;
var
   num, f: integer;
function fact(x: integer): integer; (* calculates factorial of x - x! *)

begin
   if x=0 then
      fact := 1
   else
      fact := x * fact(x-1); (* recursive call *)
end; { end of function fact}

begin
   writeln(' Enter a number: ');
   readln(num);
   f := fact(num);
   
   writeln(' Factorial ', num, ' is: ' , f);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Enter a number:
5
Factorial 5 is: 120

以下は、を生成する別の例です。 Fibonacci Series を使用して指定された番号に対して recursive 関数-

program recursiveFibonacci;
var
   i: integer;
function fibonacci(n: integer): integer;

begin
   if n=1 then
      fibonacci := 0
   
   else if n=2 then
      fibonacci := 1
   
   else
      fibonacci := fibonacci(n-1) + fibonacci(n-2);
end; 

begin
   for i:= 1 to 10 do
   
   write(fibonacci (i), '  ');
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

0 1 1 2	3 5 8 13 21 34

サブプログラムの引数

サブプログラムの場合(function or procedure)引数を使用する場合は、引数の値を受け入れる変数を宣言する必要があります。これらの変数は、formal parameters サブプログラムの。

仮パラメータは、サブプログラム内の他のローカル変数と同様に動作し、サブプログラムへの入力時に作成され、終了時に破棄されます。

サブプログラムの呼び出し中に、引数をサブプログラムに渡す方法は2つあります。

シニア番号 通話の種類と説明
1 値で呼び出す

このメソッドは、引数の実際の値をサブプログラムの仮パラメーターにコピーします。この場合、サブプログラム内のパラメーターに加えられた変更は、引数に影響を与えません。

2 参照による呼び出し

このメソッドは、引数のアドレスを仮パラメーターにコピーします。サブプログラム内では、アドレスは呼び出しで使用される実際の引数にアクセスするために使用されます。これは、パラメータに加えられた変更が引数に影響を与えることを意味します。

デフォルトでは、Pascalは call by value引数を渡す。一般に、これは、サブプログラム内のコードが、サブプログラムの呼び出しに使用される引数を変更できないことを意味します。「Pascal-関数」の章で使用したサンプルプログラムは、max()という名前の関数を使用して呼び出しました。call by value

一方、ここで提供されているサンプルプログラム(exProcedure)は、を使用してプロシージャfindMin()を呼び出します。call by reference

プログラミングのスコープは、定義された変数が存在する可能性があり、その変数を超えてアクセスできないプログラムの領域です。Pascalプログラミング言語で変数を宣言できる場所は3つあります-

  • ローカル変数と呼ばれるサブプログラムまたはブロック内

  • グローバル変数と呼ばれるすべてのサブプログラムの外

  • 仮パラメータと呼ばれるサブプログラムパラメータの定義

何であるかを説明しましょう local そして global 変数と仮パラメータ。

ローカル変数

サブプログラムまたはブロック内で宣言される変数は、ローカル変数と呼ばれます。それらは、そのサブプログラムまたはコードのブロック内にあるステートメントによってのみ使用できます。ローカル変数は、それ自体の外部のサブプログラムには認識されません。以下は、ローカル変数を使用した例です。ここで、すべての変数ab、およびcは、exLocalという名前のプログラムに対してローカルです

program exLocal; 
var
   a, b, c: integer;

begin
   (* actual initialization *)
   a := 10;
   b := 20;
   c := a + b;
   
   writeln('value of a = ', a , ' b =  ',  b, ' and c = ', c);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

value of a = 10 b = 20 c = 30

ここで、プログラムをもう少し拡張して、displayという名前のプロシージャを作成しましょう。このプロシージャは、独自の変数abcのセットを持ち、プログラムexLocalから直接それらの値を表示します。

program exLocal;
var
   a, b, c: integer;
procedure display;

var
   a, b, c: integer;
begin
   (* local variables *)
   a := 10;
   b := 20;
   c := a + b;
   
   writeln('Winthin the procedure display');
   writeln('value of a = ', a , ' b =  ',  b, ' and c = ', c);
end;

begin
   a:= 100;
   b:= 200;
   c:= a + b;
   
   writeln('Winthin the program exlocal');
   writeln('value of a = ', a , ' b =  ',  b, ' and c = ', c);
   display();
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Within the program exlocal
value of a = 100 b = 200 c = 300
Within the procedure display
value of a = 10 b = 20 c = 30

グローバル変数

グローバル変数は、関数の外部、通常はプログラムの上で定義されます。グローバル変数は、プログラムの存続期間を通じてその値を保持し、プログラム用に定義された任意の関数内でアクセスできます。

A global変数には任意の関数からアクセスできます。つまり、グローバル変数は、宣言後、プログラム全体で使用できます。以下は使用例ですglobal そして local 変数-

program exGlobal;
var
   a, b, c: integer;
procedure display;
var
   x, y, z: integer;

begin
   (* local variables *)
   x := 10;
   y := 20;
   z := x + y;
   
   (*global variables *)
   a := 30;
   b:= 40;
   c:= a + b;
   
   writeln('Winthin the procedure display');
   writeln(' Displaying the global variables a, b, and c');
   
   writeln('value of a = ', a , ' b =  ',  b, ' and c = ', c);
   writeln('Displaying the local variables x, y, and z');
   
   writeln('value of x = ', x , ' y =  ',  y, ' and z = ', z);
end;

begin
   a:= 100;
   b:= 200;
   c:= 300;
   
   writeln('Winthin the program exlocal');
   writeln('value of a = ', a , ' b =  ',  b, ' and c = ', c);
   
   display();
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Within the program exlocal
value of a = 100 b = 200 c = 300
Within the procedure display
Displaying the global variables a, b, and c
value of a = 30 b = 40 c = 70
Displaying the local variables x, y, and z
value of x = 10 y = 20 z = 30

プロシージャdisplayは、変数a、b、およびcにアクセスできることに注意してください。これらは、表示に関するグローバル変数であり、それ自体のローカル変数でもあります。プログラムはローカル変数とグローバル変数に同じ名前を付けることができますが、関数内のローカル変数の値が優先されます。

前の例を少し変更してみましょう。ここで、プロシージャ表示のローカル変数abc −と同じ名前になります。

program exGlobal;
var
   a, b, c: integer;
procedure display;

var
   a, b, c: integer;

begin
   (* local variables *)
   a := 10;
   b := 20;
   c := a + b;
   
   writeln('Winthin the procedure display');
   writeln(' Displaying the global variables a, b, and c');
   
   writeln('value of a = ', a , ' b =  ',  b, ' and c = ', c);
   writeln('Displaying the local variables a, b, and c');
   
   writeln('value of a = ', a , ' b =  ',  b, ' and c = ', c);
end;

begin
   a:= 100;
   b:= 200;
   c:= 300;
   
   writeln('Winthin the program exlocal');
   writeln('value of a = ', a , ' b =  ',  b, ' and c = ', c);   
   
   display();
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Within the program exlocal
value of a = 100 b = 200 c = 300
Within the procedure display
Displaying the global variables a, b, and c
value of a = 10 b = 20 c = 30
Displaying the local variables a, b, and c
value of a = 10 b = 20 c = 30

Pascalの文字列は、実際にはオプションのサイズ指定を持つ文字のシーケンスです。文字は、数字、文字、空白、特殊文字、またはすべての組み合わせにすることができます。Extended Pascalは、システムと実装に応じて、さまざまなタイプの文字列オブジェクトを提供します。プログラムで使用されるより一般的なタイプの文字列について説明します。

文字列はさまざまな方法で定義できます-

  • Character arrays −これは、一重引用符で囲まれた0個以上のバイトサイズの文字のシーケンスである文字列です。

  • String variables − TurboPascalで定義されているString型の変数。

  • Short strings −サイズ指定の文字列型の変数。

  • Null terminated strings −の変数 pchar タイプ。

  • AnsiStrings − Ansistringは、長さの制限がない文字列です。

Pascalは、文字列演算子(+)を1つだけ提供します。

次のプログラムは、最初の4種類の文字列を出力します。次の例ではAnsiStringsを使用します。

program exString;
var
   greetings: string;
   name: packed array [1..10] of char;
   organisation: string[10];
   message: pchar;

begin
   greetings := 'Hello ';
   message := 'Good Day!';
   
   writeln('Please Enter your Name');
   readln(name);
   
   writeln('Please Enter the name of your Organisation');
   readln(organisation);
   
   writeln(greetings, name, ' from ', organisation);
   writeln(message); 
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Please Enter your Name
John Smith
Please Enter the name of your Organisation
Infotech
Hello John Smith from Infotech

次の例では、さらにいくつかの関数を使用しています。見てみましょう。

program exString;
uses sysutils;
var
   str1, str2, str3 : ansistring;
   str4: string;
   len: integer;

begin
   str1 := 'Hello ';
   str2 := 'There!';
   
   (* copy str1 into str3 *)
   str3 := str1;
   writeln('appendstr( str3, str1) :  ', str3 );
   
   (* concatenates str1 and str2 *)
   appendstr( str1, str2);
   writeln( 'appendstr( str1, str2) ' , str1 );
   str4 := str1 + str2;
   writeln('Now str4 is: ', str4);
   
   (* total lenghth of str4 after concatenation  *)
   len := byte(str4[0]);
   writeln('Length of the final string str4: ', len); 
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

appendstr( str3, str1) : Hello
appendstr( str1, str2) : Hello There!
Now str4 is: Hello There! There!
Length of the final string str4: 18

Pascal文字列の関数とプロシージャ

Pascalは、文字列を操作するさまざまな関数とプロシージャをサポートしています。これらのサブプログラムは、実装ごとに異なります。ここでは、FreePascalが提供するさまざまな文字列操作サブプログラムをリストしています。

シニア番号 機能と目的
1

function AnsiCompareStr(const S1: ; const S2:):Integer;

2つの文字列を比較します

2

function AnsiCompareText(const S1: ; const S2:):Integer;

大文字と小文字を区別せずに2つの文字列を比較します

3

function AnsiExtractQuotedStr(var Src: PChar; Quote: Char):;

文字列から引用符を削除します

4

function AnsiLastChar(const S:):PChar;

文字列の最後の文字を取得します

5

function AnsiLowerCase(const s:):

文字列をすべて小文字に変換します

6

function AnsiQuotedStr(const S: ; Quote: Char):;

文字列を引用します

7

function AnsiStrComp(S1: PChar;S2: PChar):Integer;

大文字と小文字を区別して文字列を比較します

8

function AnsiStrIComp(S1: PChar; S2: PChar):Integer;

大文字と小文字を区別せずに文字列を比較します

9

function AnsiStrLComp(S1: PChar; S2: PChar; MaxLen: Cardinal):Integer;

文字列のL文字を大文字と小文字を区別して比較します

10

function AnsiStrLIComp(S1: PChar; S2: PChar; MaxLen: Cardinal):Integer;

大文字と小文字を区別しない文字列のL文字を比較します

11

function AnsiStrLastChar(Str: PChar):PChar;

文字列の最後の文字を取得します

12

function AnsiStrLower(Str: PChar):PChar;

文字列をすべて小文字に変換します

13

function AnsiStrUpper(Str: PChar):PChar;

文字列をすべて大文字に変換します

14

function AnsiUpperCase(const s:):;

文字列をすべて大文字に変換します

15

procedure AppendStr(var Dest: ; const S:);

2つの文字列を追加します

16

procedure AssignStr(var P: PString; const S:);

ヒープ上の文字列の値を割り当てます

17

function CompareStr(const S1: ; const S2:):Integer; overload;

大文字と小文字を区別する2つの文字列を比較します

18

function CompareText(const S1: ; const S2:):Integer;

大文字と小文字を区別しない2つの文字列を比較します

19 procedure DisposeStr(S: PString); overload;

ヒープから文字列を削除します

20

procedure DisposeStr(S: PShortString); overload;

ヒープから文字列を削除します

21

function IsValidIdent( const Ident:):Boolean;

文字列は有効なパスカル識別子ですか

22

function LastDelimiter(const Delimiters: ; const S:):Integer;

文字列内の最後の文字の出現

23

function LeftStr(const S: ; Count: Integer):;

文字列の最初のN文字を取得します

24

function LoadStr(Ident: Integer):;

リソースから文字列をロードします

25

function LowerCase(const s: ):; overload;

文字列をすべて小文字に変換します

26

function LowerCase(const V: variant ):; overload;

文字列をすべて小文字に変換します

27

function NewStr(const S:):PString; overload;

ヒープに新しい文字列を割り当てます

28

function RightStr(const S: ; Count: Integer):;

文字列の最後のN文字を取得します

29

function StrAlloc(Size: Cardinal):PChar;

文字列にメモリを割り当てます

30

function StrBufSize(Str: PChar):SizeUInt;

文字列用にメモリを予約します

31

procedure StrDispose(Str: PChar);

ヒープから文字列を削除します

32

function StrPas(Str: PChar):;

PCharをパスカル文字列に変換します

33

function StrPCopy(Dest: PChar; Source:):PChar;

Pascal文字列をコピーします

34

function StrPLCopy(Dest: PChar; Source: ; MaxLen: SizeUInt):PChar;

Nバイトのパスカル文字列をコピーします

35

function UpperCase(const s:):;

文字列をすべて大文字に変換します

Pascalは、プログラマーが定数、変数、関数、式などの論理エンティティを定義、保存、操作できるようにするデータ型ブール値を提供します。

ブール値は基本的に整数型です。ブール型変数には、2つの事前定義された可能な値がありますTrue そして False。ブール値に解決される式は、ブール型に割り当てることもできます。

Free Pascalは、 ByteBoolWordBool そして LongBoolタイプ。これらは、それぞれByte、Word、またはLongint型です。

値Falseは0(ゼロ)と同等であり、ブール値に変換する場合、ゼロ以外の値はすべてTrueと見なされます。Trueのブール値は、LongBool型の変数に割り当てられている場合、-1に変換されます。

論理演算子に注意する必要があります andor そして not ブールデータ型に対して定義されています。

ブールデータ型の宣言

ブール型の変数は、varキーワードを使用して宣言されます。

var
boolean-identifier: boolean;

例えば、

var
choice: boolean;

program exBoolean;
var
exit: boolean;

choice: char;
   begin
   writeln('Do you want to continue? ');
   writeln('Enter Y/y for yes, and N/n for no');
   readln(choice);

if(choice = 'n') then
   exit := true
else
   exit := false;

if (exit) then
   writeln(' Good Bye!')
else
   writeln('Please Continue');

readln;
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Do you want to continue?
Enter Y/y for yes, and N/n for no
N
Good Bye!
Y
Please Continue

Pascalプログラミング言語は、配列と呼ばれるデータ構造を提供します。これは、同じタイプの要素の固定サイズの順次コレクションを格納できます。配列はデータのコレクションを格納するために使用されますが、配列を同じタイプの変数のコレクションと考える方が便利な場合がよくあります。

number1、number2、...、number100などの個々の変数を宣言する代わりに、numbersなどの1つの配列変数を宣言し、numbers [1]、numbers [2]、...、numbers [100]を使用して表現します。個々の変数。配列内の特定の要素は、インデックスによってアクセスされます。

すべてのアレイは、連続したメモリ位置で構成されています。最小アドレスは最初の要素に対応し、最大アドレスは最後の要素に対応します。

インデックス0から始まるCスタイルの配列が必要な場合は、1ではなく0からインデックスを開始する必要があることに注意してください。

配列の宣言

Pascalで配列を宣言するには、プログラマーは型を宣言してからその配列の変数を作成するか、配列変数を直接宣言します。

1次元配列の型宣言の一般的な形式は次のとおりです。

type
   array-identifier = array[index-type] of element-type;

どこ、

  • array-identifier −は配列タイプの名前を示します。

  • index-type−配列の添え字を指定します。実数以外の任意のスカラーデータ型にすることができます

  • element-type −格納される値のタイプを指定します

例えば、

type
   vector = array [ 1..25] of real;
var
   velocity: vector;

現在、速度はベクトル型の可変配列であり、最大25個の実数を保持するのに十分です。

0インデックスから配列を開始するには、宣言は次のようになります。

type
   vector = array [ 0..24] of real;
var
   velocity: vector;

配列添え字の種類

Pascalでは、配列の添え字は、実数を除いて、整数、ブール値、列挙型、サブレンジなどの任意のスカラー型にすることができます。配列の添え字も負の値になる可能性があります。

例えば、

type
   temperature = array [-10 .. 50] of real;
var
   day_temp, night_temp: temperature;

下付き文字が文字型である別の例を取り上げましょう-

type
   ch_array = array[char] of 1..26;
var
   alphabet: ch_array;

下付き文字は列挙型である可能性があります-

type
   color = ( red, black, blue, silver, beige);
   car_color = array of [color] of boolean;
var
   car_body: car_color;

配列の初期化

Pascalでは、配列は、特定の添え字を指定するか、for-doループを使用して、割り当てによって初期化されます。

例-

type
   ch_array = array[char] of 1..26;
var
   alphabet: ch_array;
   c: char;

begin
   ...
   for c:= 'A' to 'Z' do
   alphabet[c] := ord[m];  
   (* the ord() function returns the ordinal values *)

配列要素へのアクセス

要素には、配列名にインデックスを付けることでアクセスします。これは、配列名の後に角括弧内に要素のインデックスを配置することによって行われます。例-

a: integer;
a: = alphabet['A'];

上記のステートメントは、alphabetという名前の配列から最初の要素を取得し、その値を変数aに割り当てます。

以下は、上記の3つの概念すべてを使用する例です。宣言、割り当て、配列へのアクセス-

program exArrays;
var
   n: array [1..10] of integer;   (* n is an array of 10 integers *)
   i, j: integer;

begin
   (* initialize elements of array n to 0 *)        
   for i := 1 to 10 do
       n[ i ] := i + 100;   (* set element at location i to i + 100 *)
    (* output each array element's value *)
   
   for j:= 1 to 10 do
      writeln('Element[', j, '] = ', n[j] );
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Element[1] = 101
Element[2] = 102
Element[3] = 103
Element[4] = 104
Element[5] = 105
Element[6] = 106
Element[7] = 107
Element[8] = 108
Element[9] = 109
Element[10] = 110

Pascalアレイの詳細

配列はPascalにとって重要であり、さらに多くの詳細が必要です。Pascalプログラマーにとって明らかな配列に関連するいくつかの重要な概念があります-

シニア番号 コンセプトと説明
1 多次元配列

Pascalは多次元配列をサポートしています。多次元配列の最も単純な形式は、2次元配列です。

2 動的配列

このタイプの配列では、初期の長さはゼロです。配列の実際の長さは、標準で設定する必要がありますSetLength 関数。

3 パック配列

これらの配列はビットパックされています。つまり、各文字または真理値は、1つのストレージユニット(通常はワード(4バイト以上))を使用する代わりに、連続したバイトで格納されます。

4 配列をサブプログラムに渡す

インデックスなしで配列の名前を指定することにより、配列へのポインタをサブプログラムに渡すことができます。

Pascalのポインタは簡単で楽しく学ぶことができます。一部のPascalプログラミングタスクはポインタを使用するとより簡単に実行でき、動的メモリ割り当てなどの他のタスクはポインタを使用しないと実行できません。したがって、完璧なPascalプログラマーになるには、ポインターを学ぶ必要があります。シンプルで簡単なステップでそれらを学び始めましょう。

ご存知のように、すべての変数はメモリ位置であり、すべてのメモリ位置にはアドレスが定義されており、メモリ内のアドレスを示すポインタ変数の名前を使用してアクセスできます。

ポインタとは何ですか?

ポインタは動的変数であり、その値は別の変数のアドレス、つまりメモリ位置の直接アドレスです。他の変数や定数と同様に、変数アドレスを格納するために使用する前に、ポインターを宣言する必要があります。ポインタ変数宣言の一般的な形式は次のとおりです。

type
   ptr-identifier = ^base-variable-type;

ポインター型は、キャレット記号の上矢印(^)の前に基本型を付けることによって定義されます。base-typeは、データ項目のタイプを定義します。ポインタ変数が特定のタイプであると定義されると、そのタイプのデータ項目のみを指すことができます。ポインタ型が定義されると、var ポインタ変数を宣言する宣言。

var
   p1, p2, ... : ptr-identifier;

以下はいくつかの有効なポインタ宣言です-

type
   Rptr = ^real;
   Cptr = ^char;
   Bptr = ^ Boolean;
   Aptr = ^array[1..5] of real;
   date-ptr = ^ date;
      Date = record
         Day: 1..31;
         Month: 1..12;
         Year: 1900..3000;
      End;
var
   a, b : Rptr;
   d: date-ptr;

ポインター変数は、同じキャレット記号(^)を使用して逆参照されます。たとえば、ポインタrptrによって参照される関連変数は、rptr ^です。−としてアクセスできます。

rptr^ := 234.56;

次の例は、この概念を示しています-

program exPointers;
var
   number: integer;
   iptr: ^integer;

begin
   number := 100;
   writeln('Number is: ', number);
   
   iptr := @number;
   writeln('iptr points to a value: ', iptr^);
   
   iptr^ := 200;
   writeln('Number is: ', number);
   writeln('iptr points to a value: ', iptr^);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Number is: 100
iptr points to a value: 100
Number is: 200
iptr points to a value: 200

パスカルでのメモリアドレスの印刷

Pascalでは、アドレス演算子(@)を使用して、変数のアドレスをポインター変数に割り当てることができます。このポインタを使用して、データ項目を操作およびアクセスします。ただし、何らかの理由でメモリアドレス自体を処理する必要がある場合は、それをワードタイプ変数に格納する必要があります。

上記の例を拡張して、ポインタiptr −に格納されているメモリアドレスを出力してみましょう。

program exPointers;
var
   number: integer;
   iptr: ^integer;
   y: ^word;

begin
   number := 100;
   writeln('Number is: ', number);
   iptr := @number;
   writeln('iptr points to a value: ', iptr^);
   
   iptr^ := 200;
   writeln('Number is: ', number);
   writeln('iptr points to a value: ', iptr^);
   y := addr(iptr);
   writeln(y^); 
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Number is: 100
iptr points to a value: 100
Number is: 200
iptr points to a value: 200
45504

NILポインタ

を割り当てることは常に良い習慣です NIL割り当てる正確なアドレスがない場合のポインタ変数への値。これは、変数宣言時に行われます。割り当てられたポインタNILどこも指さない。次のプログラムを検討してください-

program exPointers;
var
   number: integer;
   iptr: ^integer;
   y: ^word;

begin
   iptr := nil;
   y := addr(iptr);
   
   writeln('the vaule of iptr is ', y^);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

The value of ptr is 0

を確認するには nil 次のようにifステートメントを使用できるポインター-

if(ptr <> nill )then     (* succeeds if p is not null *)
if(ptr = nill)then    (* succeeds if p is null *)

Pascalポインタの詳細

ポインタには多くの簡単な概念があり、Pascalプログラミングにとって非常に重要です。Pascalプログラマーにとって明らかなはずの、以下のいくつかの重要なポインターの概念があります。

シニア番号 コンセプトと説明
1 パスカル-ポインタ演算

ポインタで使用できる算術演算子は、インクリメント、デクリメント、+、-の4つです。

2 Pascal-ポインタの配列

多数のポインターを保持する配列を定義できます。

3 Pascal-ポインタへのポインタ

Pascalを使用すると、ポインタの上にポインタを置くことができます。

4 Pascalのサブプログラムへのポインターの受け渡し

参照またはアドレスの両方で引数を渡すと、渡された引数を、呼び出されたサブプログラムによって呼び出し側サブプログラムで変更できます。

5 Pascalのサブプログラムからポインタを返す

Pascalでは、サブプログラムがポインタを返すことができます。

Pascal配列を使用すると、同じ種類の複数のデータアイテムを保持できる変数のタイプを定義できますが、レコードは、異なる種類のデータアイテムを組み合わせることができるPascalで使用できる別のユーザー定義データタイプです。

レコードはさまざまなフィールドで構成されています。図書館で本を追跡したい場合、各本に関する次の属性を追跡したい場合があります。

  • Title
  • Author
  • Subject
  • ブックID

レコードの定義

レコード型を定義するには、型宣言ステートメントを使用できます。レコードタイプは次のように定義されます-

type
record-name = record
   field-1: field-type1;
   field-2: field-type2;
   ...
   field-n: field-typen;
end;

これがあなたが本の記録を宣言する方法です-

type 
Books = record
   title: packed array [1..50] of char;
   author: packed array [1..50] of char;
   subject: packed array [1..100] of char;
   book_id: integer;
end;

レコード変数は、通常の方法で次のように定義されます。

var
   r1, r2, ... : record-name;

または、レコードタイプ変数を-として直接定義することもできます。

var
Books : record
   title: packed array [1..50] of char;
   author: packed array [1..50] of char;
   subject: packed array [1..100] of char;
   book_id: integer;
end;

レコードのフィールドへのアクセス

レコードの任意のフィールドにアクセスするには、メンバーアクセス演算子(。)を使用します。メンバーアクセス演算子は、レコード変数名とアクセスするフィールドの間のピリオドとしてコード化されます。以下は、構造の使用法を説明する例です-

program exRecords;
type
Books = record
   title: packed array [1..50] of char;
   author: packed array [1..50] of char;
   subject: packed array [1..100] of char;
   book_id: longint;
end;

var
   Book1, Book2: Books; (* Declare Book1 and Book2 of type Books *)

begin
   (* book 1 specification *)
   Book1.title  := 'C Programming';
   Book1.author := 'Nuha Ali '; 
   Book1.subject := 'C Programming Tutorial';
   Book1.book_id := 6495407;

   (* book 2 specification *)
   Book2.title := 'Telecom Billing';
   Book2.author := 'Zara Ali';
   Book2.subject := 'Telecom Billing Tutorial';
   Book2.book_id := 6495700;
 
   (* print Book1 info *)
   writeln ('Book 1 title : ', Book1.title);
   writeln('Book 1 author : ', Book1.author);
   writeln( 'Book 1 subject : ', Book1.subject);
   writeln( 'Book 1 book_id : ', Book1.book_id);
   writeln; 

   (* print Book2 info *)
   writeln ('Book 2 title : ', Book2.title);
   writeln('Book 2 author : ', Book2.author);
   writeln( 'Book 2 subject : ', Book2.subject);
   writeln( 'Book 2 book_id : ', Book2.book_id);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407

Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700

サブプログラム引数として記録

他の変数またはポインターを渡すのと非常によく似た方法で、サブプログラム引数としてレコードを渡すことができます。上記の例でアクセスしたのと同様の方法でレコードフィールドにアクセスします-

program exRecords;
type
Books = record
   title: packed array [1..50] of char;
   author: packed array [1..50] of char;
   subject: packed array [1..100] of char;
   book_id: longint;
end;

var
   Book1, Book2: Books; (* Declare Book1 and Book2 of type Books *)

(* procedure declaration *)
procedure printBook( var book: Books );

begin
   (* print Book info *)
   writeln ('Book  title : ', book.title);
   writeln('Book  author : ', book.author);
   writeln( 'Book  subject : ', book.subject);
   writeln( 'Book book_id : ', book.book_id);
end;

begin
   (* book 1 specification *)
   Book1.title  := 'C Programming';
   Book1.author := 'Nuha Ali '; 
   Book1.subject := 'C Programming Tutorial';
   Book1.book_id := 6495407;
   
   (* book 2 specification *)
   Book2.title := 'Telecom Billing';
   Book2.author := 'Zara Ali';
   Book2.subject := 'Telecom Billing Tutorial';
   Book2.book_id := 6495700;
   
   (* print Book1 info *)
   printbook(Book1);
   writeln; 

   (* print Book2 info *)
   printbook(Book2);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407

Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700

レコードへのポインタ

次のように他の変数へのポインタを定義するのと非常によく似た方法で、レコードへのポインタを定義できます。

type
record-ptr = ^ record-name;
record-name = record
   field-1: field-type1;
   field-2: field-type2;
   ...
   field-n: field-typen;
end;

これで、レコードタイプ変数のアドレスを上記で定義したポインタ変数に格納できます。作成されたポインタ型の変数を宣言するには、varキーワード-を使用します。

var
   r1, r2, ... : record-ptr;

これらのポインターを使用する前に、これらのポインターによって操作されるレコード名タイプの変数用のストレージを作成する必要があります。

new(r1);
new(r2);

レコードへのポインタを使用してレコードのメンバーにアクセスするには、^を使用する必要があります。次のように演算子-

r1^.feild1 := value1;
r1^.feild2 := value2;
...
r1^fieldn := valuen;

最後に、使用されなくなったストレージを廃棄することを忘れないでください-

dispose(r1);
dispose(r2);

Booksレコードへのポインタを使用して、最初の例を書き直してみましょう。これがあなたが概念を理解するのが簡単になることを願っています-

program exRecords;
type
BooksPtr = ^ Books;
Books = record
   title: packed array [1..50] of char;
   author: packed array [1..50] of char;
   subject: packed array [1..100] of char;
   book_id: longint;
end;

var
  (* Declare Book1 and Book2 of pointer type that refers to Book type *)
   Book1, Book2: BooksPtr; 

begin
   new(Book1);
   new(book2);
   
   (* book 1 specification *)
   Book1^.title  := 'C Programming';
   Book1^.author := 'Nuha Ali '; 
   Book1^.subject := 'C Programming Tutorial';
   Book1^.book_id := 6495407;
   
   (* book 2 specification *)
   Book2^.title := 'Telecom Billing';
   Book2^.author := 'Zara Ali';
   Book2^.subject := 'Telecom Billing Tutorial';
   Book2^.book_id := 6495700;
   
   (* print Book1 info *)
   writeln ('Book 1 title : ', Book1^.title);
   writeln('Book 1 author : ', Book1^.author);
   writeln( 'Book 1 subject : ', Book1^.subject);
   writeln( 'Book 1 book_id : ', Book1^.book_id);
   
   (* print Book2 info *)
   writeln ('Book 2 title : ', Book2^.title);
   writeln('Book 2 author : ', Book2^.author);
   writeln( 'Book 2 subject : ', Book2^.subject);
   writeln( 'Book 2 book_id : ', Book2^.book_id);
   
   dispose(Book1); 
   dispose(Book2);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Book 1 title : C Programming
Book 1 author : Nuha Ali
Book 1 subject : C Programming Tutorial
Book 1 book_id : 6495407

Book 2 title : Telecom Billing
Book 2 author : Zara Ali
Book 2 subject : Telecom Billing Tutorial
Book 2 book_id : 6495700

Withステートメント

レコードのメンバーには、メンバーアクセス演算子(。)を使用してアクセスできることを説明しました。このように、レコード変数の名前を毎回書き込む必要があります。ザ・With ステートメントは、それを行うための代替方法を提供します。

最初の例から抜粋した次のコードスニペットを見てください-

(* book 1 specification *)
   Book1.title  := 'C Programming';
   Book1.author := 'Nuha Ali '; 
   Book1.subject := 'C Programming Tutorial';
   Book1.book_id := 6495407;

同じ割り当ては、を使用して書くことができます With -としてのステートメント

(* book 1 specification *)
With Book1 do
begin
   title  := 'C Programming';
   author := 'Nuha Ali '; 
   subject := 'C Programming Tutorial';
   book_id := 6495407;
end;

Pascalは、バリアントという名前の一意のタイプのストレージをサポートしています。バリアント変数には、任意の単純なタイプの値を割り当てることができます。バリアントに格納される値のタイプは、実行時にのみ決定されます。バリアントには、通常の型、文字列型、int64型など、ほとんどすべての単純な型を割り当てることができます。

セット、レコード、配列、ファイル、オブジェクト、クラスなどの構造化タイプは、バリアントとの代入互換性がありません。バリアントへのポインタを割り当てることもできます。

FreePascalはバリアントをサポートしています。

バリアントの宣言

を使用して、他の型と同じようにバリアント型を宣言できます。 varキーワード。バリアント型を宣言するための構文は次のとおりです。

var
   v: variant;

現在、このバリアント変数vは、列挙型を含むほぼすべての単純型に割り当てることができ、その逆も可能です。

type  
   color = (red, black, white);  
var  
   v : variant;  
   i : integer;  
   b : byte;  
   w : word;  
   q : int64;  
   e : extended;  
   d : double;  
   en : color;  
   as : ansistring;  
   ws : widestring;  

begin  
   v := i;  
   v := b;  
   v := w;  
   v := q;  
   v := e;  
   v := en;  
   v := d:  
   v := as;  
   v := ws;  
end;

次の例は、概念を説明します-

Program exVariant;

uses variants;
type
   color = (red, black, white);

var
   v : variant;
   i : integer;
   r: real;
   c : color;
   as : ansistring;


begin
   i := 100;
   v:= i;
   writeln('Variant as Integer: ', v);

   r:= 234.345;
   v:= r;
   writeln('Variant as real: ', v);

   c := red;
   v := c;
   writeln('Variant as Enumerated data: ', v);

   as:= ' I am an AnsiString';
   v:= as;
   writeln('Variant as AnsiString: ', v);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Variant as Integer: 100
Variant as real: 234.345
Variant as Enumerated data: 0
Variant as AnsiString: I am an AnsiString

セットは、同じタイプの要素のコレクションです。Pascalでは、設定されたデータ型を定義できます。セット内の要素は、そのメンバーと呼ばれます。数学では、セットはメンバーを中括弧{}で囲むことによって表されます。ただし、Pascalでは、集合要素は角括弧[]で囲まれ、集合コンストラクターと呼ばれます。

セットタイプと変数の定義

パスカルセットタイプは次のように定義されます

type
set-identifier = set of base type;

セットタイプの変数は、次のように定義されます。

var
s1, s2, ...: set-identifier;

または、

s1, s2...: set of base type;

いくつかの有効なセット型宣言の例は次のとおりです。

type
Days = (mon, tue, wed, thu, fri, sat, sun);
Letters = set of char;
DaySet = set of days;
Alphabets = set of 'A' .. 'Z';
studentAge = set of 13..20;

演算子の設定

Pascalセットでは、次のセット操作を実行できます。

シニア番号 操作と説明
1

Union

これは2つのセットを結合し、両方のセットのメンバーを含む新しいセットを提供します。

2

Difference

2つのセットの差を取得し、どちらのセットにも共通ではない要素を持つ新しいセットを提供します。

3

Intersection

2つのセットの共通部分を取得し、両方のセットに共通の要素を持つ新しいセットを提供します。

4

Inclusion

P内のすべてのアイテムもQに含まれているが、その逆ではない場合、セットPはセットQに含まれます。

5

Symmetric difference

2つのセットの対称差を取得し、いずれかのセットにあり、それらの交点にはない要素のセットを提供します。

6

In

メンバーシップをチェックします。

次の表は、FreePascalでサポートされているすべての集合演算子を示しています。と仮定するS1 そして S2 次のような2つの文字セットです。

S1:= ['a'、 'b'、 'c'];

S2:= ['c'、 'd'、 'e'];

オペレーター 説明
+ 2セットのユニオン

S1 + S2はセットを与えます

['a'、 'b'、 'c'、 'd'、 'e']

- 2セットの違い

S1-S2はセットを与えます

['a'、 'b']

* 2つのセットの交差

S1 * S2はセットを与えます

['c']

> < 2セットの対称差 S1> <S2は集合['a'、 'b'、 'd'、 'e']を与えます
= 2セットの同等性をチェックします S1 = S2はブール値Falseを与えます
<> 2セットの不等式をチェックします S1 <> S2はブール値Trueを与えます
<= 含む(一方のセットが他方のサブセットであるかどうかを確認します) S1 <= S2はブール値Falseを与えます
含める セットに要素を含めます。基本的には、同じ基本型のセットと要素の和集合です。

インクルード(S1、['d'])はセットを与えます

['あいうえお']

除外する セットから要素を除外します。基本的には同じ基本型のセットと要素の違いです

Exclude(S2、['d'])はセットを与えます

['c'、 'e']

セット内の要素のセットメンバーシップをチェックします S2の['e']はブール値Trueを与えます

次の例は、これらの演算子のいくつかの使用法を示しています-

program setColors;
type  
color = (red, blue, yellow, green, white, black, orange);  
colors = set of color;  
 
procedure displayColors(c : colors);  
const  
names : array [color] of String[7]  
  = ('red', 'blue', 'yellow', 'green', 'white', 'black', 'orange');  
var  
   cl : color;  
   s : String;  

begin  
   s:= ' ';  
   for cl:=red to orange do  
      if cl in c then  
      begin  
         if (s<>' ') then s :=s +' , ';  
         s:=s+names[cl];  
      end;  
   writeln('[',s,']');  
end;  
 
var  
   c : colors;  
 
begin  
   c:= [red, blue, yellow, green, white, black, orange];
   displayColors(c);

   c:=[red, blue]+[yellow, green]; 
   displayColors(c);  

   c:=[red, blue, yellow, green, white, black, orange] - [green, white];     
   displayColors(c);    

   c:= [red, blue, yellow, green, white, black, orange]*[green, white];     
   displayColors(c);  

   c:= [red, blue, yellow, green]><[yellow, green, white, black]; 
   displayColors(c);  
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

[ red , blue , yellow , green , white , black , orange]
[ red , blue , yellow , green]
[ red , blue , yellow , black , orange]
[ green , white]
[ red , blue , white , black]

Pascalは、ファイルをコンポーネントのシーケンスとして扱います。コンポーネントは、均一なタイプである必要があります。ファイルのタイプは、コンポーネントのタイプによって決まります。ファイルのデータ型は次のように定義されます-

type
file-name = file of base-type;

ここで、base-typeは、ファイルのコンポーネントのタイプを示します。基本タイプは、整数、実数、ブール、列挙、サブレンジ、レコード、配列、および別のファイルタイプを除くセットのようなものにすることができます。ファイルタイプの変数は、var宣言を使用して作成されます-

var
f1, f2,...: file-name;

以下は、いくつかのファイルタイプとファイル変数を定義するいくつかの例です-

type
   rfile = file of real;
   ifile = file of integer;
   bfile = file of boolean;
   datafile = file of record
   arrfile = file of array[1..4] of integer;

var
   marks: arrfile;
   studentdata: datafile;
   rainfalldata: rfile;
   tempdata: ifile;
   choices: bfile;

ファイルの作成と書き込み

学生の記録用のデータファイルを作成するプログラムを書いてみましょう。それはstudents.datという名前のファイルを作成し、それに学生のデータを書き込みます-

program DataFiles;
type
   StudentRecord = Record
      s_name: String;
      s_addr: String;
      s_batchcode: String;
   end;

var
   Student: StudentRecord;
   f: file of StudentRecord;

begin
   Assign(f,'students.dat');
   Rewrite(f);
   Student.s_name := 'John Smith';
   Student.s_addr := 'United States of America';
   Student.s_batchcode := 'Computer Science';
   Write(f,Student);
   Close(f);
end.

コンパイルして実行すると、プログラムはstudents.datという名前のファイルを作業ディレクトリに作成します。メモ帳などのテキストエディタを使用してファイルを開き、ジョンスミスのデータを確認できます。

ファイルからの読み取り

作成して、students.datという名前のファイルに書き込みました。それでは、ファイルから学生のデータを読み取るプログラムを作成しましょう。

program DataFiles;
type
   StudentRecord = Record
      s_name: String;
      s_addr: String;
      s_batchcode: String;
   end;

var
   Student: StudentRecord;
   f: file of StudentRecord;

begin
   assign(f, 'students.dat');
   reset(f); 
   while not eof(f) do
   
   begin
      read(f,Student);
      writeln('Name: ',Student.s_name);
      writeln('Address: ',Student.s_addr);
      writeln('Batch Code: ', Student.s_batchcode);
   end;
   
   close(f);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Name: John Smith
Address: United States of America
Batch Code: Computer Science

サブプログラムパラメータとしてのファイル

Pascalでは、ファイル変数を標準およびユーザー定義のサブプログラムのパラメーターとして使用できます。次の例は、この概念を示しています。プログラムは、raindown.txtという名前のファイルを作成し、いくつかの降雨データを保存します。次に、ファイルを開き、データを読み取り、平均降雨量を計算します。

その点に注意してください、 if you use a file parameter with subprograms, it must be declared as a var parameter.

program addFiledata;
const
   MAX = 4;
type
   raindata = file of real;

var
   rainfile: raindata;
   filename: string;
procedure writedata(var f: raindata);

var
   data: real;
   i: integer;

begin
   rewrite(f, sizeof(data));
   for i:=1 to MAX do
   
   begin
      writeln('Enter rainfall data: ');
      readln(data);
      write(f, data);
   end;
   
   close(f);
end;

procedure computeAverage(var x: raindata);
var
   d, sum: real;
   average: real;

begin
   reset(x);
   sum:= 0.0;
   while not eof(x) do
   
   begin
      read(x, d);
      sum := sum + d;
   end;
   
   average := sum/MAX;
   close(x);
   writeln('Average Rainfall: ', average:7:2);
end;

begin
   writeln('Enter the File Name: ');
   readln(filename);
   assign(rainfile, filename);
   writedata(rainfile);
   computeAverage(rainfile);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Enter the File Name:
rainfall.txt
Enter rainfall data:
34
Enter rainfall data:
45
Enter rainfall data:
56
Enter rainfall data:
78
Average Rainfall: 53.25

テキストファイル

Pascalのテキストファイルは、各行が行末マーカーで終了する文字行で構成されています。このようなファイルは、次のように宣言および定義できます。

type
file-name = text;

通常の文字ファイルとテキストファイルの違いは、テキストファイルが行に分割され、各行が特別な行末マーカーで終了し、システムによって自動的に挿入されることです。次の例では、contact.txtという名前のテキストファイルを作成して書き込みます。

program exText;
var
   filename, data: string;
   myfile: text;

begin
   writeln('Enter the file name: ');
   readln(filename);
   
   assign(myfile, filename);
   rewrite(myfile);
   
   writeln(myfile, 'Note to Students: ');
   writeln(myfile, 'For details information on Pascal Programming');
   writeln(myfile, 'Contact: Tutorials Point');
   writeln('Completed writing'); 
   
   close(myfile);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Enter the file name:
contact.txt 
Completed writing

ファイルへの追加

ファイルへの追加とは、ファイルを上書きせずに、すでにデータが含まれている既存のファイルに書き込むことを意味します。次のプログラムはこれを示しています-

program exAppendfile;
var
   myfile: text;
   info: string;

begin
   assign(myfile, 'contact.txt');
   append(myfile);
   
   writeln('Contact Details');
   writeln('[email protected]');
   close(myfile);
   
   (* let us read from this file *)
   assign(myfile, 'contact.txt');
   reset(myfile);
   while not eof(myfile) do
   
   begin
      readln(myfile, info);
      writeln(info);
   end;
   close(myfile);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Contact Details
[email protected]
Note to Students:
For details information on Pascal Programming
Contact: Tutorials Point

ファイル処理関数

Free Pascalは、ファイル処理のために次の機能/手順を提供します-

シニア番号 関数名と説明
1

procedure Append(var t: Text);

追加モードでファイルを開きます

2

procedure Assign(out f: file; const Name:);

ファイルに名前を割り当てます

3

procedure Assign(out f: file; p: PChar);

ファイルに名前を割り当てます

4

procedure Assign(out f: file; c: Char);

ファイルに名前を割り当てます

5

procedure Assign(out f: TypedFile; const Name:);

ファイルに名前を割り当てます

6

procedure Assign(out f: TypedFile; p: PChar);

ファイルに名前を割り当てます

7

procedure Assign(out f: TypedFile; c: Char);

ファイルに名前を割り当てます

8

procedure Assign(out t: Text; const s:);

ファイルに名前を割り当てます

9

procedure Assign(out t: Text; p: PChar);

ファイルに名前を割り当てます

10

procedure Assign(out t: Text; c: Char);

ファイルに名前を割り当てます

11

procedure BlockRead(var f: file; var Buf; count: Int64; var Result: Int64);

ファイルからメモリにデータを読み取ります

12

procedure BlockRead(var f: file; var Buf; count: LongInt; var Result: LongInt);

ファイルからメモリにデータを読み取ります

13

procedure BlockRead(var f: file; var Buf; count: Cardinal; var Result: Cardinal);

ファイルからメモリにデータを読み取ります

14

procedure BlockRead(var f: file; var Buf; count: Word; var Result: Word);

ファイルからメモリにデータを読み取ります

15

procedure BlockRead(var f: file; var Buf; count: Word; var Result: Integer);

ファイルからメモリにデータを読み取ります

16

procedure BlockRead(var f: file; var Buf; count: Int64);

ファイルからメモリにデータを読み取ります

17

procedure BlockWrite(var f: file; const Buf; Count: Int64; var Result: Int64);

メモリからファイルにデータを書き込みます

18

procedure BlockWrite(var f: file; const Buf; Count: LongInt; var Result: LongInt);

メモリからファイルにデータを書き込みます

19

procedure BlockWrite(var f: file; const Buf; Count: Cardinal; var Result: Cardinal);

メモリからファイルにデータを書き込みます

20

procedure BlockWrite(var f: file; const Buf; Count: Word; var Result: Word);

メモリからファイルにデータを書き込みます

21

procedure BlockWrite(var f: file; const Buf; Count: Word; var Result: Integer);

メモリからファイルにデータを書き込みます

22

procedure BlockWrite(var f: file; const Buf; Count: LongInt);

メモリからファイルにデータを書き込みます

23

procedure Close(var f: file);

ファイルを閉じます

24

procedure Close(var t: Text);

ファイルを閉じます

25

function EOF(var f: file):Boolean;

ファイルの終わりをチェックします

26

function EOF(var t: Text):Boolean;

ファイルの終わりをチェックします

27

function EOF: Boolean;

ファイルの終わりをチェックします

28

function EOLn(var t: Text):Boolean;

行末をチェックします

29

function EOLn: Boolean;

行末をチェックします

30

procedure Erase(var f: file);

ディスクからファイルを削除します

31

procedure Erase(var t: Text);

ディスクからファイルを削除します

32

function FilePos( var f: file):Int64;

ファイル内の位置

33

function FileSize(var f: file):Int64;

ファイルのサイズ

34

procedure Flush(var t: Text);

ファイルバッファをディスクに書き込みます

35

function IOResult: Word;

最後のファイルIO操作の結果を返します

36

procedure Read(var F: Text; Args: Arguments);

ファイルから変数に読み込みます

37

procedure Read(Args: Arguments);

ファイルから変数に読み込みます

38

procedure ReadLn(var F: Text; Args: Arguments);

ファイルから変数に読み込み、次の行に移動します

39

procedure ReadLn(Args: Arguments);

ファイルから変数に読み込み、次の行に移動します

40

procedure Rename(var f: file; const s:);

ディスク上のファイルの名前を変更します

41

procedure Rename(var f: file; p: PChar);

ディスク上のファイルの名前を変更します

42

procedure Rename(var f: file; c: Char);

ディスク上のファイルの名前を変更します

43

procedure Rename(var t: Text; const s);

ディスク上のファイルの名前を変更します

44

procedure Rename(var t: Text; p: PChar);

ディスク上のファイルの名前を変更します

45

procedure Rename( var t: Text; c: Char);

ディスク上のファイルの名前を変更します

46

procedure Reset(var f: file; l: LongInt);

読むためにファイルを開きます

47

procedure Reset(var f: file);

読むためにファイルを開きます

48

procedure Reset(var f: TypedFile);

読むためにファイルを開きます

49

procedure Reset(var t: Text);

読むためにファイルを開きます

50

procedure Rewrite(var f: file; l: LongInt);

書き込み用にファイルを開きます

51

procedure Rewrite(var f: file);

書き込み用にファイルを開きます

52

procedure Rewrite(var f: TypedFile);

書き込み用にファイルを開きます

53

procedure Rewrite(var t: Text);

書き込み用にファイルを開きます

54

procedure Seek(var f: file; Pos: Int64);

ファイルの位置を設定します

55

function SeekEOF(var t: Text):Boolean;

ファイルの位置をファイルの終わりに設定します

56

function SeekEOF: Boolean;

ファイルの位置をファイルの終わりに設定します

57

function SeekEOLn(var t: Text):Boolean;

ファイルの位置を行末に設定します

58

function SeekEOLn: Boolean;

ファイルの位置を行末に設定します

59

procedure SetTextBuf(var f: Text; var Buf);

ファイルバッファのサイズを設定します

60

procedure SetTextBuf(var f: Text; var Buf; Size: SizeInt);

ファイルバッファのサイズを設定します

61

procedure Truncate(var F: file);

位置でファイルを切り捨てます

62

procedure Write(Args: Arguments);

変数をファイルに書き込みます

63

procedure Write(var F: Text; Args: Arguments);

変数をファイルに書き込む

64

procedure Writeln(Args: Arguments);

変数をファイルに書き込み、改行を追加します

65

procedure WriteLn(var F: Text; Args: Arguments);

変数をファイルに書き込み、改行を追加します

この章では、Pascalでの動的メモリ管理について説明します。Pascalプログラミング言語は、メモリの割り当てと管理のためのいくつかの機能を提供します。

動的にメモリを割り当てる

プログラミングをしているときに、配列のサイズを知っていれば、それは簡単で、配列として定義できます。たとえば、任意の人の名前を保存するには、最大100文字にすることができるため、次のように定義できます。

var
name: array[1..100] of char;

しかし、ここで、保存する必要のあるテキストの長さがわからない場合、たとえば、トピックに関する詳細な説明を保存したい場合を考えてみましょう。ここでは、必要なメモリ量を定義せずに、文字列へのポインタを定義する必要があります。

パスカルは手順を提供します newポインタ変数を作成します。

program exMemory;
var
name: array[1..100] of char;
description: ^string;

begin
   name:= 'Zara Ali';
   
   new(description);
      if not assigned(description) then
         writeln(' Error - unable to allocate required memory')
      else
         description^ := 'Zara ali a DPS student in class 10th';
   writeln('Name = ', name );
   writeln('Description: ', description^ );
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Name = Zara Ali
Description: Zara ali a DPS student in class 10th

ここで、後で参照する特定のバイト数のポインターを定義する必要がある場合は、 getmem 関数または getmem 次の構文を持つプロシージャ-

procedure Getmem(
   out p: pointer;
   Size: PtrUInt
);

function GetMem(
   size: PtrUInt
):pointer;

前の例では、文字列へのポインタを宣言しました。文字列の最大値は255バイトです。バイトに関してそれほど多くのスペース、またはより大きなスペースが本当に必要ない場合は、getmemサブプログラムでそれを指定できます。getmem −を使用して、前の例を書き直してみましょう。

program exMemory;
var
name: array[1..100] of char;
description: ^string;

begin
   name:= 'Zara Ali';
   
   description := getmem(200);
      if not assigned(description) then
         writeln(' Error - unable to allocate required memory')
      else
         description^ := 'Zara ali a DPS student in class 10th';
   writeln('Name = ', name );
   writeln('Description: ', description^ );
   
   freemem(description);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Name = Zara Ali
Description: Zara ali a DPS student in class 10th

したがって、完全に制御でき、一度定義したサイズを変更できない配列とは異なり、メモリを割り当てながら任意のサイズ値を渡すことができます。

メモリのサイズ変更と解放

プログラムがリリースされると、オペレーティングシステムはプログラムによって割り当てられたすべてのメモリを自動的に解放しますが、メモリが不要になった場合の良い習慣として、そのメモリを解放する必要があります。

パスカルは手順を提供します dispose 手順を使用して動的に作成された変数を解放するには new. を使用してメモリを割り当てた場合 getmem サブプログラムの場合、サブプログラムを使用する必要があります freememこのメモリを解放します。FREEMEMサブプログラムは、次の構文を持っています-

procedure Freemem(
   p: pointer;
  Size: PtrUInt
);

function Freemem(
   p: pointer
):PtrUInt;

または、関数ReAllocMemを呼び出すことにより、割り当てられたメモリブロックのサイズを増減できます。上記のプログラムをもう一度確認し、ReAllocMemおよびfreememサブプログラムを利用してみましょう。以下はのための構文ですReAllocMem -

function ReAllocMem(
   var p: pointer;
   Size: PtrUInt
):pointer;

以下は、ReAllocMemおよびfreememサブプログラムを利用する例です-

program exMemory;
var
name: array[1..100] of char;
description: ^string;
desp: string;

begin
   name:= 'Zara Ali';
   desp := 'Zara ali a DPS student.';
   
   description := getmem(30);
      if not assigned(description) then
         writeln('Error - unable to allocate required memory')
      else
         description^ := desp;

   (* Suppose you want to store bigger description *)
   description := reallocmem(description, 100);
   desp := desp + ' She is in class 10th.';
   description^:= desp; 
   
   writeln('Name = ', name );
   writeln('Description: ', description^ );
   
   freemem(description);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Name = Zara Ali
Description: Zara ali a DPS student. She is in class 10th

メモリ管理機能

Pascalは、Pascalでさまざまなデータ構造を実装し、低レベルのプログラミングを実装する際に使用される一連のメモリ管理機能を提供します。これらの関数の多くは実装に依存しています。Free Pascalは、メモリ管理のために次の機能と手順を提供します-

SN 関数名と説明
1

function Addr(X: TAnytype):Pointer;

変数のアドレスを返します

2

function Assigned(P: Pointer):Boolean;

ポインタが有効かどうかを確認します

3

function CompareByte(const buf1; const buf2; len: SizeInt):SizeInt;

1バイトあたり2つのメモリバッファを比較します

4

function CompareChar(const buf1; const buf2; len: SizeInt):SizeInt;

1バイトあたり2つのメモリバッファを比較します

5

function CompareDWord(const buf1; const buf2; len: SizeInt):SizeInt;

1バイトあたり2つのメモリバッファを比較します

6

function CompareWord(const buf1; const buf2; len: SizeInt):SizeInt;

1バイトあたり2つのメモリバッファを比較します

7

function Cseg: Word;

コードセグメントを返します

8

procedure Dispose(P: Pointer);

動的に割り当てられたメモリを解放します

9

procedure Dispose(P: TypedPointer; Des: TProcedure);

動的に割り当てられたメモリを解放します

10

function Dseg: Word;

データセグメントを返します

11

procedure FillByte(var x; count: SizeInt; value: Byte);

メモリ領域を8ビットパターンで埋めます

12

procedure FillChar( var x; count: SizeInt; Value: Byte|Boolean|Char);

メモリ領域を特定の文字で埋めます

13

procedure FillDWord( var x; count: SizeInt; value: DWord);

メモリ領域を32ビットパターンで埋めます

14

procedure FillQWord( var x; count: SizeInt; value: QWord);

メモリ領域を64ビットパターンで埋めます

15 procedure FillWord( var x; count: SizeInt; Value: Word);

メモリ領域を16ビットパターンで埋めます

16

procedure Freemem( p: pointer; Size: PtrUInt);

割り当てられたメモリを解放します

17

procedure Freemem( p: pointer );

割り当てられたメモリを解放します

18

procedure Getmem( out p: pointer; Size: PtrUInt);

新しいメモリを割り当てます

19

procedure Getmem( out p: pointer);

新しいメモリを割り当てます

20

procedure GetMemoryManager( var MemMgr: TMemoryManager);

現在のメモリマネージャを返します

21

function High( Arg: TypeOrVariable):TOrdinal;

開いている配列または列挙されたものの最高のインデックスを返します

22

function IndexByte( const buf; len: SizeInt; b: Byte):SizeInt;

メモリ範囲内のバイトサイズの値を検索します

23

function IndexChar( const buf; len: SizeInt; b: Char):SizeInt;

メモリ範囲内の文字サイズの値を検索します

24

function IndexDWord( const buf; len: SizeInt; b: DWord):SizeInt;

メモリ範囲でDWordサイズ(32ビット)の値を検索します

25

function IndexQWord( const buf; len: SizeInt; b: QWord):SizeInt;

メモリ範囲でQWordサイズの値を検索します

26

function Indexword( const buf; len: SizeInt; b: Word):SizeInt;

メモリ範囲内のワードサイズの値を検索します

27

function IsMemoryManagerSet: Boolean;

メモリマネージャが設定されていますか

28

function Low( Arg: TypeOrVariable ):TOrdinal;

開いている配列または列挙された最小のインデックスを返します

29

procedure Move( const source; var dest; count: SizeInt );

メモリ内のある場所から別の場所にデータを移動します

30

procedure MoveChar0( const buf1; var buf2; len: SizeInt);

最初のゼロ文字までデータを移動します

31

procedure New( var P: Pointer);

変数にメモリを動的に割り当てます

32

procedure New( var P: Pointer; Cons: TProcedure);

変数にメモリを動的に割り当てます

33

function Ofs( var X ):LongInt;

変数のオフセットを返します

34

function ptr( sel: LongInt; off: LongInt):farpointer;

セグメントとオフセットをポインタに結合します

35

function ReAllocMem( var p: pointer; Size: PtrUInt):pointer;

ヒープ上のメモリブロックのサイズを変更します

36

function Seg( var X):LongInt;

セグメントを返します

37

procedure SetMemoryManager( const MemMgr: TMemoryManager );

メモリマネージャを設定します

38

function Sptr: Pointer;

現在のスタックポインタを返します

39

function Sseg: Word;

スタックセグメントレジスタ値を返します

Pascalプログラムは、ユニットと呼ばれるモジュールで構成できます。ユニットは、変数と型宣言、ステートメント、プロシージャなどで構成されるいくつかのコードブロックで構成されている場合があります。Pascalには多くの組み込みユニットがあり、Pascalではプログラマが使用する独自のユニットを定義および記述できます。後でさまざまなプログラムで。

内蔵ユニットの使用

組み込みユニットとユーザー定義ユニットの両方が、uses句によってプログラムに含まれています。Pascal-バリアントチュートリアルでは、バリアントユニットをすでに使用しています。このチュートリアルでは、ユーザー定義の単位の作成と組み込みについて説明します。ただし、最初に組み込みユニットを含める方法を見てみましょうcrt あなたのプログラムで-

program myprog;
uses crt;

次の例は、 crt 単位-

Program Calculate_Area (input, output);
uses crt;
var 
   a, b, c, s, area: real;

begin
   textbackground(white); (* gives a white background *)
   clrscr; (*clears the screen *)
   
   textcolor(green); (* text color is green *)
   gotoxy(30, 4); (* takes the pointer to the 4th line and 30th column) 
   
   writeln('This program calculates area of a triangle:');
   writeln('Area = area = sqrt(s(s-a)(s-b)(s-c))');
   writeln('S stands for semi-perimeter');
   writeln('a, b, c are sides of the triangle');
   writeln('Press any key when you are ready');
   
   readkey;
   clrscr;
   gotoxy(20,3);
   
   write('Enter a: ');
   readln(a);
   gotoxy(20,5);
   
   write('Enter b:');
   readln(b);
   gotoxy(20, 7);
   
   write('Enter c: ');
   readln(c);

   s := (a + b + c)/2.0;
   area := sqrt(s * (s - a)*(s-b)*(s-c));
   gotoxy(20, 9);
   
   writeln('Area: ',area:10:3);
   readkey;
end.

これは、Pascalチュートリアルの最初に使用したのと同じプログラムであり、コンパイルして実行し、変更の影響を見つけます。

パスカルユニットの作成と使用

ユニットを作成するには、ユニットに保存するモジュールまたはサブプログラムを作成し、次のファイルに保存する必要があります。 .pas拡張。このファイルの最初の行は、キーワードunitで始まり、その後にユニットの名前が続きます。例-

unit calculateArea;

Pascalユニットを作成する際の3つの重要なステップは次のとおりです-

  • ファイルの名前とユニットの名前は完全に同じである必要があります。したがって、ユニットcalculateAreacalculateArea.pasという名前のファイルに保存されます

  • 次の行は単一のキーワードで構成する必要があります interface。この行の後に、このユニットに含まれるすべての関数とプロシージャの宣言を記述します。

  • 関数宣言の直後に、次の単語を記述します implementation、これもキーワードです。キーワード実装を含む行の後に、すべてのサブプログラムの定義を指定します。

次のプログラムは、calculateArea-という名前のユニットを作成します。

unit CalculateArea;
interface

function RectangleArea( length, width: real): real;
function CircleArea(radius: real) : real;
function TriangleArea( side1, side2, side3: real): real;

implementation

function RectangleArea( length, width: real): real;
begin
   RectangleArea := length * width;
end;

function CircleArea(radius: real) : real;
const
   PI = 3.14159;
begin
   CircleArea := PI * radius * radius;
end;

function TriangleArea( side1, side2, side3: real): real;
var
   s, area: real;

begin
   s := (side1 + side2 + side3)/2.0;
   area := sqrt(s * (s - side1)*(s-side2)*(s-side3));
   TriangleArea := area;
end;

end.

次に、上記で定義した単位を使用する簡単なプログラムを作成しましょう。

program AreaCalculation;
uses CalculateArea,crt;

var
   l, w, r, a, b, c, area: real;

begin
   clrscr;
   l := 5.4;
   w := 4.7;
   area := RectangleArea(l, w);
   writeln('Area of Rectangle 5.4 x 4.7 is: ', area:7:3);

   r:= 7.0;
   area:= CircleArea(r);
   writeln('Area of Circle with radius 7.0 is: ', area:7:3);

   a := 3.0;
   b:= 4.0;
   c:= 5.0;
  
   area:= TriangleArea(a, b, c);
   writeln('Area of Triangle 3.0 by 4.0 by 5.0 is: ', area:7:3);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Area of Rectangle 5.4 x 4.7 is: 25.380
Area of Circle with radius 7.0 is: 153.938
Area of Triangle 3.0 by 4.0 by 5.0 is: 6.000

あなたが書くソフトウェアのほとんどは、現在の日付と時刻を返す何らかの形式の日付関数を実装する必要があります。デートは日常生活の一部であるため、考えずに一緒に仕事をすることが容易になります。Pascalは、日付の操作を簡単にする日付演算用の強力なツールも提供します。ただし、これらの関数の実際の名前と動作は、コンパイラーによって異なります。

現在の日付と時刻を取得する

PascalのTimeToString関数は、現在の時刻をコロン(:)で区切られた形式で提供します。次の例は、現在の時刻を取得する方法を示しています-

program TimeDemo;
uses sysutils;

begin
   writeln ('Current time : ',TimeToStr(Time));
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Current time : 18:33:08

ザ・ Date 関数は現在の日付をで返します TDateTimeフォーマット。TDateTimeはdouble値であり、デコードとフォーマットが必要です。次のプログラムは、プログラムでそれを使用して現在の日付を表示する方法を示しています-

Program DateDemo;
uses sysutils;
var
   YY,MM,DD : Word;

begin
   writeln ('Date : ',Date);
   DeCodeDate (Date,YY,MM,DD);
   writeln (format ('Today is (DD/MM/YY): %d/%d/%d ',[dd,mm,yy]));
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Date: 4.111300000000000E+004
Today is (DD/MM/YY):23/7/2012

Now関数は、現在の日付と時刻を返します-

Program DatenTimeDemo;
uses sysutils;
begin
   writeln ('Date and Time at the time of writing : ',DateTimeToStr(Now));
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Date and Time at the time of writing : 23/7/2012 18:51:

Free Pascalは、という名前の単純なタイムスタンプ構造を提供します TTimeStamp、次の形式です-

type TTimeStamp = record
   Time: Integer;
   Date: Integer;
end;

さまざまな日付と時刻の関数

Free Pascalは、次の日付と時刻の機能を提供します-

シニア番号 関数名と説明
1

function DateTimeToFileDate(DateTime: TDateTime):LongInt;

DateTimeタイプをファイルの日付に変換します。

2

function DateTimeToStr( DateTime: TDateTime):;

DateTimeの文字列表現を構築します

3

function DateTimeToStr(DateTime: TDateTime; const FormatSettings: TFormatSettings):;

DateTimeの文字列表現を構築します

4

procedure DateTimeToString(out Result: ;const FormatStr: ;const DateTime: TDateTime);

DateTimeの文字列表現を構築します

5

procedure DateTimeToString(out Result: ; const FormatStr: ; const DateTime: TDateTime; const FormatSettings: TFormatSettings);

DateTimeの文字列表現を構築します

6

procedure DateTimeToSystemTime(DateTime: TDateTime; out SystemTime: TSystemTime);

DateTimeをシステム時刻に変換します

7

function DateTimeToTimeStamp( DateTime: TDateTime):TTimeStamp;DateTimeをタイムスタンプに変換します

8

function DateToStr(Date: TDateTime):;

日付の文字列表現を構築します

9

function DateToStr(Date: TDateTime; const FormatSettings: TFormatSettings):;

日付の文字列表現を構築します

10

function Date: TDateTime;

現在の日付を取得します

11

function DayOfWeek(DateTime: TDateTime):Integer;

曜日を取得します

12

procedure DecodeDate(Date: TDateTime; out Year: Word; out Month: Word; out Day: Word);

DateTimeを年月日にデコードします

13

procedure DecodeTime(Time: TDateTime; out Hour: Word; out Minute: Word; out Second: Word; out MilliSecond: Word);

DateTimeを時間、分、秒にデコードします

14

function EncodeDate(Year: Word; Month: Word; Day: Word):TDateTime;

年、日、月をDateTimeにエンコードします

15

function EncodeTime(Hour: Word; Minute: Word; Second: Word; MilliSecond: Word):TDateTime;

時間、分、秒をDateTimeにエンコードします

16

function FormatDateTime(const FormatStr: ; DateTime: TDateTime):;

DateTimeの文字列表現を返します

17

function FormatDateTime(const FormatStr: ; DateTime: TDateTime; const FormatSettings: TFormatSettings):;

DateTimeの文字列表現を返します

18

function IncMonth(const DateTime: TDateTime; NumberOfMonths: Integer = 1):TDateTime;

月に1を追加

19

function IsLeapYear(Year: Word):Boolean;

年がうるう年かどうかを判断します

20

function MSecsToTimeStamp(MSecs: Comp):TTimeStamp;

ミリ秒数をタイムスタンプに変換します

21

function Now: TDateTime;

現在の日付と時刻を取得します

22

function StrToDateTime(const S:):TDateTime;

文字列をDateTimeに変換します

23

function StrToDateTime(const s: ShortString; const FormatSettings: TFormatSettings):TDateTime;

文字列をDateTimeに変換します

24

function StrToDateTime(const s: AnsiString; const FormatSettings: TFormatSettings):TDateTime;

文字列をDateTimeに変換します

25

function StrToDate(const S: ShortString):TDateTime;

文字列を日付に変換します

26

function StrToDate(const S: Ansistring):TDateTime;

文字列を日付に変換します

27

function StrToDate(const S: ShortString; separator: Char):TDateTime;

文字列を日付に変換します

28

function StrToDate(const S: AnsiString; separator: Char):TDateTime;

文字列を日付に変換します

29

function StrToDate(const S: ShortString; const useformat: ; separator: Char):TDateTime;

文字列を日付に変換します

30

function StrToDate(const S: AnsiString; const useformat: ; separator: Char):TDateTime;

文字列を日付に変換します

31

function StrToDate(const S: PChar; Len: Integer; const useformat: ; separator: Char = #0):TDateTime;

文字列を日付に変換します

32

function StrToTime(const S: Shortstring):TDateTime;

文字列を時間に変換します

33

function StrToTime(const S: Ansistring):TDateTime;

文字列を時間に変換します

34

function StrToTime(const S: ShortString; separator: Char):TDateTime;

文字列を時間に変換します

35

function StrToTime(const S: AnsiString; separator: Char):TDateTime;

文字列を時間に変換します

36

function StrToTime(const S: ; FormatSettings: TFormatSettings):TDateTime;

文字列を時間に変換します

37

function StrToTime(const S: PChar; Len: Integer; separator: Char = #0):TDateTime;

文字列を時間に変換します

38

function SystemTimeToDateTime(const SystemTime: TSystemTime):TDateTime;

システム時刻を日時に変換します

39

function TimeStampToDateTime(const TimeStamp: TTimeStamp):TDateTime;

タイムスタンプをDateTimeに変換します

40

function TimeStampToMSecs(const TimeStamp: TTimeStamp):comp;

タイムスタンプをミリ秒数に変換します

41

function TimeToStr(Time: TDateTime):;

時間の文字列表現を返します

42

function TimeToStr(Time: TDateTime; const FormatSettings: TFormatSettings):;

時間の文字列表現を返します

43

function Time: TDateTime;

現在の時刻を取得する

次の例は、上記の関数のいくつかの使用法を示しています-

Program DatenTimeDemo;
uses sysutils;
var
year, month, day, hr, min, sec, ms: Word;

begin
   writeln ('Date and Time at the time of writing : ',DateTimeToStr(Now));
   writeln('Today is ',LongDayNames[DayOfWeek(Date)]);
   writeln;
   writeln('Details of Date: ');
   
   DecodeDate(Date,year,month,day);
   writeln (Format ('Day: %d',[day]));
   writeln (Format ('Month: %d',[month]));
   writeln (Format ('Year: %d',[year]));
   writeln;
   writeln('Details of Time: ');
   
   DecodeTime(Time,hr, min, sec, ms);
   writeln (format('Hour: %d:',[hr]));
   writeln (format('Minutes: %d:',[min]));
   writeln (format('Seconds: %d:',[sec]));
   writeln (format('Milliseconds: %d:',[hr]));
end.

上記のコードをコンパイルして実行すると、次の結果が得られました。

Date and Time at the time of writing : 7/24/2012 8:26:
Today is Tuesday
Details of Date:
Day:24
Month:7
Year: 2012
Details of Time:
Hour: 8
Minutes: 26
Seconds: 21
Milliseconds: 8

太陽、地球、月などのさまざまなオブジェクトで作られた宇宙を想像できます。同様に、ホイール、ステアリング、ギアなどのさまざまなオブジェクトで作られた車を想像できます。同様に、オブジェクト指向のプログラミングの概念があります。すべてをオブジェクトと見なし、さまざまなオブジェクトを使用してソフトウェアを実装します。Pascalには、実世界のオブジェクトを実装するために使用される2つの構造データ型があります。

  • オブジェクトタイプ
  • クラスタイプ

オブジェクト指向の概念

詳細に進む前に、オブジェクト指向パスカルに関連する重要なパスカル用語を定義しましょう。

  • Object−オブジェクトは、レコードのようなフィールドを含む特別な種類のレコードです。ただし、レコードとは異なり、オブジェクトにはオブジェクトの一部としてプロシージャと関数が含まれています。これらのプロシージャと関数は、オブジェクトのタイプに関連付けられたメソッドへのポインタとして保持されます。

  • Class−クラスはオブジェクトとほぼ同じ方法で定義されますが、作成方法に違いがあります。クラスはプログラムのヒープに割り当てられますが、オブジェクトはスタックに割り当てられます。これはオブジェクトへのポインタであり、オブジェクト自体ではありません。

  • Instantiation of a class−インスタンス化とは、そのクラスタイプの変数を作成することを意味します。クラスは単なるポインタであるため、クラスタイプの変数が宣言されると、オブジェクト全体ではなく、ポインタにのみメモリが割り当てられます。コンストラクターの1つを使用してインスタンス化された場合にのみ、オブジェクトにメモリーが割り当てられます。クラスのインスタンスは「オブジェクト」とも呼ばれますが、ObjectPascalオブジェクトと混同しないでください。このチュートリアルでは、Pascalオブジェクトの場合は「Object」、概念オブジェクトまたはクラスインスタンスの場合は「object」と記述します。

  • Member Variables −これらは、クラスまたはオブジェクト内で定義された変数です。

  • Member Functions −これらは、クラスまたはオブジェクト内で定義された関数またはプロシージャであり、オブジェクトデータにアクセスするために使用されます。

  • Visibility of Members−オブジェクトまたはクラスのメンバーは、フィールドとも呼ばれます。これらのフィールドには、異なる可視性があります。可視性とは、メンバーのアクセス可能性、つまり、これらのメンバーがアクセスできる場所を指します。オブジェクトには、パブリック、プライベート、保護の3つの可視性レベルがあります。クラスには、パブリック、プライベート、厳密にプライベート、保護、公開の5つの可視性タイプがあります。可視性について詳しく説明します。

  • Inheritance−親クラスの既存の機能を継承することによってクラスが定義されている場合、そのクラスは継承されていると言われます。ここで、子クラスは、親クラスのすべてまたは少数のメンバー関数と変数を継承します。オブジェクトも継承できます。

  • Parent Class−別のクラスに継承されるクラス。これは、基本クラスまたはスーパークラスとも呼ばれます。

  • Child Class−別のクラスから継承するクラス。これは、サブクラスまたは派生クラスとも呼ばれます。

  • Polymorphism−これは、同じ機能をさまざまな目的に使用できるオブジェクト指向の概念です。たとえば、関数名は同じままですが、引数の数が異なる場合があり、異なるタスクを実行できます。Pascalクラスはポリモーフィズムを実装します。オブジェクトはポリモーフィズムを実装していません。

  • Overloading−これは、引数のタイプに応じて、一部またはすべての演算子の実装が異なるタイプのポリモーフィズムです。同様に、関数も異なる実装でオーバーロードできます。Pascalクラスはオーバーロードを実装しますが、オブジェクトは実装しません。

  • Data Abstraction −実装の詳細が隠されている(抽象化されている)データの表現。

  • Encapsulation −すべてのデータとメンバー関数を一緒にカプセル化してオブジェクトを形成するという概念を指します。

  • Constructor −クラスまたはオブジェクトからオブジェクトが形成されるたびに自動的に呼び出される特殊なタイプの関数を指します。

  • Destructor −オブジェクトまたはクラスが削除されるか、スコープ外になるたびに自動的に呼び出される特殊なタイプの関数を指します。

Pascalオブジェクトの定義

オブジェクトは、型宣言を使用して宣言されます。オブジェクト宣言の一般的な形式は次のとおりです。

type object-identifier = object  
   private
   field1 : field-type;  
   field2 : field-type;  
   ...
   public
   procedure proc1;  
   function f1(): function-type;
   end;  
var objectvar : object-identifier;

2つの整数型データメンバーを持つRectangleオブジェクトを定義しましょう- length そして width これらのデータメンバーを操作するためのいくつかのメンバー関数と、長方形を描画するためのプロシージャ。

type 
   Rectangle = object  
   private  
      length, width: integer; 
   
   public  
      constructor init;  
      destructor done;  
      
      procedure setlength(l: inteter);  
      function getlength(): integer;  
      
      procedure setwidth(w: integer);  
      function getwidth(): integer;  
      
      procedure draw;
end;
var
   r1: Rectangle;
   pr1: ^Rectangle;

オブジェクトを作成した後、そのオブジェクトに関連するメンバー関数を呼び出すことができます。1つのメンバー関数は、関連オブジェクトのメンバー変数のみを処理できます。

次の例は、2つの長方形オブジェクトの長さと幅を設定し、メンバー関数を呼び出してそれらを描画する方法を示しています。

r1.setlength(3);
r1.setwidth(7);

writeln(' Draw a rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
new(pr1);
pr1^.setlength(5);
pr1^.setwidth(4);

writeln(' Draw a rectangle: ', pr1^.getlength(), ' by ' ,pr1^.getwidth());
pr1^.draw;
dispose(pr1);

以下は、Pascalでオブジェクトを使用する方法を示す完全な例です-

program exObjects;
type 
   Rectangle = object  
   private  
      length, width: integer; 
   
   public  
      procedure setlength(l: integer);
      function getlength(): integer;  
      
      procedure setwidth(w: integer);  
      function getwidth(): integer;  
      
      procedure draw;
end;
var
   r1: Rectangle;
   pr1: ^Rectangle;

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;  
begin
   getlength := length;
end;

function Rectangle.getwidth(): integer;  
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var 
   i, j: integer;
begin
   for i:= 1 to length do
   begin
     for j:= 1 to width do
        write(' * ');
     writeln;
   end;
end;

begin
   r1.setlength(3);
   r1.setwidth(7);
   
   writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
   r1.draw;
   new(pr1);
   pr1^.setlength(5);
   pr1^.setwidth(4);
   
   writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
   pr1^.draw;
   dispose(pr1);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *

オブジェクトメンバーの可視性

可視性は、オブジェクトメンバーのアクセス可能性を示します。Pascalオブジェクトメンバーには3種類の可視性があります-

シニア番号 可視性とアクセシビリティ
1

Public

メンバーは、プログラムユニット外の他のユニットで使用できます。

2

Private

メンバーは、現在のユニットでのみアクセスできます。

3

Protected

メンバーは、親オブジェクトの子孫であるオブジェクトのみが使用できます。

デフォルトでは、オブジェクトのフィールドとメソッドはパブリックであり、現在のユニットの外部にエクスポートされます。

Pascalオブジェクトのコンストラクタとデストラクタ-

Constructorsは特殊なタイプのメソッドであり、オブジェクトが作成されるたびに自動的に呼び出されます。キーワードコンストラクターを使用してメソッドを宣言するだけで、Pascalでコンストラクターを作成します。従来、メソッド名はInitですが、独自の有効な識別子を指定できます。コンストラクター関数には、必要な数の引数を渡すことができます。

Destructorsオブジェクトの破棄中に呼び出されるメソッドです。デストラクタメソッドは、コンストラクタによって作成されたメモリ割り当てをすべて破棄します。

次の例では、Rectangleクラスのコンストラクタとデストラクタを提供します。これらは、オブジェクトの作成時に長方形の長さと幅を初期化し、スコープ外になると長方形を破棄します。

program exObjects;
type 
   Rectangle = object  
   private  
      length, width: integer; 
   public  
      constructor init(l, w: integer);
      destructor done;
      
      procedure setlength(l: integer);
      function getlength(): integer;  
      
      procedure setwidth(w: integer);  
      function getwidth(): integer;  
      
      procedure draw;
end;

var
   r1: Rectangle;
   pr1: ^Rectangle;

constructor Rectangle.init(l, w: integer);
begin
   length := l;
   width := w;
end;

destructor Rectangle.done;
begin
   writeln(' Desctructor Called');
end; 

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;  
begin
   getlength := length;
end;

function Rectangle.getwidth(): integer;  
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var 
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write(' * ');
      writeln;
   end;
end;

begin
   r1.init(3, 7);
   writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
   r1.draw;
   new(pr1, init(5, 4));
   
   writeln('Draw a rectangle:', pr1^.getlength(), ' by ',pr1^.getwidth());
   pr1^.draw;
   pr1^.init(7, 9);
   
   writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
   pr1^.draw;
   dispose(pr1);
   r1.done;
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *
Draw a rectangle: 7 by 9
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
Destructor Called

Pascalオブジェクトの継承

Pascalオブジェクトは、オプションで親オブジェクトから継承できます。次のプログラムは、Pascalオブジェクトの継承を示しています。名前の付いた別のオブジェクトを作成しましょうTableTop、Rectangleオブジェクトから継承しています。

program exObjects;
type 
   Rectangle = object  
   private  
      length, width: integer; 
   public  
      procedure setlength(l: integer);  
      function getlength(): integer;  
      procedure setwidth(w: integer);  
      function getwidth(): integer;  
      procedure draw;
end;

TableTop = object (Rectangle)
   private
     material: string;
   public
      function getmaterial(): string;
      procedure setmaterial( m: string);
      procedure displaydetails;
      procedure draw;
end;

var
   tt1: TableTop;

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;  
begin
   getlength := length;
end;

function Rectangle.getwidth():integer;
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var 
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write(' * ');
      writeln;
  end;
end;

function TableTop.getmaterial(): string;
begin
   getmaterial := material;
end;

procedure TableTop.setmaterial( m: string);
begin
   material := m;
end;

procedure TableTop.displaydetails;
begin
   writeln('Table Top: ', self.getlength(), ' by ' , self.getwidth());
   writeln('Material: ', self.getmaterial());
end;

procedure TableTop.draw();
var
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write(' * ');
   writeln;
   end;
   writeln('Material: ', material);
end;

begin
   tt1.setlength(3);
   tt1.setwidth(7);
   tt1.setmaterial('Wood');
   tt1.displaydetails();
   writeln;
   writeln('Calling the Draw method');
   tt1.draw();
end.

以下は注意すべき重要なポイントです-

  • オブジェクトTabletopは、Rectangleオブジェクトのすべてのメンバーを継承しています。

  • TableTopにもdrawメソッドがあります。TableTopオブジェクトを使用してdrawメソッドが呼び出されると、TableTopのdrawが呼び出されます。

  • 名前の付いた暗黙のインスタンスがあります self これは、オブジェクトの現在のインスタンスを参照します。

上記のコードをコンパイルして実行すると、次の結果が得られます。

Table Top: 3 by 7
Material: Wood

Calling the Draw Method 
* * * * * * *
* * * * * * *
* * * * * * *
Material: Wood

Pascalオブジェクトは、オブジェクト指向パラダイムのいくつかの特性を示すことを確認しました。カプセル化、データ隠蔽、継承を実装しますが、制限もあります。たとえば、Pascalオブジェクトはポリモーフィズムに参加しません。そのため、クラスは、プログラム、特にGUIベースのソフトウェアで適切なオブジェクト指向の動作を実装するために広く使用されています。

クラスはオブジェクトとほぼ同じ方法で定義されますが、オブジェクト自体ではなく、オブジェクトへのポインタです。技術的には、これは、クラスがプログラムのヒープに割り当てられるのに対し、オブジェクトはスタックに割り当てられることを意味します。つまり、変数をオブジェクトタイプとして宣言すると、スタック上でオブジェクトのサイズと同じ量のスペースが必要になりますが、クラスタイプの変数を宣言すると、常にポインターのサイズになります。スタック上。実際のクラスデータはヒープ上にあります。

パスカルクラスの定義

クラスは、型宣言を使用して、オブジェクトと同じ方法で宣言されます。クラス宣言の一般的な形式は次のとおりです。

type class-identifier = class  
   private
      field1 : field-type;  
      field2 : field-type;  
        ...
   
   public
      constructor create();
      procedure proc1;  
      function f1(): function-type;
end;  
var classvar : class-identifier;

以下の重要な点に注意する価値があります-

  • クラス定義は、プログラムの型宣言部分にのみ含まれる必要があります。

  • クラスは、を使用して定義されます class キーワード。

  • フィールドは、クラスの各インスタンスに存在するデータ項目です。

  • メソッドは、クラスの定義内で宣言されます。

  • と呼ばれる事前定義されたコンストラクタがあります CreateRootクラスで。すべての抽象クラスとすべての具象クラスはRootの子孫であるため、すべてのクラスには少なくとも1つのコンストラクターがあります。

  • と呼ばれる事前定義されたデストラクタがあります DestroyRootクラスで。すべての抽象クラスとすべての具象クラスはRootの子孫であるため、すべてのクラスには少なくとも1つのデストラクタがあります。

長さと幅の2つの整数型データメンバーと、これらのデータメンバーを操作するためのいくつかのメンバー関数と長方形を描画するプロシージャを持つRectangleクラスを定義しましょう。

type
   Rectangle = class
   private
      length, width: integer;
   
   public
      constructor create(l, w: integer);
      procedure setlength(l: integer);
      function getlength(): integer;
      procedure setwidth(w: integer);
      function getwidth(): integer;
      procedure draw;
end;

長方形クラスのインスタンスを作成し、長方形を描画する完全なプログラムを作成しましょう。これは、Pascalオブジェクトについて説明したときに使用したのと同じ例です。次の例外を除いて、両方のプログラムはほぼ同じであることがわかります-

  • クラスを使用するには、{$ modeobjfpc}ディレクティブを含める必要があります。

  • コンストラクターを使用するには、{$ m +}ディレクティブを含める必要があります。

  • クラスのインスタンス化は、オブジェクトのインスタンス化とは異なります。変数を宣言するだけではインスタンス用のスペースは作成されません。コンストラクターcreateを使用してメモリを割り当てます。

これが完全な例です-

{$mode objfpc} // directive to be used for defining classes {$m+}		   // directive to be used for using constructor

program exClass;
type
   Rectangle = class
   private
      length, width: integer;
   
   public
      constructor create(l, w: integer);
      procedure setlength(l: integer);
      
      function getlength(): integer;
      procedure setwidth(w: integer);
      
      function getwidth(): integer;
      procedure draw;
end;
var
   r1: Rectangle;

constructor Rectangle.create(l, w: integer);
begin
   length := l;
   width := w;
end;

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;
begin
   getlength := length;
end;

function Rectangle.getwidth(): integer;
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write(' * ');
      writeln;
   end;
end;

begin
   r1:= Rectangle.create(3, 7);
   
   writeln(' Draw Rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
   r1.draw;
   r1.setlength(4);
   r1.setwidth(6);
   
   writeln(' Draw Rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
   r1.draw;
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Draw Rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw Rectangle: 4 by 6
* * * * * * 
* * * * * * 
* * * * * * 
* * * * * *

クラスメンバーの可視性

可視性は、クラスメンバーのアクセシビリティを示します。パスカルクラスのメンバーには、5種類の可視性があります-

シニア番号 可視性とアクセシビリティ
1

Public

これらのメンバーはいつでもアクセスできます。

2

Private

これらのメンバーには、クラス定義を含むモジュールまたはユニットでのみアクセスできます。これらは、クラスメソッドの内部または外部からアクセスできます。

3

Strict Private

これらのメンバーには、クラス自体のメソッドからのみアクセスできます。同じユニット内の他のクラスまたは子孫クラスはそれらにアクセスできません。

4

Protected

これはprivateと同じですが、これらのメンバーは、他のモジュールに実装されている場合でも、子孫タイプにアクセスできる点が異なります。

5

Published

これはPublicと同じですが、コンパイラーが{$ M +}状態の場合、コンパイラーはこれらのクラスの自動ストリーミングに必要な型情報を生成します。公開されたセクションで定義されたフィールドは、クラスタイプである必要があります。

Pascalクラスのコンストラクタとデストラクタ

コンストラクターは特別なメソッドであり、オブジェクトが作成されるたびに自動的に呼び出されます。したがって、コンストラクター関数を介して多くのものを初期化することにより、この動作を最大限に活用します。

Pascalは、コンストラクターを定義するためのcreate()と呼ばれる特別な関数を提供します。コンストラクター関数には、必要な数の引数を渡すことができます。

次の例では、Booksという名前のクラスのコンストラクターを1つ作成し、オブジェクトの作成時に本の価格とタイトルを初期化します。

program classExample;

{$MODE OBJFPC} //directive to be used for creating classes
{$M+} //directive that allows class constructors and destructors
type
   Books = Class 
   private 
      title : String; 
      price: real;
   
   public
      constructor Create(t : String; p: real); //default constructor
      
      procedure setTitle(t : String); //sets title for a book
      function getTitle() : String; //retrieves title
      
      procedure setPrice(p : real); //sets price for a book
      function getPrice() : real; //retrieves price
      
      procedure Display(); // display details of a book
end;
var
   physics, chemistry, maths: Books;

//default constructor 
constructor Books.Create(t : String; p: real);
begin
   title := t;
   price := p;
end;

procedure Books.setTitle(t : String); //sets title for a book
begin
   title := t;
end;

function Books.getTitle() : String; //retrieves title
begin
   getTitle := title;
end;

procedure Books.setPrice(p : real); //sets price for a book
begin
   price := p;
end;

function Books.getPrice() : real; //retrieves price
begin
   getPrice:= price;
end;

procedure Books.Display();
begin
   writeln('Title: ', title);
   writeln('Price: ', price:5:2);
end;

begin 
   physics := Books.Create('Physics for High School', 10);
   chemistry := Books.Create('Advanced Chemistry', 15);
   maths := Books.Create('Algebra', 7);
   
   physics.Display;
   chemistry.Display;
   maths.Display;
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Title: Physics for High School
Price: 10
Title: Advanced Chemistry
Price: 15
Title: Algebra
Price: 7

createという名前の暗黙のコンストラクタと同様に、クラスで使用されているすべてのリソースを解放できる暗黙のデストラクタメソッドdestroyもあります。

継承

Pascalクラス定義は、オプションで親クラス定義から継承できます。構文は次のとおりです-

type
childClas-identifier = class(baseClass-identifier) 
< members >
end;

次の例は、Booksクラスを継承し、要件に基づいて機能を追加する小説クラスを提供します。

program inheritanceExample;

{$MODE OBJFPC} //directive to be used for creating classes
{$M+} //directive that allows class constructors and destructors

type
   Books = Class 
   protected 
      title : String; 
      price: real;
   
   public
      constructor Create(t : String; p: real); //default constructor
      
      procedure setTitle(t : String); //sets title for a book
      function getTitle() : String; //retrieves title
      
      procedure setPrice(p : real); //sets price for a book
      function getPrice() : real; //retrieves price
      
      procedure Display(); virtual; // display details of a book
end;
(* Creating a derived class *)

type
   Novels = Class(Books)
   private
      author: String;
   
   public
      constructor Create(t: String); overload;
      constructor Create(a: String; t: String; p: real); overload;
      
      procedure setAuthor(a: String); // sets author for a book
      function getAuthor(): String; // retrieves author name
      
      procedure Display(); override;
end;
var
   n1, n2: Novels;

//default constructor 
constructor Books.Create(t : String; p: real);
begin
   title := t;
   price := p;
end;

procedure Books.setTitle(t : String); //sets title for a book
begin
   title := t;
end;

function Books.getTitle() : String; //retrieves title
begin
   getTitle := title;
end;

procedure Books.setPrice(p : real); //sets price for a book
begin
   price := p;
end;

function Books.getPrice() : real; //retrieves price
begin
   getPrice:= price;
end;

procedure Books.Display();
begin
   writeln('Title: ', title);
   writeln('Price: ', price);
end;

(* Now the derived class methods  *)
constructor Novels.Create(t: String);
begin
   inherited Create(t, 0.0);
   author:= ' ';
end;

constructor Novels.Create(a: String; t: String; p: real);
begin
   inherited Create(t, p);
   author:= a;
end;

procedure Novels.setAuthor(a : String); //sets author for a book
begin
   author := a;
end;

function Novels.getAuthor() : String; //retrieves author
begin
   getAuthor := author;
end;

procedure Novels.Display();
begin
   writeln('Title: ', title);
   writeln('Price: ', price:5:2);
   writeln('Author: ', author);
end;

begin 
   n1 := Novels.Create('Gone with the Wind');
   n2 := Novels.Create('Ayn Rand','Atlas Shrugged', 467.75);
   n1.setAuthor('Margaret Mitchell');
   n1.setPrice(375.99);
   n1.Display;
   n2.Display;
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

Title: Gone with the Wind
Price: 375.99
Author: Margaret Mitchell
Title: Atlas Shrugged
Price: 467.75
Author: Ayn Rand

以下の重要な点に注意する価値があります-

  • Booksクラスのメンバーは protected 可視性。

  • Novelsクラスには2つのコンストラクターがあるため、 overload 演算子は関数のオーバーロードに使用されます。

  • Books.Displayプロシージャが宣言されました virtual、Novelsクラスの同じメソッドができるように override それ。

  • Novels.Createコンストラクターは、を使用して基本クラスコンストラクターを呼び出します。 inherited キーワード。

インターフェイス

インターフェイスは、実装者に共通の関数名を提供するように定義されています。さまざまな実装者が、要件に応じてこれらのインターフェイスを実装できます。インターフェイスはスケルトンであり、開発者によって実装されていると言えます。以下はインターフェースの例です-

type  
   Mail = Interface  
      Procedure SendMail;  
      Procedure GetMail;  
   end;  
   
   Report = Class(TInterfacedObject,  Mail)  
      Procedure SendMail;  
      Procedure GetMail;  
   end;

クラスがインターフェースを実装する場合、インターフェースのすべてのメソッドを実装する必要があることに注意してください。インターフェイスのメソッドが実装されていない場合、コンパイラはエラーを出します。

抽象クラス

抽象クラスは、インスタンス化できず、継承されるだけのクラスです。抽象クラスは、次のように、クラス定義にシンボルabstractという単語を含めることによって指定されます。

type
   Shape = ABSTRACT CLASS (Root)
      Procedure draw; ABSTRACT;
      ...
   end;

抽象クラスから継承する場合、親のクラス宣言で抽象とマークされたすべてのメソッドは、子によって定義される必要があります。さらに、これらのメソッドは同じ可視性で定義する必要があります。

静的キーワード

クラスメンバーまたはメソッドを静的として宣言すると、クラスのインスタンス化を必要とせずにそれらにアクセスできるようになります。静的として宣言されたメンバーは、インスタンス化されたクラスオブジェクトではアクセスできません(静的メソッドではアクセスできます)。次の例は、概念を示しています-

program StaticExample;
{$mode objfpc}
{$static on}
type
   myclass=class
      num : integer;static;
   end;
var
   n1, n2 : myclass;
begin
   n1:= myclass.create;
   n2:= myclass.create;
   n1.num := 12;
   writeln(n2.num);
   n2.num := 31;
   writeln(n1.num);
   writeln(myclass.num);
   myclass.num := myclass.num + 20;
   writeln(n1.num);
   writeln(n2.num);
end.

上記のコードをコンパイルして実行すると、次の結果が得られます。

12
31
31
51
51

静的メンバーを使用するには、ディレクティブ{$ staticon}を使用する必要があります。