サブルーチン: プロシージャと関数 - 1


が画面に表示されます。

サブルーチンは、名前があり、独自の別個のタスクを解決するプログラムの別個の部分です。サブルーチンはメインプログラムの先頭に配置され、名前を指定することでメインプログラムから起動(呼び出し)できます。

サブルーチンを使用すると、プログラム内の別の場所に同じコードを記述する必要がある場合に、コードの重複を避けることができます。
プログラムにインポートされるライブラリ (数学ライブラリ math など) は、誰かがすでにコンパイルしたサブルーチンで構成されています。プログラマーは、どのようなアルゴリズムを実装するかを考える必要はなく、正確に何をしているのかだけを考えて、単にアルゴリズムを適用するだけです。これにより時間を大幅に節約できます。すでに誰かが書いたアルゴリズムを自分で書く必要は
ありません。
各ルーチンは次の 1 つのことだけを実行する必要があります。 単に何かを計算するか、データを出力するか、あるいは他のことを行うかのいずれかです。

サブルーチンにはプロシージャ関数の 2 種類があります

サブルーチンは、結果を特定の形式で画面に出力するなど、いくつかのアクションを実行します (簡単な例として、ステートメント writeln() は標準のサブルーチンであり、画面情報)

関数サブルーチンはメイン プログラムで使用できる結果 (数値、文字列など) を返します

簡単な手順を書いてみましょう。
画面に「Error」という文字列を表示する必要があるとします。ユーザーの過失(間違ったデータを入力した場合など)によりコード内でエラーが発生する可能性があるたびに
これはステートメントを書くことで実行できます <プレ> writeln('エラー'); そして、そのような行をプログラム内の多くの場所に挿入する必要があると想像してください。もちろんどこにでも書いて大丈夫です。ただし、この解決策には 2 つの欠点があります。
1) この文字列は何度もメモリに保存されます
2) エラー時の出力を変更したい場合は、プログラム全体でこの行を変更する必要があり、かなり不便です

このような場合には手続きが必要
になります。 プロシージャを含むプログラムは次のようになります。 <プレ> ... 名前空間 std を使用します。 プロシージャ printError(); // 手続きの説明 始める writeln('エラー'); // プロシージャ本体 - プロシージャが実行するコマンド 終わり; // メインプログラム 始める; ... 印刷エラー(); // 実行のためのプロシージャを開始します。実行したいプロシージャの名前を指定するだけです。 ... 印刷エラー(); ... 終わり。 プロシージャは、procedure という単語で始まります。 プロシージャ名の後に括弧が書かれ、プロシージャの実行が依存する変数とその型を示します。例:

var a, b, 答え: 整数;
プロシージャ Sum(a, b: 整数);
始める
   答え:= a + b;
終了;

プロシージャ内で実行されるすべてのステートメントはインデントされます。

プロシージャはメインプログラムの前に記述されます

プロシージャを実行するには、メイン プログラムでプロシージャを名前で呼び出し、 かっこを忘れずに記述する必要があります
プログラム内のプロシージャは何度でも呼び出すことができます。

ここで、ユーザーのエラーに応じて、ユーザーが犯した間違いの種類に応じて異なるメッセージを表示する必要があると考えてみましょう。
この場合、エラーごとに独自のプロシージャを作成できます。 <プレ> プロシージャ printErrorZero(); 始める writeln('エラー。ゼロ除算!'); 終わり; <プレ> プロシージャ printErrorInput(); 始める writeln('入力エラー!'); 終わり; さらに多くのエラーの可能性がある場合はどうなるでしょうか?この解決策は私たちには合いません。
どのようなエラーメッセージを表示するかを指示してプロシージャを制御する方法を学ぶ必要があります。
これを行うには、プロシージャ名の後に括弧内に記述するパラメータが必要です。 <プレ> procedure printError(s: string); 始める writeln; 終了; このプロシージャでは、 s はパラメータ、つまりプロシージャの制御を可能にする特別な変数です。
パラメータは、サブルーチンの動作方法を決定する変数です。パラメータ名は、サブプログラムのヘッダーにセミコロンで区切ってリストされています。パラメータの後には、コロン の後にそのタイプが続きます。

ここで、プロシージャを呼び出すときに、プロシージャ内のパラメータ (変数) に割り当てられる実際の値を括弧内に示す必要があります。 <プレ> printError('エラー!ゼロ除算!'); この値を引数と呼びます。
引数は、サブルーチンが呼び出されたときにサブルーチンに渡されるパラメータ値です。
引数には定数値だけでなく、変数や算術式も使用できます。

多くの場合、サブルーチン内でのみ使用される追加の変数を使用する必要があります。このような変数はローカル (またはローカル) と呼ばれ、変数が作成されたサブルーチン内でのみ操作できます。
 
ローカル変数スコープは、宣言される関数またはプロシージャです。

したがって、変数の有効範囲 (スコープ) を、それが本当に必要なサブルーチンのみに制限することができます。プログラミングでは、この技術はカプセル化と呼ばれます。 - 変数が外部から変更されないように隠します。

プログラム内の任意の場所 (サブルーチン内) で参照できる変数を宣言する必要がある場合、そのような変数はすべてのサブルーチンの外で宣言されます (以下の表のプログラム 3 を参照)。
このような変数はグローバルと呼ばれます。

3 つのプログラムを分析します。 <テーブル align="center" border="1" cellpadding="1" cellpacing="1" style="width:95%"> <本体>
1) このプログラムでは、変数 i はローカルです。ローカル変数がサブルーチン内で宣言されている 2) ここでは、メイン プログラムに変数 i (値 7) が存在する場合でも、値 5 の新しいローカル変数 i が作成されます。
このプログラムを実行すると、画面に値 75 が表示されます
3) このプログラムにはグローバル変数 i があります。その値はサブルーチン内およびメイン プログラム内で変更できます。
このプロシージャはグローバル変数 i を使用して動作し、新しい値 2 が割り当てられます。値 2
プロシージャ test();
var i: 整数;
始める
   私:= 5;
    writeln(i);
終了;
変数 i: 整数;

プロシージャ test();
var i: 整数;
始める
   私:= 5;
    writeln(i);
終了;

始める
   私:= 7;
   書き込み(i);
   テスト();
終了。
変数 i: 整数;

プロシージャ test();
始める
    i := 2;
終了;

始める
   テスト();
    writeln(i);
終了。
問題:2 つの変数の値を交換するプロシージャを作成してください。
このタスクの特徴は、プロシージャで行われた変更を呼び出し側プログラムに認識させる必要があることです。

次のように手順を書いてみましょう

var x、y: 整数。 <プレ> プロシージャ Swap(a, b: 整数); // プロシージャパラメータのこのような記述では、 var c: 整数; begin // 引数 (x と y) の値をコピーします // 変数 a と b は x と y に関係のない独立変数です c := a; a := b; b := c; 終わり; 始める x := 1;   y := 2; スワップ(x, y); //変数 x と y (引数) の値がパラメータ a と b にコピーされます writeln('x = ', x, ', y = ', y); // x=1、y=2 終わり。 このプログラムを実行すると、変数 xy の値が変化していないことがわかります。パラメータで引数の値を変更するには、参照によるデータの受け渡しを使用する必要があります。これを行うには、データ型の名前の後に記述します。サブルーチンのヘッダーには、 var  という単語を入れる必要があります。 <プレ> プロシージャ Swap(var a, b: 整数);   // これで変数 a と b はメモリ内の変数 x と y のアドレスを取得します var c: 整数;  始める c := a; a := b; b := c; 終わり; 使用法: 参照によって引数を渡す場合、プロシージャを呼び出すときにこの場所に含めることができるのは変数名 (数値や算術式ではありません) のみです。< br />
次のようなプロシージャを呼び出さないでください: <プレ> スワップ(x, 4); スワップ(5+x, y);