Pascal-quick-guide

提供:Dev Guides
移動先:案内検索

パスカル-概要

Pascalは、1970年代初頭にNiklaus Wirthによって最初に開発された汎用の高レベル言語です。 体系的な規律としてプログラミングを教え、信頼できる効率的なプログラムを開発するために開発されました。

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

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

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

パスカル言語の機能

パスカルには次の機能があります-

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

パスカルについて

  • Pascal言語は、フランスの数学者でコンピューター開発の先駆者であるBlaise Pascalにちなんで命名されました。
  • Niklaus Wirthは、1970年にオリジナルのPascalプログラミング言語の開発を完了しました。
  • Pascalは、Algolプログラミング言語のブロック構造スタイルに基づいています。
  • Pascalは、プログラミングを体系的な分野として教えるのに適した言語として開発されました。その実装は信頼性が高く効率的です。
  • ISO 7185パスカル規格は、1983年に最初に公開されました。
  • パスカルは、Apple LisaおよびMacの初期の開発で使用された主要な高レベル言語でした。
  • 1986年にApple Computerは最初のObject Pascal実装をリリースし、1993年にPascal標準化委員会はPascalのオブジェクト指向拡張機能を公開しました。

Pascalを使用する理由

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

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

Pascalの最も驚くべき実装の中には-

  • スカイプ
  • 総司令官
  • 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 OS XとiOSのネイティブコードを生成します。 Embarcaderoは、LinuxおよびAndroidオペレーティングシステムのサポートを構築することを計画しています。
  • Free Pascal -PascalおよびObject Pascalプログラムを実行するための無料のコンパイラです。 Free Pascalコンパイラは、Linux、Windows、OS/2、FreeBSD、Mac OS X、DOSおよびその他のプラットフォーム向けの32ビットおよび64ビットTurbo PascalおよびDelphi互換のPascalコンパイラです。
  • Turbo51 -Turbo Pascal 7構文を備えた、8051ファミリのマイクロコントローラ用の無料のPascalコンパイラです。
  • Oxygene -.NETおよびMonoプラットフォーム用のObject Pascalコンパイラです。
  • * GNU Pascal(GPC)*-GNU Compiler Collectionのフロントエンドで構成されるPascalコンパイラです。

これらのチュートリアルでは、Free Pascalを使用します。 オペレーティングシステム用のFree Pascalは、次のリンクからダウンロードできます:https://www.freepascal.org/download.var[Download Free Pascal]

LinuxにFree Pascalをインストールする

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

  • tar.gz バージョン。個別のファイルとしても利用できます。
  • .rpm (Red Hat Package Manager)バージョン。
  • .deb (Debian)バージョン。
rpm -i fpc-X.Y.Z-N.ARCH.rpm

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

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

dpkg -i fpc-XXX.deb

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

詳細については、https://www.freepascal.org/docs-html/user/usersu5l [Free Pascalインストールガイド]をご覧ください。

MacにFree Pascalをインストールする

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

WindowsにFree Pascalをインストールする

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

  • ディレクトリを選択します。
  • インストールするパッケージの部分を選択します。
  • オプションで、.ppまたは.pas拡張子をFree Pascal IDEに関連付けることを選択します。

詳細については、https://www.freepascal.org/docs-html/user/usersu3l [Free Pascalインストールガイド]をご覧ください。

テキストエディタ

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

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

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

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

パスカル-プログラム構造

Pascalプログラミング言語の基本的な構成要素を学習する前に、次の章で参照できるように、最小限の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 }

パスカルハローワールドの例

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

program HelloWorld;
uses crt;

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

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

Hello, World!

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

  • プログラムの最初の行 program HelloWorld; は、プログラムの名前を示します。 プログラムの2行目はcrtを使用します; はプリプロセッサコマンドで、実際のコンパイルに進む前にcrtユニットを含めるようコンパイラに指示します。
  • beginステートメントとendステートメントで囲まれた次の行は、メインプログラムブロックです。 Pascalのすべてのブロックは、 begin ステートメントと end ステートメントで囲まれています。 ただし、メインプログラムの終了を示す終了ステートメントの後には、セミコロン(;)の代わりに完全なストップ(。)が続きます。
  • メインプログラムブロックの begin ステートメントは、プログラムの実行が開始される場所です。
  • ( *…​ )*内の行はコンパイラによって無視され、プログラムに*コメント*を追加するために配置されています。
  • ステートメント writeln( 'Hello、World!'); は、Pascalで使用可能なwriteln関数を使用し、「Hello、World!」というメッセージを表示します。画面に表示されます。
  • ステートメント readkey; は、ユーザーがキーを押すまで表示を一時停止します。 これはcrtユニットの一部です。 ユニットは、Pascalのライブラリのようなものです。
  • 最後のステートメント* end。*はプログラムを終了します。

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

  • テキストエディターを開き、上記のコードを追加します。
  • ファイルを_hello.pas_として保存します
  • コマンドプロンプトを開き、ファイルを保存したディレクトリに移動します。
  • コマンドプロンプトでfpc hello.pasと入力し、Enterキーを押してコードをコンパイルします。
  • コードにエラーがない場合、コマンドプロンプトは次の行に移動し、 hello 実行可能ファイルと hello.o オブジェクトファイルを生成します。
  • ここで、コマンドプロンプトで hello と入力して、プログラムを実行します。
  • 画面に「Hello World」と表示され、キーを押すまでプログラムが待機します。
$ 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変数は、関数のコード本体の外側で宣言されます。つまり、 beginend のペア内では宣言されませんが、プロシージャ/関数の定義後、 begin キーワードの前で宣言されます。 グローバル変数の場合、プログラムヘッダーの後に定義されます。

機能/手順

Pascalでは、 procedure は実行する命令のセットであり、戻り値はありません。 function は戻り値を持つプロシージャです。 関数/手順の定義は次のようになります-

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

コメント

複数行コメントは、中括弧とアスタリスクで囲まれています( …​ ). Pascalでは、中括弧\ {…​ }.

( *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で同じ意味を持ちます。

パスカルステートメント

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

たとえば-

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

Pascalの予約語

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

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

and array begin case const
div do downto else end
file for function goto if
in label mod nil not
of or packed procedure program
record repeat set then to
type until var while with

パスカルの文字セットと識別子

パスカル文字セットはで構成されています-

  • すべて大文字(A-Z)
  • すべての小文字(a-z)
  • すべての数字(0-9) 特殊記号-+/:=、。 ;. ()[] = \ {} `空白

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

パスカル-データ型

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

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

Pascalデータ型

パスカルのデータ型は、次の図に以下のように要約することができます-

Pascalデータ型

型宣言

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

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

たとえば、次の宣言では、変数の日数と年齢を整数型、yesとtrueをブール型、名前と市を文字列型、料金と費用を実数型として定義しています。

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

整数型

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

Type Minimum Maximum Format
Integer -2147483648 2147483647 signed 32-bit
Cardinal 0 4294967295 unsigned 32-bit
Shortint -128 127 signed 8-bit
Smallint -32768 32767 signed 16-bit
Longint -2147483648 2147483647 signed 32-bit
Int64 -2^63 2^63 - 1 signed 64-bit
Byte 0 255 unsigned 8-bit
Word 0 65535 unsigned 16-bit
Longword 0 4294967295 unsigned 32-bit

定数

定数を使用すると、プログラムが読みやすくなり、プログラムの先頭の特定の場所に特別な量を保持するのに役立ちます。 Pascalでは、numerical、logical、string、および_character_定数を使用できます。 const 宣言を指定することにより、プログラムの宣言部分で定数を宣言できます。

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

const
Identifier = contant_value;

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

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

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

列挙型

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

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月の前に、というように続きます。 列挙型識別子のドメインは、数値定数または文字定数で構成することはできません。

部分範囲タイプ

サブレンジ型により、変数は特定の範囲内にある値をとることができます。 たとえば、有権者の_age_が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の各変数には特定のタイプがあり、変数のメモリのサイズとレイアウトを決定します。そのメモリ内に保存できる値の範囲。変数に適用できる一連の操作。

変数の名前は、文字、数字、およびアンダースコア文字で構成できます。 文字またはアンダースコアで始まる必要があります。 Pascalは大文字と小文字を区別しないため、大文字と小文字は同じ意味です。 前の章で説明した基本タイプに基づいて、次の基本変数タイプがあります-

Pascalの基本変数

Sr.No Type & Description
1

Character

通常、単一のオクテット(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;

_type_宣言と_var_宣言の違いに注意してください。 型宣言は、整数、実数などの型のカテゴリまたはクラスを示しますが、変数の仕様は、変数が取る値の型を示します。 Pascalの_type_宣言を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
  • ひも

定数の宣言

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

const
identifier = constant_value;

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

シニア

定数タイプと例

1

順序(整数)型定数

valid_age = 21;

2

タイプ定数を設定

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

3

ポインタ型定数

P = NIL;

4

実数型定数

e = 2.7182818;

velocity_light = 3.0E + 10;

5

文字型定数

演算子= '+';

6

  • 文字列型定数 *

社長=「ジョニー・デップ」;

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

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では、数値変数を使用したこのような出力フォーマットが可能です。

パスカル-演算子

演算子は、特定の数学的または論理的な操作を実行するようコンパイラーに指示する記号です。 パスカルは、演算子の次のタイプを許可します-

  • 算術演算子
  • 関係演算子
  • ブール演算子
  • ビット演算子
  • 集合演算子
  • 文字列演算子

算術演算子、関係演算子、ブール演算子、ビット演算子を1つずつ説明します。 集合演算子と文字列操作については後で説明します。

算術演算子

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

リンク:/pascal/pascal_arithmetic_operators [例を表示]

Operator Description Example
+ Adds two operands A + B will give 30
- Subtracts second operand from the first A - B will give -10
* Multiplies both operands A* B will give 200
/ Divides numerator by denominator B/A will give 2
% Modulus Operator and remainder of after an integer division B % A will give 0

関係演算子

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

リンク:/pascal/pascal_relational_operators [例を表示]

Operator Description Example
= Checks if the values of two operands are equal or not, if yes, then condition becomes true. (A = B) is not true.
<> Checks if the values of two operands are equal or not, if values are not equal, then condition becomes true. (A <> B) is true.
> Checks if the value of left operand is greater than the value of right operand, if yes, then condition becomes true. (A > B) is not true.
< Checks if the value of left operand is less than the value of right operand, if yes, then condition becomes true. (A < B) is true.
>= Checks if the value of left operand is greater than or equal to the value of right operand, if yes, then condition becomes true. (A >= B) is not true.
Checks if the value of left operand is less than or equal to the value of right operand, if yes, then condition becomes true. (A ⇐ B) is true.

ブール演算子

次の表は、Pascal言語でサポートされているすべてのブール演算子を示しています。 これらの演算子はすべてブール値オペランドで機能し、ブール値の結果を生成します。 変数 A が真を保持し、変数 B が偽を保持すると仮定します-

リンク:/pascal/pascal_boolean_operators [例を表示]

Operator Description Example
and Called Boolean AND operator. If both the operands are true, then condition becomes true. (A and B) is false.
and then It is similar to the AND operator, however, it guarantees the order in which the compiler evaluates the logical expression. Left to right and the right operands are evaluated only when necessary. (A and then B) is false.
or Called Boolean OR Operator. If any of the two operands is true, then condition becomes true. (A or B) is true.
or else It is similar to Boolean OR, however, it guarantees the order in which the compiler evaluates the logical expression. Left to right and the right operands are evaluated only when necessary. (A or else B) is true.
not Called Boolean NOT Operator. Used to reverse the logical state of its operand. If a condition is true, then Logical NOT operator will make it false. not (A and B) is true.

ビット演算子

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

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

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を保持すると仮定すると:

link:/pascal/pascal_bit_operators [例を表示]

[cols=",,",options="header",]
|===
|Operator |Description |Example |& |Binary AND Operator copies a bit to the result if it exists in both operands. |(A & B) will give 12, which is 0000 1100 || |Binary OR Operator copies a bit if it exists in either operand. |(A | B) will give 61, which is 0011 1101 |! |Binary OR Operator copies a bit if it exists in either operand. Its same as | operator. |(A ! B) will give 61, which is 0011 1101 |~ |Binary Ones Complement Operator is unary and has the effect of 'flipping' bits. |(~A ) will give -61, which is 1100 0011 in 2's complement form due to a signed binary number. |<< |Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand. |A << 2 will give 240, which is 1111 0000 |>> |Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand. |A >> 2 will give 15, which is 0000 1111
|===

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

[cols=",",options="header",]
|===
|Operators |Operations |not |Bitwise NOT |and |Bitwise AND |or |Bitwise OR |xor |Bitwise exclusive OR |shl |Bitwise shift left |shr |Bitwise shift right |<< |Bitwise shift left |>> |Bitwise shift right
|===

=== パスカルでの演算子の優先順位

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

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

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

リンク:/pascal/pascal_operators_precedence [例を表示]

[cols=",",options="header",]
|===
|Operator |Precedence |~, not, |Highest |*,/, div, mod, and, & | ||, !, +, -, or, | |=, <>, <, <=, >, >=, in | |or else, and then |Lowest
|===

パスカル-意思決定

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

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

Pascalの意思決定ステートメント

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

Sr.No Statement & Description
1

if - then statement

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

If-then-else statement

  • if-thenステートメント*の後に、オプションの* elseステートメント*を続けることができます。これは、ブール式が偽のときに実行されます。
3

nested if statements

1つの if または else if ステートメントを別の if または else if ステートメント内で使用できます。

4

case statement

  • case* ステートメントを使用すると、変数を値のリストと等しいかどうかをテストできます。
5

case - else statement

これは if-then-else ステートメントに似ています。 ここでは、 case の後に else という用語が続きます。

6

nested case statements

1つの case ステートメントを別の case ステートメント内で使用できます。

パスカル-ループ

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

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

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

ループアーキテクチャ

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

Sr.No Loop Type & Description
1

while-do loop

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

2

for-do loop

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

3

repeat-until loop

whileステートメントと似ていますが、ループ本体の最後で条件をテストします。

4

nested loops

while、for、またはuntil untilループで、1つ以上のループを別のループ内で使用できます。

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

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

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

Sr.No Control Statement & Description
1

break statement

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

continue statement

ループがその本体の残りをスキップし、反復する前にその状態をすぐに再テストします。

3

goto statement

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

パスカル-関数

サブプログラム

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

パスカルは2種類のサブプログラムを提供します-

  • 関数-これらのサブプログラムは単一の値を返します。
  • 手順-これらのサブプログラムは値を直接返しません。

関数

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

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

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

関数を定義する

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

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

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

Pascalの関数定義は、関数 header 、ローカル declarations 、および関数 body で構成されています。 関数ヘッダーは、キーワードfunctionと、関数に指定された name で構成されます。 ここに関数のすべての部分があります-

  • 引数-引数は、呼び出し側プログラムと関数識別子の間のリンクを確立し、仮パラメータとも呼ばれます。 パラメーターはプレースホルダーのようなものです。 関数が呼び出されると、パラメーターに値を渡します。 この値は、実パラメーターまたは引数と呼ばれます。 パラメータリストは、関数のパラメータのタイプ、順序、および数を参照します。 このような仮パラメータの使用はオプションです。 これらのパラメーターには、標準データ型、ユーザー定義データ型、またはサブレンジデータ型があります。 +関数ステートメントに表示される仮パラメータリストは、単純変数または添え字付き変数、配列または構造化変数、またはサブプログラムです。
  • 戻り値の型-すべての関数は値を返す必要があるため、すべての関数に型を割り当てる必要があります。 function-type は、関数が返す値のデータ型です。 標準のユーザー定義のスカラー型またはサブレンジ型の場合がありますが、構造化型にすることはできません。
  • ローカル宣言-ローカル宣言は、ラベル、定数、変数、関数、およびプロシージャの宣言を参照します。これらは、関数の本体のみに適用されます。
  • 関数本体-関数本体には、関数の動作を定義するステートメントのコレクションが含まれています。 予約語beginとendで常に囲まれている必要があります。 これは、すべての計算が行われる関数の一部です。 関数名に値を割り当てる関数本体には、タイプ- name:= expression; の割り当てステートメントが必要です。 この値は、関数が実行されたときに返されます。 本文の最後のステートメントは、終了ステートメントでなければなりません。

以下は、パスカルで関数を定義する方法を示す例です-

( *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;

関数宣言

関数*宣言*は、関数名と関数の呼び出し方法をコンパイラーに伝えます。 関数の実際の本体は個別に定義できます。

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

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

パスカル-手順

  • プロシージャ*は、単一の値を返す代わりに、結果のグループを取得できるサブプログラムです。

プロシージャの定義

Pascalでは、プロシージャは procedure キーワードを使用して定義されます。 プロシージャ定義の一般的な形式は次のとおりです-

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

Pascalのプロシージャ definition は、プロシージャの header 、ローカル declarations 、および body で構成されます。 プロシージャヘッダーは、キーワード procedure とプロシージャに付けられた名前で構成されます。 ここに手順のすべての部分があります-

  • 引数-引数は、呼び出し側プログラムとプロシージャ識別子との間のリンクを確立し、仮パラメータとも呼ばれます。 手続きの引数の規則は、関数の規則と同じです。
  • ローカル宣言-ローカル宣言は、ラベル、定数、変数、関数、およびプロシージャの宣言を参照します。これらは、プロシージャの本体のみに適用されます。
  • プロシージャ本体-プロシージャ本体には、プロシージャの動作を定義するステートメントのコレクションが含まれます。 予約語beginとendで常に囲まれている必要があります。 これは、すべての計算が行われる手順の一部です。

以下は、_findMin()_と呼ばれるプロシージャのソースコードです。 このプロシージャは、4つのパラメータx、y、z、およびmを受け取り、mという名前の変数に最初の3つの変数の最小値を格納します。 変数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 }

手続き宣言

プロシージャ*宣言*は、プロシージャ名とプロシージャの呼び出し方法をコンパイラに伝えます。 プロシージャの実際の本体は個別に定義できます。

プロシージャ宣言には次の構文があります-

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

プロシージャの名前はどのタイプにも関連付けられていないことに注意してください。 上記の定義されたプロシージャ_findMin()_の場合、以下は宣言です-

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

プロシージャの呼び出し

プロシージャの作成中に、プロシージャの実行内容の定義を指定します。 プロシージャを使用するには、そのプロシージャを呼び出して定義済みのタスクを実行する必要があります。 プログラムがプロシージャを呼び出すと、プログラム制御は呼び出されたプロシージャに転送されます。 呼び出されたプロシージャは定義されたタスクを実行し、最後のendステートメントに到達すると、呼び出し元プログラムに制御を返します。

プロシージャを呼び出すには、以下に示すように、プロシージャ名とともに必要なパラメータを渡す必要があります-

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

以下は、*再帰*関数を使用して指定された数の*フィボナッチ数列*を生成する別の例です-

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

サブプログラムの引数

サブプログラム(関数またはプロシージャ)が引数を使用する場合、引数の値を受け入れる変数を宣言する必要があります。 これらの変数は、サブプログラムの*仮パラメータ*と呼ばれます。

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

サブプログラムを呼び出している間、引数をサブプログラムに渡すことができる2つの方法があります-

Sr.No Call Type & Description
1

Call by value

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

2

Call by reference

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

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

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

パスカル-可変範囲

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

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

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

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

    *local* および *global* 変数と仮パラメーターとは何かを説明しましょう。

ローカル変数

サブプログラムまたはブロック内で宣言される変数は、ローカル変数と呼ばれます。 それらは、そのサブプログラムまたはコードブロック内にあるステートメントでのみ使用できます。 ローカル変数は、それ自身の外部のサブプログラムには知られていません。 以下は、ローカル変数を使用した例です。 ここで、すべての変数_a b_、および_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という名前のプロシージャを作成します。このプロシージャには、変数_a b_、および_c_のセットがあり、プログラム_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

グローバル変数

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

*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

プロシージャ表示は、変数a、b、cにアクセスできることに注意してください。変数a、b、cは、表示に関してグローバル変数であると同時に、独自のローカル変数です。 プログラムはローカル変数とグローバル変数に同じ名前を持つことができますが、関数内のローカル変数の値が優先されます。

前の例を少し変更してみましょう。手順表示のローカル変数は、a _、 b c_と同じ名前になります-

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は、システムと実装に応じて、さまざまなタイプの文字列オブジェクトを提供します。 プログラムで使用されるより一般的なタイプの文字列について説明します。

あなたは多くの方法で文字列を定義することができます-

  • 文字配列-これは、一重引用符で囲まれたゼロ以上のバイトサイズの文字のシーケンスである文字列です。
  • 文字列変数-Turbo Pascalで定義されている文字列型の変数。
  • 短い文字列-サイズが指定された文字列型の変数。
  • ヌル文字列- pchar 型の変数。
  • AnsiStrings -Ansistringsは長さ制限のない文字列です。

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

Sr.No. Function & Purpose
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;

パスカル文字列をコピーします

34

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

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

35

function UpperCase(const s:):;

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

パスカル-ブール値

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

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

Free Pascalは、 ByteBoolWordBool 、および LongBool タイプもサポートしています。 これらは、それぞれバイト、ワード、または倍長整数型です。

値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]、numbers2、および…​、numbers [100]を使用して表現します個々の変数。 配列内の特定の要素は、インデックスによってアクセスされます。

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

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

Pascalの配列

配列の宣言

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

一次元配列の型宣言の一般的な形式は-

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プログラマーに明らかな配列に関連するいくつかの重要な概念があります-

Sr.No Concept & Description
1

Multi-dimensional arrays

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

2

Dynamic array

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

3

Packed array

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

4

Passing arrays to subprograms

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

パスカル-ポインター

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でメモリアドレスを印刷する

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プログラマーにとっては明確なはずです-

Sr.No Concept & Description
1

Pascal - Pointer arithmetic

ポインターで使用できる4つの算術演算子があります:増分、減分、+、-

2

Pascal - Array of pointers

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

3

Pascal - Pointer to pointer

Pascalでは、ポインターにポインターを付けることができます。

4

Passing pointers to subprograms in Pascal

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

5

Return pointer from subprograms in Pascal

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

パスカル-レコード

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

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

  • タイトル
  • 著者
  • 件名
  • ブックID

レコードを定義する

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

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

以下は、Bookレコードを宣言する方法です-

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は、variantという名前の一意のタイプのストレージをサポートしています。 バリアント変数には、任意の単純なタイプの値を割り当てることができます。 バリアントに保存される値のタイプは、実行時にのみ決定されます。 ほぼすべての単純型をバリアントに割り当てることができます:順序型、文字列型、int64型。

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

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

バリアントの宣言

*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では、設定されたデータ型を定義できます。 セット内の要素は、そのメンバーと呼ばれます。 数学では、集合は_braces \ {} _でメンバーを囲むことによって表されます。 ただし、Pascalでは、セット要素は角括弧[]で囲まれ、セットコンストラクターと呼ばれます。

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

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

type
set-identifier = set of base type;

セット型の変数は次のように定義されます

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

or,

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セットで次のセット操作を実行できます。

Sr.No Operations & Descriptions
1

Union

これにより2つのセットが結合され、両方のセットのメンバーを持つ新しいセットが作成されます。

2

Difference

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

3

Intersection

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

4

Inclusion

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

5

Symmetric difference

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

6

In

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

次の表は、Free Pascalでサポートされているすべての集合演算子を示しています。 S1S2 は2つの文字セットであり、

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

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

Operator Description Example
+ Union of two sets

S1 + S2 will give a set

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

- Difference of two sets

S1 - S2 will give a set

['a'、 'b']

* Intersection of two sets

S1* S2 will give a set

{空} ['c']

>< Symmetric difference of two sets S1 >< S2 will give a set ['a', 'b', 'd', 'e']
= Checks equality of two sets S1 = S2 will give the boolean value False
<> Checks non-equality of two sets S1 <> S2 will give the boolean value True
Contains (Checks if one set is a subset of the other) S1 ⇐ S2 will give the boolean value False
Include Includes an element in the set; basically it is the Union of a set and an element of same base type

Include (S1, ['d']) will give a set

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

Exclude Excludes an element from a set; basically it is the Difference of a set and an element of same base type

Exclude (S2, ['d']) will give a set

['c'、 'e']

In Checks set membership of an element in a set ['e'] in S2 gives the boolean value 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;

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

学生の記録用のデータファイルを作成するプログラムを作成しましょう。 student.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_という名前のファイルを作業ディレクトリに作成します。 メモ帳などのテキストエディタを使用してファイルを開き、John Smithのデータを確認できます。

ファイルからの読み取り

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

サブプログラムでファイルパラメータを使用する場合、varパラメータとして宣言する必要があることに注意してください。

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は、ファイル処理のために次の関数/手順を提供します-

Sr.No. Function Name & Description
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;

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

Pascalは、ポインター変数を作成するための手順* 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

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

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

プログラムが出てくると、オペレーティングシステムはプログラムによって割り当てられたすべてのメモリを自動的に解放しますが、メモリが不要になった場合は、そのメモリを解放することをお勧めします。

Pascalには、プロシージャ* new。を使用して動的に作成された変数を解放するプロシージャ *dispose が用意されています。 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での低レベルプログラミングの実装に使用されるメモリ管理機能を提供します。 これらの関数の多くは実装に依存しています。 無料のパスカルは、メモリ管理のために以下の機能と手順を提供します-

S.N Function Name & Description
1

function Addr(X: TAnytype):Pointer;

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

2

function Assigned(P: Pointer):Boolean;

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

3

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

バイトごとに2つのメモリバッファを比較します

4

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

バイトごとに2つのメモリバッファを比較します

5

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

バイトごとに2つのメモリバッファを比較します

6

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

バイトごとに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-Variants_チュートリアルでバリアントユニットを使用しています。 このチュートリアルでは、ユーザー定義ユニットの作成と組み込みについて説明します。 ただし、まずプログラムに組み込みユニット 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チュートリアルの最初に使用したものと同じプログラムで、コンパイルして実行し、変更の効果を見つけます。

Pascalユニットの作成と使用

ユニットを作成するには、保存するモジュールまたはサブプログラムを作成し、*。pas *拡張子の付いたファイルに保存する必要があります。 このファイルの最初の行は、キーワードunitで始まり、その後にユニット名が続く必要があります。 たとえば-

unit calculateArea;

以下は、Pascalユニットを作成する際の3つの重要なステップです-

  • ファイルの名前とユニットの名前はまったく同じでなければなりません。 したがって、ユニット_calculateArea_は_calculateArea.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;

さまざまな日付と時刻の関数

無料のパスカルは、次の日付と時刻の機能を提供します-

Sr.No. Function Name & Description
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;Converts DateTime to timestamp
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-Oriented Pascalに関連する重要なPascal用語を定義しましょう。

  • オブジェクト-オブジェクトは、レコードのようなフィールドを含む特別な種類のレコードです。ただし、レコードとは異なり、オブジェクトにはオブジェクトの一部としてプロシージャと関数が含まれます。 これらのプロシージャと関数は、オブジェクトの型に関連付けられたメソッドへのポインタとして保持されます。
  • クラス-クラスはオブジェクトとほぼ同じ方法で定義されますが、作成方法に違いがあります。 クラスはプログラムのヒープに割り当てられ、オブジェクトはスタックに割り当てられます。 オブジェクト自体ではなく、オブジェクトへのポインタです。
  • クラスのインスタンス化-インスタンス化とは、そのクラスタイプの変数を作成することを意味します。 クラスは単なるポインターであるため、クラス型の変数が宣言されると、オブジェクト全体ではなく、ポインターのみにメモリが割り当てられます。 コンストラクターの1つを使用してインスタンス化された場合のみ、メモリがオブジェクトに割り当てられます。 クラスのインスタンスは「オブジェクト」とも呼ばれますが、Object Pascalオブジェクトと混同しないでください。 このチュートリアルでは、Pascalオブジェクトには「オブジェクト」を、概念オブジェクトまたはクラスインスタンスには「オブジェクト」を記述します。
  • メンバー変数-これらは、クラスまたはオブジェクト内で定義された変数です。
  • メンバー関数-これらは、クラスまたはオブジェクト内で定義された関数またはプロシージャであり、オブジェクトデータにアクセスするために使用されます。
  • メンバーの可視性-オブジェクトまたはクラスのメンバーは、フィールドとも呼ばれます。 これらのフィールドには異なる可視性があります。 可視性とは、メンバーのアクセス可能性、つまり、これらのメンバーがアクセス可能な場所を指します。 オブジェクトには、パブリック、プライベート、保護の3つの可視性レベルがあります。 クラスには、パブリック、プライベート、厳密にプライベート、保護、公開の5つの可視性タイプがあります。 可視性について詳しく説明します。
  • 継承-親クラスの既存の機能を継承することによってクラスが定義される場合、継承されると言われます。 ここで、子クラスは親クラスのすべてまたはいくつかのメンバー関数と変数を継承します。 オブジェクトを継承することもできます。
  • 親クラス-別のクラスによって継承されるクラス。 これは、基本クラスまたはスーパークラスとも呼ばれます。
  • 子クラス-別のクラスから継承するクラス。 これは、サブクラスまたは派生クラスとも呼ばれます。
  • 多態性-これは、同じ機能を異なる目的に使用できるオブジェクト指向の概念です。 たとえば、関数名は同じままですが、引数の数が異なり、異なるタスクを実行できます。 Pascalクラスはポリモーフィズムを実装しています。 オブジェクトはポリモーフィズムを実装しません。
  • オーバーロード-これは、一部またはすべての演算子が引数のタイプに応じて異なる実装を持つポリモーフィズムのタイプです。 同様に、異なる実装で関数をオーバーロードすることもできます。 Pascalクラスはオーバーロードを実装していますが、Objectsは実装していません。
  • データの抽象化-実装の詳細が隠されている(抽象化された)データの表現。
  • カプセル化-すべてのデータとメンバー関数を一緒にカプセル化してオブジェクトを形成する概念を指します。
  • コンストラクタ-クラスまたはオブジェクトからオブジェクトが形成されるたびに自動的に呼び出される特別なタイプの関数を指します。
  • デストラクタ-オブジェクトまたはクラスが削除されるか、スコープ外になると自動的に呼び出される特別なタイプの関数を指します。

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つの整数型データメンバ- length および width と、これらのデータメンバを操作するいくつかのメンバ関数と、長方形を描画するプロシージャを持つRectangleオブジェクトを定義しましょう。

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
* * * *
* * * *
* * * *
* * * *
* * * *

オブジェクトメンバーの可視性

可視性は、オブジェクトメンバのアクセシビリティを示します。 パスカルオブジェクトのメンバーには3種類の可視性があります-

Sr.No Visibility & Accessibility
1

Public

メンバーは、プログラムユニット以外の他のユニットで使用できます。

2

Private

メンバーは現在のユニットでのみアクセス可能です。

3

Protected

メンバーは、親オブジェクトから派生したオブジェクトでのみ使用できます。

デフォルトでは、オブジェクトのフィールドとメソッドはパブリックであり、現在のユニットの外部にエクスポートされます。

Pascalオブジェクトのコンストラクタとデストラクタ-

  • コンストラクタ*は特別なタイプのメソッドであり、オブジェクトが作成されるたびに自動的に呼び出されます。 キーワードコンストラクターでメソッドを宣言するだけで、Pascalでコンストラクターを作成できます。 通常、メソッド名はInitですが、独自の有効な識別子を指定できます。 コンストラクター関数には、好きなだけ引数を渡すことができます。
  • デストラクタ*は、オブジェクトの破壊中に呼び出されるメソッドです。 デストラクタメソッドは、コンストラクタによって作成されたメモリ割り当てを破棄します。

次の例は、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オブジェクトの継承を示しています。 Rectangleオブジェクトを継承する TableTop という名前の別のオブジェクトを作成してみましょう。

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の描画が呼び出されます。
  • オブジェクトの現在のインスタンスを参照する self という名前の暗黙的なインスタンスがあります。

上記のコードをコンパイルして実行すると、次の結果が生成されます-

Table Top: 3 by 7
Material: Wood

Calling the Draw Method
* * * * * * *
* * * * * * *
* * * * * * *
Material: Wood

パスカル-クラス

Pascalオブジェクトがオブジェクト指向のパラダイムのいくつかの特徴を示すことを見てきました。 カプセル化、データ隠蔽、継承を実装しますが、制限もあります。 たとえば、Pascalオブジェクトはポリモーフィズムに参加しません。 したがって、クラスは、プログラム、特にGUIベースのソフトウェアに適切なオブジェクト指向の動作を実装するために広く使用されています。

クラスはオブジェクトとほぼ同じ方法で定義されますが、オブジェクト自体ではなく、オブジェクトへのポインタです。 技術的には、これはクラスがプログラムのヒープに割り当てられ、オブジェクトがスタックに割り当てられることを意味します。 つまり、変数をオブジェクト型として宣言すると、スタック上でオブジェクトのサイズと同じくらいのスペースを占有しますが、クラス型の変数を宣言すると、常にポインターのサイズを使用しますスタック上。 実際のクラスデータはヒープ上にあります。

Pascalクラスの定義

クラスは、型宣言を使用して、オブジェクトと同じ方法で宣言されます。 クラス宣言の一般的な形式は次のとおりです-

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 キーワードを使用して定義されます。
  • フィールドは、クラスの各インスタンスに存在するデータ項目です。
  • メソッドはクラスの定義内で宣言されます。
  • Rootクラスには Create と呼ばれる定義済みのコンストラクターがあります。 すべての抽象クラスとすべての具象クラスはルートの子孫なので、すべてのクラスには少なくとも1つのコンストラクターがあります。
  • Rootクラスには Destroy と呼ばれる定義済みのデストラクタがあります。 すべての抽象クラスとすべての具象クラスはルートの子孫なので、すべてのクラスには少なくとも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オブジェクトの説明で使用したものと同じ例です。 次の例外を除き、両方のプログラムがほぼ同じであることがわかります-

  • クラスを使用するには、\ {$ mode objfpc}ディレクティブを含める必要があります。
  • コンストラクターを使用するには、\ {$ 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種類の可視性を持っています-

Sr.No Visibility & Accessibility
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クラスのメンバーは、可視性が「保護」されています。
  • Novelsクラスには2つのコンストラクターがあるため、関数のオーバーロードには overload 演算子が使用されます。
  • Books.Displayプロシージャは virtual と宣言されているため、Novelsクラスの同じメソッドで*オーバーライド*できます。
  • Novels.Createコンストラクターは、 inherited キーワードを使用して基本クラスコンストラクターを呼び出します。

インターフェース

インターフェイスは、実装者に共通の関数名を提供するために定義されています。 異なる実装者は、要件に応じてこれらのインターフェイスを実装できます。 インターフェースは、開発者によって実装されるスケルトンと言えます。 以下は、インターフェイスの例です-

type
   Mail = Interface
      Procedure SendMail;
      Procedure GetMail;
   end;

   Report = Class(TInterfacedObject,  Mail)
      Procedure SendMail;
      Procedure GetMail;
   end;

クラスがインターフェイスを実装する場合、インターフェイスのすべてのメソッドを実装する必要があることに注意してください。 インターフェイスのメソッドが実装されていない場合、コンパイラはエラーを返します。

抽象クラス

抽象クラスは、インスタンス化することはできず、継承されるだけです。 抽象クラスは、このように、クラス定義に単語シンボル抽象を含めることによって指定されます-

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

静的メンバーを使用するには、ディレクティブ\ {$ static on}を使用する必要があります。