サブルーチン
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2023/10/21 16:13 UTC 版)
歴史
サブルーチンという考え方は、ことさら新しいものではない。アルゴリズムなどにおいて、問題を部分問題に切り分けて解くという分割統治法はコンピュータ以前からあり、コンピュータプログラミングについても、EDSACのプログラミングについて出版された、この分野の世界最初の書籍とされる The Preparation of Programs for an Electronic Digital Computer(1951)においても part one, chapter 2 がサブルーチンに関する章である。
各プログラミング言語におけるサブルーチン
おおむね歴史が古い言語から説明する。
FORTRAN
Fortranでは、値を返すサブプログラムは関数(function
)、値を返さないサブプログラムはサブルーチン(subroutine
)と呼ばれる。Fortran 90以降の関数はPURE属性により副作用を持たないことを明示できる。
LISP
LISPでは関数と呼ばれることが多く、Common Lispでも関数と呼ぶ。しかしSchemeの仕様では手続きという用語を使っている。なおLispにはサブルーチンをマクロで実装するという重要な手法もある。
BASIC
古典的なBASICでは、GOSUB 命令によるサブルーチンがあった。インタプリタは GOSUB 命令を見つけると、GOSUB 命令の終わりの場所(アドレス)をインタプリタ内のスタックにプッシュして保存し、命令で指定された行に飛び、実行を続ける。その後、実行中に RETURN 命令を見つけると、スタックから先ほど保存しておいた呼び出し元の場所をポップして取り出し、そこに飛び、GOSUB 命令の次の命令から実行を再開する。サブルーチンを作成したい場合は、ユーザーは「この行からこの行まではサブルーチンとする」と決めてプログラムを作成した。以上のように「RETURN できる GOTO」でしかない(引数も返り値もローカル変数もない)ため、(グローバル)変数を経由する、配列をユーザースタックとして使うなど、技巧を必要とした。比較的高機能な実装では、DEFFN 命令により、式一個で記述できる範囲という制限ながらも、引数と返り値のあるユーザー定義関数の追加(拡張)が行えるものもあった。
Pascal
Pascalではfunction
およびprocedure
という予約語を使って宣言する[注釈 1]。
C言語
カーニハンとリッチーによる解説書『プログラミング言語C』、いわゆる「K&R」には、C言語の関数はPascalの「手続き」や「関数」に相当すると書かれてある[10]。つまりC言語では戻り値の有無にかかわらず「関数」(function) と呼んでいる。
関数の定義の書式は次の通りである[10]。
<戻り値の型> <関数名>( <引数> ) { 関数内の処理の記述 }
C言語では歴史的な理由から、値を返さない関数を宣言および定義する場合は、関数の型(返戻値の型)を書く場所にvoid
(void型)と書く[注釈 2]。
関数の宣言が複数ある場合、どの順番で書いても良いし、複数のファイルに分けて書いても良い[10]。ただし、ひとつの関数を複数のファイルに分けて書いてはいけない[10]。
なお、K&RのCはANSI C(C89)として標準化される前の古い仕様に基づいており、Cの歴史を知るうえでは重要だが、2023年現在はISO/IEC 9899規格を参照することが望ましい。
Perl
Perlでは、ユーザー定義のものはサブルーチンであるが、引数を渡すことができ、値を返すこともできる。サブルーチン内からは、渡された引数には特殊変数からアクセスし、値を返すにはreturn文[注釈 3]を使う。
Visual Basic
Visual Basic (VB)、Visual Basic for Applications (VBA)、Visual Basic .NET (VB.NET) では、サブルーチンをプロシージャと総称しており、値を返すプロシージャを「Function
プロシージャ」、値を返さないプロシージャを「Sub
プロシージャ」と呼ぶ。さらにプロパティを定義するための構文として「Property
プロシージャ」がある[11][12]。
他
Microsoft Excelにおける関数は、主に、計算をしたり、データの検索や集計をしたり、表示を変換したりするものである。合計値を求めるSUM関数や、平均値を求めるAVERAGE関数、条件演算子に相当するIF関数など、100を超える組み込みの「ワークシート関数」が存在する。一方、VBAコードからのみ利用可能な「VBA関数」もある。例えばIIf関数[13]はIF関数に似た働きをするが、ワークシート上の数式内では利用できず、VBAからのみ利用可能である。ワークシート関数およびVBA関数はいずれもユーザー定義の関数を登録して利用することもできる。
再帰呼び出し
あるサブルーチンf
の定義中でf
自身を再度呼び出すことを再帰呼び出し(さいきよびだし、recursive function call)という[14][1]。再帰呼び出しを使うと、ある処理で得られた値に対しさらに同じ処理を何度も繰り返すような場合に簡潔な記述にすることができる[15]。たとえば階乗の計算をするために使ったり[1]、ファイルシステムのような木構造の探索に使ったり[16]、オセロソフト・チェスソフト・将棋ソフト・囲碁ソフトなどの「先読み」に使ったりできる[注釈 4][17][18][19][20]。
なお、一般的なコンピュータおよびプログラミング言語では、サブルーチン呼び出しの際はコールスタックに引数やローカル変数などの領域が確保されるが、パーソナルコンピュータのような比較的リソースに余裕のある環境であっても、このコールスタックの容量は既定でスレッドごとに数MiB程度に設定されており、サブルーチンの呼び出し階層が深すぎるとスタックオーバーフローを引き起こす場合がある。特に再帰呼び出しは呼び出し階層が深くなりがちで、再帰回数が多すぎるとスタックオーバーフローを引き起こしやすい。
注釈
- ^ C言語と違い、中身の記述すなわち定義まで含むものもPascalでは「宣言」と言う。
- ^ 標準化以前(K&R初版時代のC)は、省略した場合のデフォルトとしてintを返すと解釈される仕様だったという経緯があり、互換性を保つためにそれが標準とされたため、値を返さない場合には
void
を書いて明示しなければならない、という仕様になっている。 - ^ http://perldoc.perl.org/perlsub.html には return statement とあるが、return 自体の解説は http://perldoc.perl.org/functions/return.html のように関数扱いになっている。
- ^ オセロゲームの盤面先読みのコードは、以前、基本情報技術者試験に出題されたことがあり教科書や問題集などでも掲載されるようになっていた。
出典
- ^ a b c d 大滝みや子『2020年版 基本情報技術者 標準教科書』オーム社、2019年。pp.95-96「手続きと関数」「再帰呼び出し」の章
- ^ 電子情報通信学会『知識の森』 - 6 群「基礎理論とハードウェア」 - 3 編「アルゴリズムとデータ構造」 - 1 章「アルゴリズムとアルゴリズム解析」
- ^ 問49 変数を引数として渡しても、サブルーチンの実行後に変数の値が変更されないことが保証されているものはどれか。 | 日経クロステック(xTECH)
- ^ Calling Conventions | Microsoft Learn
- ^ Argument Passing and Naming Conventions | Microsoft Learn
- ^ x64 calling convention | Microsoft Learn
- ^ Overview of ARM ABI Conventions | Microsoft Learn
- ^ Working with DLLs | Microsoft Learn
- ^ Developing DLLs | Microsoft Learn
- ^ a b c d Brian W. Kernighan / Dennis M. Ritchie "The C Programming Language, Second Edition", 1988. ISBN 0-13-110362-8, pp.24-27 "Functions".
- ^ Writing a property procedure (VBA) | Microsoft Learn
- ^ Property プロシージャ - Visual Basic | Microsoft Learn
- ^ IIf function (Visual Basic for Applications) | Microsoft Docs
- ^ 自分から自分を呼ぶ? Pythonで「再帰呼び出し」の不思議を体験 | 日経クロステック(xTECH)
- ^ 『令和04年 栢木先生の基本情報技術者教室』技術評論社、2021年、p.209「再帰的な関数の例」
- ^ .NET TIPS [ASP.NET]データベースからツリー・メニューを生成するには? - C# VB.NET Webフォーム - @IT
- ^ Chess programming
- ^ 将棋ソフト作成入門
- ^ 再帰呼び出し
- ^ 囲碁プログラムの作り方(基本編)
- サブルーチンのページへのリンク