コンテンツにスキップ

「手続き型プログラミング」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
「手続き」(プロシージャ)の扱いは呼び出しに限られない
手続きの来歴
(他の1人の利用者による、間の2版が非表示)
1行目: 1行目:
{{独自研究|date=2016年6月}}
{{独自研究|date=2016年6月}}
{{出典の明記|date=2016年6月}}
{{出典の明記|date=2016年6月}}
{{プログラミング言語|index=てつつきかたふろくらみんく}}
[[ファイル:Процесс решения задачи проектирования.png|境界|右|フレームなし|200x200ピクセル]]
'''手続き型プログラミング'''(てつづきがたプログラミング、{{lang-en-short|''Procedural programming''}})は、手続きの定義と呼び出しをプログラム全体を組み立てる土台にした[[プログラミングパラダイム]]である。[[プロシージャ|手続き]]は言語によって[[サブルーチン]]、[[関数 (プログラミング)|関数]]、[[メソッド (計算機科学)|メソッド]]とも呼ばれている。手続きはプログラム全体を区画した部分プログラムでもあり、一定量の計算ステップまたは命令コードのまとまりを、任意の定義名に結び付けて識別化したコードユニットである。手続き型プログラミングは[[命令型プログラミング]]の分類に属しており、1958年の[[FORTRAN|FORTRANⅡ]]、[[ALGOL]]、[[COBOL]]といった最も初期の[[高水準言語]]から導入されている。


手続き(''procedure'')は、プログラム内のあらゆるポイントから呼び出す(''call'')ことが可能であり、手続き内の命令コード行の終端に達した時は、その手続きを呼び出したポイントの次のアドレスに制御が移される。これは復帰(''return'')と呼ばれる。リターン命令で途中位置でも復帰できる。手続きは他の手続き内からの呼び出しの他、自身内からの呼び出しも可能でありこれは[[再帰]](''recursive call'')と呼ばれる。手続きの呼び出しと復帰は、コンピュータ側が提供する[[コールスタック]]または[[スタックフレーム]]機能の命令アドレス管理によって実現されている。
'''手続き型プログラミング'''(てつづきがたプログラミング、{{lang-en-short|Procedural programming}})は、「手続き」の概念に基づく[[プログラミングパラダイム]]の一種。[[命令型プログラミング]]と同義に扱われることが多い。「手続き」はプロシージャ、ルーチン、[[サブルーチン]]、[[メソッド (計算機科学)|メソッド]]、関数([[関数 (数学)|数学の関数]]とは異なる。)など様々な呼称があるが、実行すべき一連の計算ステップを持つものと定義できる。手続きはプログラム実行中の任意の時点で呼び出すことができ、他の手続きからの呼び出しも、自分自身からの呼び出し([[再帰|再帰呼び出し]])も含まれる。


== 手続きの来歴 ==
手続き型プログラミングは単純な逐次型プログラミングや[[非構造化プログラミング]]よりも多くの場合よりよい選択である。非構造化プログラミングでは複雑なコードを組むことは困難であり、保守性が悪い。手続き型プログラミングには、以下のような利点がある:
手続き(''procedure'')の考え方は、[[機械語]]コードの時代から存在しており、[[低水準言語]]([[アセンブリ言語|アセンブラ]])にある[[ニーモニック・コード|ニーモニックコード]]のCALL命令とRET命令が原点である。PUSH命令による引数の[[スタック|スタックメモリ]]への積み込みと、スタックポインタレジスタの減算によるローカル変数領域の確保、ベースポインタレジスタによる引数とローカル変数へのアクセスといった[[スタックフレーム]]の機能もアセンブラ由来のものである。CALL命令のジャンプ先アドレスに付けられたラベルは手続き名と同義になった。その仕組みは1950年代半ばから登場した[[高水準言語]]にもそのまま受け継がれた。ラベルは形式化された引数欄付きの呼び出し名となり、スタックフレーム処理も自動化隠蔽され、ソースコード上で明確に区分けされた手続き(プロシージャ)として誕生した。

* コードを同じプログラム内でコピーすることなく再利用可能
* GOTO文やJUMP命令だけでプログラムの[[制御構造]]を構築するよりも容易(そのような制御構造だけで作られた巨大なプログラムを[[スパゲティプログラム]]と呼ぶ)
* [[モジュール性]]の高い[[構造化プログラミング]]が可能


== 手続きとモジュール性 ==
== 手続きとモジュール性 ==
19行目: 19行目:
単純で自己完結的で再利用可能なインタフェースであるため、手続きを使って多数の人間が書いたコードを組み合わせることが可能となり、[[ライブラリ]]なども作成できるようになった。
単純で自己完結的で再利用可能なインタフェースであるため、手続きを使って多数の人間が書いたコードを組み合わせることが可能となり、[[ライブラリ]]なども作成できるようになった。


== 命令型プログラミングとの比 ==
== 他のプログラミングパラダイムとの比 ==
ほとんどの手続き型プログラミング言語は[[命令型プログラミング]]言語でもある。実行環境の状態を明示的に参照する。この場合の状態とは([[レジスタ (コンピュータ)|レジスタ]]に対応する)「[[変数 (数学)|変数]]」であったり、[[LOGO]]言語での「タートル」の位置であったりする。


== オブジェクト指向プログラミングとの比較 ==
=== 命令型プログラミング ===

=== オブジェクト指向プログラミング ===
手続き型プログラミングでは、プログラミングは[[データ構造]]とルーチンの集合に分割される。一方[[オブジェクト指向プログラミング]]では、プログラミングは[[オブジェクト (プログラミング)|オブジェクト]]に分割される。
手続き型プログラミングでは、プログラミングは[[データ構造]]とルーチンの集合に分割される。一方[[オブジェクト指向プログラミング]]では、プログラミングは[[オブジェクト (プログラミング)|オブジェクト]]に分割される。


31行目: 32行目:
オブジェクト指向と手続き型の重要な違いとして、オブジェクト指向では[[関係データベース]]にアクセスするにあたって、データモデルのクラス構造へのマッピングが必要である。
オブジェクト指向と手続き型の重要な違いとして、オブジェクト指向では[[関係データベース]]にアクセスするにあたって、データモデルのクラス構造へのマッピングが必要である。


以下にオブジェクト指向と手続き型の言語要素を比較した表を示す:
以下にオブジェクト指向と手続き型の言語要素を比較した表を示す


{| class="wikitable"
{| class="wikitable"
39行目: 40行目:
|-
|-
| [[メソッド (計算機科学)|メソッド]]
| [[メソッド (計算機科学)|メソッド]]
| [[サブルーチン|関数サブルチン)]]
| [[サブルーチン|手続きプロシジャ)]]
|-
|-
| [[オブジェクト (プログラミング)|オブジェクト]]
| [[オブジェクト (プログラミング)|オブジェクト]]
| [[構造体|構造体(レコード)]]
|-
| [[クラス (コンピュータ)|クラス]]
| [[モジュール]]
| [[モジュール]]
|-
|-
| [[メッセージ (コンピュータ)|メッセージ]]
| [[メッセージ (コンピュータ)|メッセージ]]
| 呼び出し
| 手続き呼び出し
|-
| [[メンバ]]
| [[変数 (プログラミング)|変数]]
|}
|}


== 手続き型プログラミング言語 ==
=== 関数型プログラミング ===

=== 論理型プログラミング ===

== 代表的な手続き型言語 ==
手続き型と見なされるプログラミング言語は、手続き(プロシージャ)の概念を明確に持っていて、構文として定義している。
手続き型と見なされるプログラミング言語は、手続き(プロシージャ)の概念を明確に持っていて、構文として定義している。


85行目: 90行目:


== 関連項目 ==
== 関連項目 ==
* [[宣言型プログラミング]]
*[[プログラミングパラダイム]]
* [[命令型プログラミング]]

* [[オブジェクト指向プログラミング]]
* [[プログラミングパラダイム]]
* [[プログラミング言語]]
* [[プログラミング言語]]
* [[命令型プログラミング]]
** [[オブジェクト指向プログラミング]]
** [[構造化プログラミング]]
** [[非手続き型言語|非手続き型プログラミング]]


* [[宣言型プログラミング]]
* [[非手続き型言語]]
** [[関数型言語]]
**[[関数型言語|関数型プログラミング]]
** [[論理型言語]]
**[[論理型言語|論理型プログラミング]]
** [[問い合わせ言語]]
**[[問い合わせ言語]]

* [[構造化プログラミング]]


== 外部リンク ==
== 外部リンク ==

2020年7月5日 (日) 01:19時点における版

手続き型プログラミング(てつづきがたプログラミング、: Procedural programming)は、手続きの定義と呼び出しをプログラム全体を組み立てる土台にしたプログラミングパラダイムである。手続きは言語によってサブルーチン関数メソッドとも呼ばれている。手続きはプログラム全体を区画した部分プログラムでもあり、一定量の計算ステップまたは命令コードのまとまりを、任意の定義名に結び付けて識別化したコードユニットである。手続き型プログラミングは命令型プログラミングの分類に属しており、1958年のFORTRANⅡALGOLCOBOLといった最も初期の高水準言語から導入されている。

手続き(procedure)は、プログラム内のあらゆるポイントから呼び出す(call)ことが可能であり、手続き内の命令コード行の終端に達した時は、その手続きを呼び出したポイントの次のアドレスに制御が移される。これは復帰(return)と呼ばれる。リターン命令で途中位置でも復帰できる。手続きは他の手続き内からの呼び出しの他、自身内からの呼び出しも可能でありこれは再帰recursive call)と呼ばれる。手続きの呼び出しと復帰は、コンピュータ側が提供するコールスタックまたはスタックフレーム機能の命令アドレス管理によって実現されている。

手続きの来歴

手続き(procedure)の考え方は、機械語コードの時代から存在しており、低水準言語アセンブラ)にあるニーモニックコードのCALL命令とRET命令が原点である。PUSH命令による引数のスタックメモリへの積み込みと、スタックポインタレジスタの減算によるローカル変数領域の確保、ベースポインタレジスタによる引数とローカル変数へのアクセスといったスタックフレームの機能もアセンブラ由来のものである。CALL命令のジャンプ先アドレスに付けられたラベルは手続き名と同義になった。その仕組みは1950年代半ばから登場した高水準言語にもそのまま受け継がれた。ラベルは形式化された引数欄付きの呼び出し名となり、スタックフレーム処理も自動化隠蔽され、ソースコード上で明確に区分けされた手続き(プロシージャ)として誕生した。

手続きとモジュール性

大きく複雑なプログラムでは特にモジュール性が重要である。手続き型プログラミングでは、モジュールへの入力は構文的には「引数」であり、出力は「リターン値」である。

変数スコープは手続きのモジュール性を高めるもう1つの技法である。手続き内の変数は他の手続きからアクセスできない(逆も成り立つ)し、同じ手続きの複数の呼び出しの間でもそれが保たれる。スコープを超えたアクセスには特別な許可が必要である。

モジュール性の低い手続きも簡単なプログラムではよく使われる。その場合、実行環境内の多数の変数にアクセスし、他の手続きでも同様にそれらの変数にアクセスする。

単純で自己完結的で再利用可能なインタフェースであるため、手続きを使って多数の人間が書いたコードを組み合わせることが可能となり、ライブラリなども作成できるようになった。

他のプログラミングパラダイムとの対比

命令型プログラミング

オブジェクト指向プログラミング

手続き型プログラミングでは、プログラミングはデータ構造とルーチンの集合に分割される。一方オブジェクト指向プログラミングでは、プログラミングはオブジェクトに分割される。

一般にオブジェクト指向プログラミングの方が理解しやすいと言われている。その理由として、オブジェクト指向が人間の精神モデルの認知手法に近いからだという説もあるが、心理学が人間の認知モデルを完全には明確化できていない現時点では非常に不確かである。蒸気機関が発明されたとき、人間の精神は蒸気機関と比較された。コンピュータが発明されたとき、人間の精神はそれと比較された。オブジェクト指向プログラミングが発明されると、人間の精神はそれと比較されることになったのである。

多くの場合、オブジェクト指向の方がプログラムが小さくなり、保守が容易であると考えられている。プログラムはクラス群の定義から構成されている。オブジェクト指向言語と一口に言っても、全てをオブジェクトとみなす純粋なオブジェクト指向言語は少ない。例として最初のオブジェクト指向言語 Smalltalk があるが、商業的に成功したとは言いがたい。多くのオブジェクト指向言語は、手続き型プログラミングとオブジェクト指向を融合させたものである。

オブジェクト指向と手続き型の重要な違いとして、オブジェクト指向では関係データベースにアクセスするにあたって、データモデルのクラス構造へのマッピングが必要である。

以下にオブジェクト指向と手続き型の言語要素を比較した表を示す。

純粋なオブジェクト指向 純粋な手続き型
メソッド 手続き(プロシージャ)
オブジェクト 構造体(レコード)
クラス モジュール
メッセージ 手続き呼び出し

関数型プログラミング

論理型プログラミング

代表的な手続き型言語

手続き型と見なされるプログラミング言語は、手続き(プロシージャ)の概念を明確に持っていて、構文として定義している。

典型例はALGOLである。手続きがメソッドの形でしか出現しない言語は、手続き型というよりもオブジェクト指向と見なすのが一般的であり、以下のリストにはそのような言語は登場しない。例えば、C#Javaがそうだが、C++はメソッド以外の形態で手続きを記述可能なので、以下に挙げてある。

関連項目

外部リンク