基本情報技術者単語帳 - アルゴリズムとプログラミング
データ構造
データの集まりをコンピュータプログラムで扱いやすいように、一定の形式で格納したもの。特定の問題を解く手順(アルゴリズム)には、それぞれに適したデータ構造がある。
複数のデータの配置や関係性、データの参照や出し入れなどの操作のルールを定義したもので、様々な種類がある。それぞれに特徴や適した処理があるため、同じ処理の記述でも、目的に対して適切なデータ構造を選択できるかどうかでプログラムの複雑さや処理性能に大きな差がつくことがある。
データ構造の種類
最も基本的なデータ構造には、要素を一列に並べた「配列」(array)、要素を格納した順に取り出すことができる「キュー」(queue)、格納したのとは逆順に取り出すことができる「スタック」(stack)などがある。
格納された要素への参照データを含むデータ構造もあり、任意の標識と要素を一対一に関連付けて格納する「連想配列」(辞書、ハッシュ、マップとも呼ばれる)、要素が前後の要素への参照を持つ「連結リスト」(linked list)、要素が任意個の他の要素への参照を持つ「グラフ」(graph)、一つの頂点から樹状に枝分かれしたグラフである「木構造」(ツリー構造)などがある。
これらには細部の仕様が異なるバリエーションがある。例えば、連結リストには前の要素が後の要素への参照を持つだけの「片方向リスト」(単方向リスト)、これに加えて後の要素が前の要素への参照も持つ「双方向リスト」、要素が環状に連なっている「循環リスト」などいくつかの種類がある。
言語上の扱い
プログラミング言語では、基本的なデータ構造のいくつかが言語仕様や標準ライブラリなどにあらかじめ組み込まれて提供されていることが多い。用意されていない場合でも、既存のデータ構造や複合データ型、クラスなどの仕様を利用して開発者がデータ構造の定義や挙動の実装を行うことがある。
実際のプログラム上では基本的なデータ構造を単体で用いることも多いが、あるデータ構造の要素として別のデータ構造を格納するなど、アルゴリズムに合わせて組み合わせて用いる場合もある。
配列 【配列型】
複数のデータを連続的に並べたデータ構造。各データをその配列の要素といい、非負整数などの添字(インデックス)で識別される。
配列はほとんどのプログラミング言語に存在する最も基本的なデータ構造の一つで、単純に変数を一列に並べたものである。データ全体はコード中で配列名で指し示され、各要素は通し番号などの添字で区別される。例えば、長さ5の整数型の配列変数xを宣言すると、x[0]からx[4]まで5つの整数型の変数が用意され、それぞれ独立に整数値を格納することができる。
各要素のデータ型が同じでなければならない言語と、要素ごとに異なる型のデータを格納できる言語がある。変数の宣言が必須の言語では、配列変数の宣言時に要素のデータ型と数をあらかじめ指定しなければならないことが多い。要素数を後から増減できる動的配列(可変長配列)が利用できる言語もある。
添字は0から始まる整数とする言語が多く、要素がn個の配列の添字は0からn-1までとなる。添字に文字列など整数以外のデータ型の値を取れるようにしたデータ構造を利用できる言語もあり、これを「連想配列」(associative array)と呼ぶ。言語によっては同様のデータ構造を辞書(ディクショナリ)、ハッシュ、マップ、連想リスト等と呼ぶこともある。
配列の要素として配列を格納した、入れ子状のデータ構造を「多次元配列」という。配列の要素が配列になっており、その要素が値になっている構造が「2次元配列」で、配列が3段階に入れ子状になっている構造は「3次元配列」である。同様に、入れ子がn段階になっている配列を一般に「n次元配列」という。要素が値になっている単純な配列をこれらと対比する場合は「1次元配列」と呼ぶことがある。
多次元配列
プログラミング言語などが扱うデータ構造の一つで、配列の各要素が配列に、その要素がさらに配列になっているような入れ子構造の配列のこと。
配列(array)は多くのプログラミング言語に用意されている基本的なデータ構造の一つで、単純に複数のデータを一列に並べたものである。コード中で配列は配列名で参照され、配列内の各要素は添字(インデックス)によって識別される。
単純な配列(1次元配列)では配列の各要素にそれぞれ値が格納されているが、多次元配列では配列の各要素が配列に、その要素がさらに配列に…という具合に配列が何段階にも入れ子構造になっている。
入れ子が何段階になっているかを次元の数で表し、配列の要素が配列になっているものを「2次元配列」、その要素がさらに配列になっているものを「3次元配列」というように呼ぶ。多次元配列と対比して、入れ子になっておらず配列の要素が値になっている単純な配列のことを「1次元配列」と呼ぶことがある。
静的配列 【固定長配列】
プログラミングで用いられる配列変数の一種で、宣言時に長さ(要素数)を指定し、以降は要素を追加、削除することができないもの。
配列は一つの識別名で複数のデータを扱うことができるデータ構造で、個々の要素は自然数などの添字で識別される。静的配列はこのうち、宣言時に要素数を指定し、後からその数を増減できないものを指す。コンパイル時に要素数が確定するため処理が高速である。
例えば、C言語などで int a[10]; のように宣言すると、a[0]からa[9]までの10個の整数型の変数が格納された配列を宣言できるが、後から a[10] のような要素を追加したり、a[9]を削除して長さを短くするといった操作を行うことはできない。
一方、長さが固定的に決まっておらず、実行時に必要に応じて要素を追加、削除できる配列変数は「動的配列」(dynamic array)あるいは「可変長配列」(variable-length array)という。静的配列とは内部的な実装が異なり、固定長の場合より性能は低くなる。
Visual BasicおよびVBAのDim/RedimやJavaのArray/ArrayListように、静的配列と動的配列の両方が用意されていて使い分けることができるプログラミング言語もあるが、JavaScriptのように配列がすべて動的配列として実装されている言語もある。
動的配列 【可変長配列】
プログラミングで用いられる配列変数の一種で、長さ(要素数)が固定的に決まっておらず、実行時に必要に応じて要素を追加、削除することができるもの。
配列は一つの識別名で複数のデータを扱うことができるデータ構造で、個々の要素は自然数などの添字で識別される。動的配列はこのうち、宣言時に長さを指定せず、あるいは指定した長さを後から変更することができ、実行時に動的に要素を増減できるものを指す。
あらかじめ必要な要素数が分からない処理を行う場合にコードを簡潔に記述でき、不要になった要素を削除して記憶領域を効率的に活用することもできる。固定長の配列とは内部的な実装が異なっており、性能上は不利になることが多い。
Visual BasicおよびVBAのDim/RedimやJavaのArray/ArrayListように静的配列と動的配列の両方が用意されていて使い分けることができるプログラミング言語もあるが、JavaScriptのように配列がすべて動的配列として実装されている言語もある。
一方、宣言時に要素数を指定し、以降は長さを変更できない配列を「静的配列」(static array)あるいは「固定長配列」(fixed-length array)という。動的配列が登場するまでは配列といえば静的配列のことだったため、昔からある言語では仕様上は静的配列しか用意されていないこともある。
リスト
一覧(表)、目録、羅列、一覧に載せる、一覧にする、などの意味を持つ英単語。一般的の外来語としては同じ種類の情報を羅列した一覧のことを指すことが多く、ITの分野でもこの用法が多い。
プログラミングの分野では、ソースコードのことを「プログラムリスト」「ソースリスト」などと呼び、これを略してリストということがある。
データ構造のリスト
基本的なデータ構造の一つで、複数のデータを順序を付けて格納することができる複合データ型(コンテナ/コレクション)をリストという。
中でも、各データが次のデータの所在を表す参照情報(リンク/ポインタ)を持っているものを「連結リスト」(linked list:リンクリスト/リンクトリスト)と呼び、これを略してリストという場合も多い。リストは他に動的配列などを用いても実装することができる。
連結リストの各要素はデータの他に自分の隣の要素を指し示す所在情報を持っている。これを辿ることで、各要素に順番にアクセスすることができる。各要素が自分の次(後)の要素への参照のみを持つ構造を「片方向リスト」「単方向リスト」と呼び、これに加えて自分の前の要素への参照をもつものを「双方向リスト」という。
また、先頭から末尾へ直線上に要素が連結されているものを「線形リスト」、先頭も末尾もなく要素が円環状に連結されているものを「循環リスト」という。
線形リスト
基本的なデータ構造の一つで、要素を数珠繋ぎにした連結リスト(linked list)のうち、先頭と末尾が存在するもの。連結リストのことを線形リストと呼ぶこともある。
連結リストは複数のデータを格納するデータ構造の一つで、各要素がデータ(値やデータ構造など)の他に、隣の要素へのリンク(メモリなどにおける位置情報)を持っているようなものを指す。リンクをたどっていくことで各要素の順番にアクセスすることができる。
線形リストは先頭の要素が2番目の要素を指し示し、2番目の要素が3番目を指し示し…という具合に、末尾まで一列に要素を連結した構造になっている。末尾の要素の「次」を表すリンクをどうするかは実装によるが、Null値など不存在を表す特別な値とすることが多い。
線形リストのうち、それぞれの要素が「次」(後)の要素へのリンクを持ち、先頭側から末尾側へ一方向にのみ要素をたどることができるものを「単方向リスト」(singly linked list)あるいは「片方向リスト」、これに加えて「前」の要素へのリンクも持ち、末尾側から先頭側へもたどることができるものを「双方向リスト」(doubly linked list)という。
一方、すべての要素が円環状に連なっており、先頭や末尾が存在しない(あるいは、先頭と末尾が連結されている)ような連結リストもあり、「循環リスト」(circular linked list)と呼ばれる。
単方向リスト 【片方向リスト】
基本的なデータ構造の一つである線形リスト(linear linked list)のうち、各要素が自分の「次」の要素へのリンクを持ち、先頭側から末尾側へのみたどっていくことができるもの。
線形リストは連結リスト(linked list)の一種で、各要素が自身のデータと共に、隣の要素へのリンク(メモリなどにおける位置情報)を持ち、先頭から末尾まで要素が数珠繋ぎに並んでいる。
このうち、各要素が自身の「次」(後)の要素へのリンクを持ち、先頭から末尾に向かって順番にアクセスしていくことができるような構造のものを単方向リストという。各要素は自身の「前」の要素へのリンクは持たず、先頭方向に逆向きにたどることはできない。
一方、各要素が自身の「次」と「前」の両方の要素へのリンクを保持しており、先頭側から末尾側へも、その逆方向へもたどっていけるようになっている線形リストは「双方向リスト」(doubly linked list)という。
なお、要素が円環状に連結されている「循環リスト」(circular linked list)にも、各要素が一方の隣へのリンクしか持たない「単方向循環リスト」(circular singly linked list)あるいは「片方向循環リスト」が存在するが、単に「単方向リスト」といった場合は慣習上、単方向線形リストを指すことが多い。
双方向リスト 【双方向連結リスト】
基本的なデータ構造の一つである線形リスト(linear linked list)のうち、各要素が自分の「次」と「前」の要素へのリンクを持ち、先頭側から末尾側へも、逆方向にも要素をたどっていくことができるもの。
線形リストは連結リスト(linked list)の一種で、各要素が自身のデータと共に、隣の要素へのリンク(メモリなどにおける位置情報)を持ち、先頭から末尾まで要素が数珠繋ぎに並んでいる。このうち、各要素が自身の次の要素と前の要素へのリンクを持ち、先頭から末尾へ、あるいは末尾から先頭へ順番にアクセスしていくことができるような構造のものを双方向リストという。
一方、各要素が自身の「次」の要素へのリンクしか持たず、先頭側から末尾側へ一方向にのみたどっていくことができるような線形リストは「単方向リスト」(singly linked list)あるいは「片方向リスト」という。
なお、要素が円環状に連結されている「循環リスト」(circular linked list)にも、各要素が両隣へのリンクを持ち、どちらの方向にも移動できる「双方向循環リスト」(circular doubly linked list)が存在するが、単に「双方向リスト」といった場合は慣習上、双方向線形リストを指すことが多い。
循環リスト 【環状リスト】
基本的なデータ構造の一つで、要素を数珠繋ぎにした連結リスト(linked list)のうち、先頭や末尾が存在せず、円環状に要素が繋がれているもの。
連結リストは複数のデータを格納するデータ構造の一つで、各要素がデータ(値やデータ構造など)の他に、隣の要素へのリンク(メモリなどにおける位置情報)を持っているようなものを指す。リンクをたどっていくことで各要素の順番にアクセスすることができる。
環状リストは先頭も末尾もなく、各要素が全体で円環をなすように連結されており、ある要素を起点に隣の要素を次々にたどっていくと、もとの要素に戻ってくる。実装上は便宜上の「先頭」と「末尾」が設定され、先頭の次を末尾、あるいは末尾の前を先頭とするようにリンクを設定することが多い。
環状リストのうち、それぞれの要素が「次」(後)の要素へのリンクを持ち、ある特定の一方向にのみ要素をたどることができるものを「単方向循環リスト」(circular singly linked list)あるいは「片方向循環リスト」、これに加えて「前」の要素へのリンクも持ち、逆方向にもたどることができるものを「双方向循環リスト」(circular doubly linked list)という。
スタック
最も基本的なデータ構造の一つで、要素が入ってきた順に一列に並べ、後に入れた要素から順に取り出すという規則で出し入れを行うもの。本や書類、箱などを積み上げて置くことになぞらえてこのように呼ばれる。
スタックは要素が入ってきた順に並べ、先頭が最も古く、末尾が最も新しい要素となる。取り出すときは末尾にある最も新しいものから順に取り出す。このように後に入れたものほど先に取り出される管理方式を「LIFO」(Last-In First-Out/後入れ先出し)あるいは「FILO」(First-In Last-Out/先入れ後出し)という。
ほとんどのマイクロプロセッサにはメモリ領域に設けたスタックを操作するための機械語の命令やレジスタなどを内蔵しており、機械語のプログラムの実行制御などで非常によく用いられるデータ構造として知られる。特に、サブルーチンや関数を呼び出す際に処理中のデータや戻りアドレスなどを一時的に退避するコールスタック(実行スタック)のことを単にスタックと呼ぶ場合もある。
一方、先に追加した要素ほど先に取り出される(先頭から順に取り出す)規則で要素の出し入れを管理するデータ構造は「キュー」(queue)あるいは「待ち行列」と呼ばれる。
プッシュ/ポップ (push/pop)
スタックに要素を追加する操作を「プッシュ」(push)、取り出す操作を「ポップ」(pop)という。プッシュされた要素はスタックの末尾に追加され、スタックの要素数は1増加する。
ポップを指示するとスタックの末尾の要素が取り出され、その要素はスタックから取り除かれる。末尾から2番目にあった要素(2番目に新しかった要素)が新しい末尾となり、スタックの要素数は1減少する。
プログラミング言語などによっては、この2つの操作に加え、末尾あるいは指定位置の要素を取り出さずに値を読み込む「ピーク」(peek)、末尾あるいは指定位置の値を書き換える「ポーク」(poke)といった操作を提供している場合もある。
プロトコルスタック/ソフトウェアスタック
ネットワークプロトコル(通信規約)やソフトウェアは物理的な装置や回線に近い部分から利用者に近いものまで、役割に応じて階層構造に分かれていることが多い。
このとき、互いに相互運用性のあるプロトコルやソフトウェアを積み重ね、全体として一つのシステムや機能を実現したものをプロトコルスタック、ソフトウェアスタックなどということがある。
例えばプロトコルであれば、物理層からアプリケーション層まで、UTPケーブル - Ethernet - IP(Internet Protocol) - TCP(Transmission Control Protocol) - HTTP(Hypertext Transfer Protocol)といったように積み上げた各階層の機能が互いに連携しあって通信が可能となる。
専門知識や技能のスタック
ある事業や業務に必要な専門的な知識や技能の総体を、プロトコルやソフトウェアになぞらえて階層状に整理したものをスタックと呼ぶことがある。
階層の積み上げ方は分野によって異なり、ソフトウェアのようにハードウェア寄りから利用者寄りへ重ねていく場合と、企画-設計-実装-…といったように工程の前後関係に基づいて整理する考え方がある。
特に、ある事業分野に必要なすべてのスキルを一人で備え、すべて遂行することができる技術者のことを「フルスタックエンジニア」(英語では “full stack developer”)という。
例えば、Webサービスを開発・提供する場合に、通常はそれぞれの専門的なスタッフや部門で分業される、企画、設計、ページやユーザーインターフェースのデザイン、画像制作、HTML/CSSコーディング、サーバ側(バックエンド)プログラミング、クライアント側(フロントエンド)プログラミング、テスト、機材や回線の調達・導入、ネットワーク設定、サーバ管理、システム運用、プロモーション、利用者サポートなどを一人でできる人材のことをフルスタックであるという。
キュー 【待ち行列】
最も基本的なデータ構造の一つで、要素を入ってきた順に一列に並べ、先に入れた要素から順に取り出すという規則で出し入れを行うもの。窓口などの順番を待つ人の行列をモデル化したものとも言える。
キューは先頭が常に最も古い要素になるデータ構造で、新しい要素は必ず末尾に追加される。取り出すときは常に先頭の最も古い要素から取り出される。このように先に入れたものほど先に取り出される管理方式を「FIFO」(First-In First-Out:先入れ先出し)という。
実装上は、キューのために確保された記憶領域の中ですべての要素が到着順に並ぶとは限らず、実際の位置や順序とは別に到着順や末尾の位置などの情報を内部的に記録・管理する手法が用いられることが多い。人間の行列のように要素が取り出されるたびに残りのすべての要素の物理的な位置を隣(一つ前)に移動させるのは非効率だからである。
バリエーションとして、列の両端から要素の追加や取り出しを行える「両端キュー」(double-ended queue)や、追加する要素に優先度を設定して、優先度の高いものから取り出すようにする「優先度付きキュー」(priority queue)などがある。
一方、「先に足された要素ほど後に取り出される」(末尾から順に取り出す)という規則で要素の出し入れを管理するデータ構造は「スタック」(stack)と呼ばれる。そのような管理方式を「LIFO」(Last-In First-Out:後入れ先出し)あるいは「FILO」(First-In Last-Out:先入れ後出し)という。
要素の出し入れ
キューに要素を追加する操作を「エンキュー」(enqueue)、取り出す操作を「デキュー」(dequeue)という。エンキューされた要素はキューの末尾に追加され、キューの要素数は1増加する。
デキューを指示するとキューの先頭の要素が取り出され、その要素はキューから取り除かれる。先頭から2番目にあった要素(2番目に古かったデータ)が新しい先頭になり、キューの要素数は1減少する。
キューイング (queuing/queueing)
キューを用いて要素の管理を行うことを「キューイング」(queuing)という。キューイングは機器間やプログラム間など独立に動作する二つの主体の間で非同期にデータの受け渡しを行う手法としてよく用いられる。システム間で汎用的にデータを受け渡しするシステムを「メッセージキュー」(message queue)という。
例えば、コンピュータからプリンタにデータを伝送する速度とプリンタがデータを紙に印刷する速度では、後者のほうが圧倒的に遅い。伝送と印刷を同時に行おうとするとコンピュータ側はほとんどの時間待たされることになり無駄であるため、印刷データを一旦キューに保管し、プリンタの処理の進み具合に応じて専用の制御プログラムが少しずつデータを伝送する手法が用いられる。
FIFO 【First-In First-Out】
複数の対象を取り扱う順序を表した用語で、最初に入れたものを最初に取り出す(先に入れたものを先に出す)方式のこと。
複数の対象を列を作って待機させ順番に処理する際に、列に入った順番通りに列から取り出すような構造や手順のことを意味する。窓口などで人々が行列に並んで待ち、早く来た順に呼び出されるのと同じ方式である。
コンピュータ上でデータ群を一定の形式やルールで格納するデータ構造のうち、データを一列に並べてFIFOで出し入れするものを「キュー」(queue)という。FIFO方式でデータなどを取り扱うことを「キューイング」(queueing)ということがある。
これに対し、積み上げられた座布団のように、最初に入れたものを最後に出す(先に入れたものを後に出す)方式のことは「LIFO」(Last-In First-Out)「FILO」(First-In Last-Out)、あるいは「先入れ後出し」などという。
LIFO 【Last In First Out】
複数の対象を取り扱う順序を表した用語で、最初に入れたものを最後に取り出す(先に入れたものを後に出す)方式のこと。会計の分野では「後入先出法」と呼ぶ。
複数の対象を列を作って待機させ順番に処理する際にどのような順序で行うかを表す用語で、積み重ねた座布団の出し入れのように、列に入った順番とは逆順に取り出すような構造や手順のことを意味する。
コンピュータ上でデータの集まりを一定の構造や手順によって取り扱うデータ構造のうち、「スタック」(stack)は要素の格納・取り出しをLIFOによって行なう。常に最も最近格納された要素から取り出され、一番最初に入れた最も古い要素が取り出されるのは一番最後になるという特徴がある。
これに対し、窓口の前で待っている人の行列のように、列に投入した順序の通りに処理していく(先に入れたものを先に出す)方式のことは「FIFO」(First-In First-Out/先入れ先出し)という。
プッシュ
押す(こと)、突く(こと)、勧める、お勧め、強要(する)、前進する、圧力、などの意味を持つ英単語。一般の外来語としては、ボタンなどを物理的に押すことや、推薦する(推す)などの意味で用いられる。
プッシュ配信
通信ネットワーク上で、利用者の操作するクライアントとデータや機能を提供するサーバが分離している場合に、サーバ側から能動的に情報を送信する通信方式をプッシュ型(プッシュ通知/プッシュ配信)という。一方、クライアントからの要求に基づいてサーバが応答する方式は「プル型」(pull:引く)という。
サーバ側で最新の情報や状態の変更が生じると即座にクライアント側に伝えられるメリットがあるが、通知すべきクライアントの管理や通知処理などのために大きな負荷がかかる。携帯電話事業者が契約者の端末に受信した電子メールを配信する際などに用いられる。
HTTPなどプル型の通信にしか対応しない通信方式で擬似的にプッシュ配信を行う方式として、クライアント側のソフトウェアが一定の時間間隔で定期的に更新がないか問い合わせる手法が用いられる場合があり、これを「ポーリング」(polling)という。
プッシュとポップ
プログラミングの分野で、スタックなどのデータ構造で新たにデータを一つ追加する操作や命令をプッシュという。逆に、データを一つ取り出す操作や命令は「ポップ」(pop)という。
スタックの場合、プッシュするとデータは末尾に追加され、ポップすると末尾のデータが取り出される。このように、最も新しく追加したものから順に取り出す方式を「LIFO」(Last-In First-Out/後入れ先出し)という。
ポップ
ポンという音(を立てる)、破裂する(させる)、叩く、発砲(する)、飛び出す、急に現れる、などの意味を持つ英単語。
スタックからのポップ
プログラミングの分野で、スタックなどのデータ構造に保管されたデータの中から最も最近追加されたものを取り出す操作や命令をポップという。逆に、スタックなどにデータを追加する操作や命令は「プッシュ」(push)という。
ポップを指示するとスタックの末尾の要素が取り出され、その要素はスタックから取り除かれる。末尾から2番目にあった要素(2番目に新しかった要素)が新しい末尾となり、スタックの要素数は1減少する。
ポップアップ表示
コンピュータの操作画面上で、ウィンドウなどが画面の一番手前に新たに開くことを「ポップアップ」(pop-up)という。他のウィンドウに新しいウィンドウなどを開くことは「ポップアンダー」(pop-under)という。
ポップアップは既に表示されている他の要素に覆い被されるように出現し、利用者にメッセージを伝えたり特定の操作を促したりするために用いられることが多い。
一般の外来語
一般の外来語に含まれる「ポップ」のうち、「ポップコーン」などは一般名詞の “pop” に由来するが、「ポップミュージック」(ポップス)は “popular” (ポピュラー)の短縮形で、「POP広告」や(フォントの)「POP体」は “Point Of Purchase” (販売時点:店頭のこと)という頭文字語に由来する。
木構造 【ツリー構造】
データ構造の一つで、一つの要素(ノード)が複数の子要素を持ち、子要素が複数の孫要素を持ち、という具合に階層が深くなるほど枝分かれしていく構造のこと。
木が幹から枝、枝から葉に分岐していく様子になぞらえた名称である。木構造を構成する要素を「ノード」(node:節)と呼び、ノード間の繋がりを「エッジ」(edge)という。繋がったノード同士は親子関係を持ち、親を持たない始祖のノードを「根ノード」(root node:ルートノード)という。根ノードに近い側が「親ノード」(parent node)で、遠い側が「子ノード」(child node)である。
親は複数の子を持つことができるが、子はただ一つの親を持つ。親が共通の子ノード同士は「兄弟ノード」(sibling nodes)という。一つ以上の子を持つノード(いずれのノードの親であるノード)を「枝ノード」(branch node)「内部ノード」(internal node/inner node)「中間ノード」(intermediate node)「非終端ノード」(non-terminal node)などという。
子の無い末端のノードは「葉ノード」(leaf node:リーフノード)「終端ノード」(terminal node)「外部ノード」(external node/outer node)という。あるノードより根ノード側にあるノード群を「先祖ノード」(ancestor nodes)、葉ノード側にあるノード群を「子孫ノード」(descendant nodes)と呼ぶことがある。
根を基準に、あるノードまでのエッジの数を「深さ」(depth/level)という。根ノードの深さは0となる。また、あるノードを基準に、その子孫の葉ノードのうち最も深いものまでのエッジ数を「高さ」(height)という。根ノードの高さは最も深い葉ノードの深さに等しく、これが木構造全体の高さとなる。同じ深さにあるノードの数を「幅」(width)という。
現実の木は地中の根から上に向かって幹や枝を伸ばし、葉が上方にあるが、木構造を図示する際にはこれとは逆に、根ノードを図の最上部に描き、一段下に子ノード群、その下に孫ノード群、といった具合に下向きに広がるように描くことが多い。家系図の描き方と同じである。
木構造は子の数についての制約によって分類することが多い。例えば、子の数が2に制限されている木を「二分木」(二進木、バイナリツリー)と呼び、3つ以上の子を持つことができるものを「多分木」という。そのうち、子の数がN個(Nは3以上の自然数)に制限されている木を「N分木」(N進木)という。
他の性質による分類も用いられる。例えば、葉の深さがなるべく等しくなるように構築された木を「平衡木」(バランス木)と呼ぶ。二分木かつ平衡木であれば「平衡二分木」で、多分木の平衡木にはB木などがある。他にも用途によって様々な木構造が考案され、様々な場面に応用されている。
木の中で特定のノードおよびその子孫を「部分木」(subtree:サブツリー)という。複数の木からなる集合を「森」(forest:フォレスト)ということがある。
多分木 (multi-branch tree/multi-way tree)
木構造のうち、親ノードが3つ以上の子ノードを持つことができるもの多分木という。二分木ではノードに格納される値は一つだが、多分木ではノードに複数の値を格納し、子ノードの参照と対応付けた構造にする場合がある(B木など)。子の数に制約がなくいくつでもよい場合と、子が特定の数以下でなければならない「N分木」が含まれる。
N分木 (N進木/N-ary tree/N-way tree)
木構造のうち、親ノードが持つ子ノードの数がN個に制限されているものをN分木あるいはN進木という。
Nは2以上の自然数を表し、Nが2であるような(2個以下の子しか持てない)ものは「二分木」と呼ばれるため、通常はNが3以上の木を総称してN分木という。例えば、子が必ず3つ以下のものは「三分木」、4つ以下のものは「四分木」である。“N”の代わりに“K”や“M”などの文字を用いて表記されることもあるが、意味は同じである。
N分木のうち、子を持つノードの子の数がすべてN個であるようなものを「全N分木」(full N-ary tree)、全N分木のうち、すべての葉の深さが揃っているものを「完全N分木」(perfect N-ary tree)という。また、最下層を除いてすべての階層がノードで満たされ、最下層の葉ノードが可能な限り左に寄せられているような木を “complete N-ary tree” と呼び、これを完全N分木とすることもある。
ヒープ
データ構造の一種で、木構造(ツリー構造)のうち、親要素が子要素より常に大きい(あるいは小さい)という条件を満たすもの。また、コンピュータプログラムが利用するメモリ領域の種類の一つで、実行時に任意のタイミングで確保や解放が可能なものをヒープ領域というが、これをヒープと略す場合がある。
データ構造のヒープ
親要素が複数の子要素を持つ、階層状に枝分かれしていくデータ構造を「木構造」(ツリー構造)というが、ヒープはその特殊な場合の一つである。「どの親要素も自分の子要素より常に大きいか等しい」(あるいは、常に小さいか等しい)という制約を満たすように構成されたものを指す。子要素間の関係に制約はない。
次の要素への参照を表すポインタ的なデータがなくても単純な配列などで実装でき、根要素(ルート要素)が常に最も大きく(あるいは小さく)なるという特徴がある。根要素を取り除いて残りの要素で木を再構築するという処理を繰り返して要素全体を整列(ソート)する手法を「ヒープソート」(heap sort)と呼び、最も高速なソートアルゴリズムの一つとして知られる。
ヒープ領域 (ヒープメモリ)
コンピュータプログラムが実行時に使用するメモリ領域の一つで、任意に確保や解放を繰り返すことができるものを「ヒープ領域」「ヒープエリア」(heap area)あるいは「ヒープメモリ」(heap memory)という。これを指して単にヒープと略すことも多く、データ構造のヒープと混同しないよう文脈に注意する必要がある。
ルートノード 【根ノード】
木のように枝分かれするデータ構造である木構造(ツリー)を構成する要素(ノード)のうち、最上位に位置するノードのこと。最初に作られるノードで、木の中で唯一、親ノードを持たない。
木構造とは一つの要素(ノード)が複数の子ノードを持ち、子ノードが複数の孫ノードを持ち…、という具合に階層が深くなるほど枝分かれしていくデータ構造で、これを根から幹や枝が伸びて分かれていき葉に至る木の形になぞらえている。
木の根本となる、最初に存在するノードがルートノードで、一つの木には必ず一つのルートノードがあり、二つ以上のノードが根となることはない。木構造を図示する際には木を逆さまにしたように根を一番上に置き、下に向かって枝分かれするように描くため、実際の木の根は最も下にあるが、ルートノードは木構造の「頂点」「最上位」と形容される。
木を構成するすべてのノードは、自分の親ノードの親ノードの…と上位に枝をたどっていくと最終的にはルートノードに到達する。逆に、ルートノードから子ノードの子ノードの…と下位に向かってたどっていけば、すべてのノードに到達することができ、各ノードへの経路は一意に定まる。ルートノードとは逆に、木の末端にあり子ノードを持たないノードのことを「リーフノード」(leaf node)「葉ノード」という。
リーフノード 【葉ノード】
木のように枝分かれするデータ構造である木構造(ツリー)を構成する要素(ノード)のうち、それ以上先のない末端に位置するノードのこと。親ノードを持つが子ノードを持たない。
木構造とは一つの要素(ノード)が複数の子ノードを持ち、子ノードが複数の孫ノードを持ち…、という具合に階層が深くなるほど枝分かれしていくデータ構造で、これを根から幹や枝が伸びて分かれていき葉に至る木の形になぞらえている。
木の葉となる、末端に存在するノードがリーフノードで、一つの木には複数のリーフノードが存在することができる。木構造を図示する際には木を逆さまにしたように根を一番上に置き、下に向かって枝分かれするように描くため、実際の木の葉は上の方にあるが、リーフノードは木構造の「最下位」と形容されることもある。
木を構成するすべてのノードは、自分の子ノードの子ノードの…と下位に枝をたどっていくと最終的にはリーフノードに到達し、それ以上先にたどることはできない。リーフノード以外のノード群はすべて子ノードを持っており、総称して「内部ノード」(inner node)と呼ぶことがある。リーフノードとは逆に、木の根本(図上では頂点、最上位)にあり親ノードを持たないノードを「ルートノード」(root node)「根ノード」という。
ブランチ
枝、支流、支店、支線、分岐(する)、などの意味を持つ英単語。一般の外来語としては、企業などの支店・拠点のことを指す場合が多い。
ITの分野では、木のように枝分かれした構造のデータ集合(木構造/ツリー構造)などにおいて、要素間を結ぶ繋がりのことをブランチと呼ぶことが多い。木の枝になぞらえた表現である。
バージョン管理システムのブランチ
ファイルの変更履歴を保存・追跡できるバージョン管理システムでは、ファイルやプロジェクトのある時点以降の変更履歴の流れを分岐させて別の系統として独立させることができる機能があり、この分岐した流れのことをブランチという。
元の系統から別のブランチを派生させることにより、開発中のソフトウェアからリリース用の版を分岐させて安定させたり、ある開発プロジェクトの内容を受け継いで別の目的のプロジェクトを立ち上げたりすることができる。
他から分岐したのではない(親ブランチを持たない)オリジナルの系統のことを「トランク」(trunk)、「メインライン」(mainline)などと呼ぶ。分離したブランチを再び元のブランチに統合することができるシステムもあり、この操作をマージ(merge)という。
二分木 【バイナリツリー】
データ構造の一つである木構造(ツリー構造)のうち、どの親ノードも二つ以下の子ノードを持つもの。子がN個以下に制限されたN分木(N-ary tree)のうち最も単純な構造の木である。
木構造はグラフ構造のうち要素に親子関係があり、親が複数の子を持つことができるようなものを意味し、根ノード(root node)を頂点として階層的に枝分かれしていく構造となる。
2分木はこのうち、どの親ノードも子ノードを一つか二つしか持たないという制限が課せられたものを指し、図示したときに左側にあるものを左ノード、右にあるものを右ノードという。子は一つのみの場合もあり、子がないノードは末端の葉ノード(leaf node)となる。
全二分木/完全二分木 (full binary tree/perfect binary tree)
2分木のうち、(子のない葉ノードを除く)子を持つノードの子の数がすべて二個ずつであるようなものを「全二分木」(full binary tree)、全二分木のうちすべての葉ノードの深さが揃っているものを「完全二分木」(perfect binary tree)という。
また、最下層を除いてすべての深さがノードで満たされ、最下層の葉ノードが可能な限り左に寄せられているような木を “complete N-ary tree” と呼び、これを完全二分木とすることもある。
二分木 【バイナリツリー】
データ構造の一つである木構造(ツリー構造)のうち、どの親ノードも二つ以下の子ノードを持つもの。子がN個以下に制限されたN分木(N-ary tree)のうち最も単純な構造の木である。
木構造はグラフ構造のうち要素に親子関係があり、親が複数の子を持つことができるようなものを意味し、根ノード(root node)を頂点として階層的に枝分かれしていく構造となる。
完全2分木はこのうち、どの親ノードも子ノードを一つか二つしか持たないという制限が課せられたものを指し、図示したときに左側にあるものを左ノード、右にあるものを右ノードという。子は一つのみの場合もあり、子がないノードは末端の葉ノード(leaf node)となる。
全二分木/完全二分木 (full binary tree/perfect binary tree)
完全2分木のうち、(子のない葉ノードを除く)子を持つノードの子の数がすべて二個ずつであるようなものを「全二分木」(full binary tree)、全二分木のうちすべての葉ノードの深さが揃っているものを「完全二分木」(perfect binary tree)という。
また、最下層を除いてすべての深さがノードで満たされ、最下層の葉ノードが可能な限り左に寄せられているような木を “complete N-ary tree” と呼び、これを完全二分木とすることもある。
平衡木 【バランス木】
木構造の一種で、根ノードから子を持たない末端の葉ノードまでの深さ(高さ)がなるべく等しくなるように構築されたもの。
木構造は単一の根ノードを起点に「親ノードは複数の子ノードを持つことができる」という規則に従ってノードを連結したデータ構造で、根から末端の葉に至るまでに通過する階層の数を「深さ」という。
バランス木はこの階層の深さがどの葉もなるべく均等になるように調整した木構造である。ノードの追加や削除の際に一定のルールで木を再構成し、深さ等しく保たれるように操作する。根からどの葉までたどってもほぼ同じ数のノードを経由するため、探索などの処理をする際に平均の計算時間を短縮することができる。
二分木を平衡にした構造を「平衡二分木」(balanced binary tree)という。そのうち、どのノードの値も左の子ノードより小さく、右の子ノードより大きくなるように値を配置した「平衡二分探索木」が二分探索に適したデータ構造としてよく用いられる。多分木のバランス木である「B木」(Bツリー)やその派生構造も実用上重要である。
順序木 【順序付き木】
データ構造の一つである木構造(ツリー)のうち、各ノードに数値などが割り当てられ、その大小によって順序が存在するもの。
木構造はグラフ構造のうち要素に親子関係があり、親が複数の子を持つことができるようなものを意味し、根ノード(root node)を頂点として階層的に枝分かれしていく構造となる。
順序木はこのうち、ノードに整数などの数値や何らかの順序性のあるデータが格納され、親ノードと子ノード、あるいは親から見て複数の子ノードの間に順序を付けて区別するものを指す。コンピュータ上で扱うデータのほとんどは何らかの順序性を持つため、ほとんど順序木となる。
順序木のうち、親子関係にあるノードの値が常に「親≧子」あるいは「親≦子」となるように構築したものを「半順序木」(partially ordered tree)あるいは「ヒープ」(heap)という。根ノードが最大または最小となる特徴があり、高速な整列アルゴリズムである「ヒープソート」などに応用される。
木構造 【ツリー構造】
データ構造の一つで、一つの要素(ノード)が複数の子要素を持ち、子要素が複数の孫要素を持ち、という具合に階層が深くなるほど枝分かれしていく構造のこと。
木が幹から枝、枝から葉に分岐していく様子になぞらえた名称である。多分木を構成する要素を「ノード」(node:節)と呼び、ノード間の繋がりを「エッジ」(edge)という。繋がったノード同士は親子関係を持ち、親を持たない始祖のノードを「根ノード」(root node:ルートノード)という。根ノードに近い側が「親ノード」(parent node)で、遠い側が「子ノード」(child node)である。
親は複数の子を持つことができるが、子はただ一つの親を持つ。親が共通の子ノード同士は「兄弟ノード」(sibling nodes)という。一つ以上の子を持つノード(いずれのノードの親であるノード)を「枝ノード」(branch node)「内部ノード」(internal node/inner node)「中間ノード」(intermediate node)「非終端ノード」(non-terminal node)などという。
子の無い末端のノードは「葉ノード」(leaf node:リーフノード)「終端ノード」(terminal node)「外部ノード」(external node/outer node)という。あるノードより根ノード側にあるノード群を「先祖ノード」(ancestor nodes)、葉ノード側にあるノード群を「子孫ノード」(descendant nodes)と呼ぶことがある。
根を基準に、あるノードまでのエッジの数を「深さ」(depth/level)という。根ノードの深さは0となる。また、あるノードを基準に、その子孫の葉ノードのうち最も深いものまでのエッジ数を「高さ」(height)という。根ノードの高さは最も深い葉ノードの深さに等しく、これが木構造全体の高さとなる。同じ深さにあるノードの数を「幅」(width)という。
現実の木は地中の根から上に向かって幹や枝を伸ばし、葉が上方にあるが、多分木を図示する際にはこれとは逆に、根ノードを図の最上部に描き、一段下に子ノード群、その下に孫ノード群、といった具合に下向きに広がるように描くことが多い。家系図の描き方と同じである。
多分木は子の数についての制約によって分類することが多い。例えば、子の数が2に制限されている木を「二分木」(二進木、バイナリツリー)と呼び、3つ以上の子を持つことができるものを「多分木」という。そのうち、子の数がN個(Nは3以上の自然数)に制限されている木を「N分木」(N進木)という。
他の性質による分類も用いられる。例えば、葉の深さがなるべく等しくなるように構築された木を「平衡木」(バランス木)と呼ぶ。二分木かつ平衡木であれば「平衡二分木」で、多分木の平衡木にはB木などがある。他にも用途によって様々な多分木が考案され、様々な場面に応用されている。
木の中で特定のノードおよびその子孫を「部分木」(subtree:サブツリー)という。複数の木からなる集合を「森」(forest:フォレスト)ということがある。
多分木 (multi-branch tree/multi-way tree)
多分木のうち、親ノードが3つ以上の子ノードを持つことができるもの多分木という。二分木ではノードに格納される値は一つだが、多分木ではノードに複数の値を格納し、子ノードの参照と対応付けた構造にする場合がある(B木など)。子の数に制約がなくいくつでもよい場合と、子が特定の数以下でなければならない「N分木」が含まれる。
N分木 (N進木/N-ary tree/N-way tree)
多分木のうち、親ノードが持つ子ノードの数がN個に制限されているものをN分木あるいはN進木という。
Nは2以上の自然数を表し、Nが2であるような(2個以下の子しか持てない)ものは「二分木」と呼ばれるため、通常はNが3以上の木を総称してN分木という。例えば、子が必ず3つ以下のものは「三分木」、4つ以下のものは「四分木」である。“N”の代わりに“K”や“M”などの文字を用いて表記されることもあるが、意味は同じである。
N分木のうち、子を持つノードの子の数がすべてN個であるようなものを「全N分木」(full N-ary tree)、全N分木のうち、すべての葉の深さが揃っているものを「完全N分木」(perfect N-ary tree)という。また、最下層を除いてすべての階層がノードで満たされ、最下層の葉ノードが可能な限り左に寄せられているような木を “complete N-ary tree” と呼び、これを完全N分木とすることもある。
探索木
データ構造の一つである木構造のうち、値の探索に適した性質を備えたもの。どの要素(ノード)の値も、左側のすべての子ノードの値より大きく、右側よりは必ず小さくなるよう調整したもの。
木構造は各ノードが値と複数の子ノードへの参照を持つ構造で、単一の根本(根ノード)から階層的に枝分かれしていくようにノードが連なっている。子の数が2つまでに制限された「二分木」、任意の数持てる「多分木」(N分木)などの種類がある。
探索木は特定の値を高速に探し出すことができるようにした木構造である。最も単純な二分木を用いた「二分探索木」の場合、木にノードを追加する際、「左側の子孫(部分木)の値がすべて自分より小さく、右側はすべて大きい」という条件を満たす位置を探し出して、そこに追加する。
この木を用いてある検索値を探索するには、根本から順に「現在のノードの値より検索値が小さければ左の子ノードに、大きければ右に遷移する」というルールで木をたどっていき、値が一致するノードに到達すれば発見、見つからないまま末端(葉ノード)に到達すれば検索値は存在しないことがわかる。
二分探索木 【2分探索木】
データ構造の一つである二分木(バイナリツリー)のうち、各ノードの値よりも左の子ノードの値の方が小さく、右の子ノードの値の方が大きくなるように構築したもの。データの探索に適したデータ構造である。
木構造はグラフ構造のうち要素に親子関係があり、親が複数の子を持つことができるようなものを意味し、根ノード(root node)を頂点として階層的に枝分かれしていく構造となる。どの親ノードも子ノードを一つか二つしか持たないという制限を課されたものを「二分木」(binary tree/2分木)という。
2分探索木は二分木を構築する際に、どのノードも「左の子孫の値≦自らの値≦右の子孫の値」という条件を満たすように値を挿入していく。根ノードから出発して、挿入値が現在のノードより小さければ左の子、大きければ右の子ノードに移動していき、末端のノード(葉ノード)に達したら次に移動すべき場所に新たなノードを作成して値を格納する。N個の値の挿入には O(log N) の計算量がかかる。
格納された値を探索する際には、根ノードから出発して、各ノードの値が探索している値より大きければ左の子に、小さければ右の子ノードに移動していき、葉ノードまでたどる間に値が見つかれば探索は打ち切り、葉ノードに至っても値が見つからなければ「目的の値は存在しない」という結論になる。ノードがN個の木の探索には O(log N) の計算量がかかる。
このような探索法を「二分探索」(バイナリサーチ/二分探索法)という。根から葉までの深さ(高さ)の数だけ値を調べればよく、値を単純に端から順番に調べるより効率的に探索できる。なお、木にデータを追加する際に親と同じ値を左右どちらのノードに入れるかは任意だが、毎回異なることがないようあらかじめ決めておく。
平衡二分探索木 (self-balancing binary search tree)
2分探索木のうち、根ノードから子を持たない末端の葉ノードまでの深さ(高さ)がなるべく均等になるように構築されたものを「平衡二分探索木」という。
2分探索木で値を探索するには、根ノードから出発して、各ノードの値が探索している値より大きければ左の子に、小さければ右の子に移っていくが、枝によって深さがまちまちだと探索終了までの比較回数にばらつきが出る。
根から葉までの距離がなるべく均等な方が比較回数が揃って平均的に効率よく探索できるため、平衡二分探索木では値の挿入や削除の際に高さが均等になるような処理を行う。代償として、木の構築の際には平衡を考慮しない単純な二分探索木より時間がかかる。
B木 【B tree】
木構造の一つで、多分木かつ平衡木(バランス木)であるようなもの。いくつかの派生構造が知られ、ファイルシステムやデータベースなどでよく用いられる。
木構造は単一の根ノードを起点に「親ノードは複数の子ノードを持つことができる」という規則に従ってノードを連結したデータ構造で、根から末端の葉に至るまでに通過する階層の数を「深さ」という。
B木は親が3つ以上の任意の数の子を持つことができる「多分木」で、どの葉の深さもなるべく均等になる「平衡木」としての性質も兼ね備えている。二分木とは異なり、一つのノードに複数の値(キー)が登録される。
各ノードはn個の子ノード(C1~Cn)と、n-1個のキー(K1~Kn-1)を持っている。nの数はノードごとに異なってよいが、最大値は決まっている。キーは昇順(小さい順)に整列(ソート)されており、子ノードへのリンクは各キーの中間にあるとみなされる。C1はK1の左、C2はK1とK2の中間、…CnはKn-1の右といった具合である。
例えば、キーとして自然数を格納できるB木で、根ノードが3つのキー(5,10,15)と4つの子ノード(C1,C2,C3,C4)を持つとき、キー1~4はC1(およびその子孫)に、6~9はC2に、11~14はC3に、16以上はC4にそれぞれ格納される。
この木から「13」を探索したい場合、まず根ノードのキーを探索する。存在しないので、最も近い10と15の間にある子ノードC3をたどってそのキーを調べる。この操作を繰り返し子孫ノードに適用し、途中でキーが見つかれば探索終了となり、葉ノードまで探しても無ければ存在しないことがわかる。
値を挿入するには、探索によって値が存在すべきノードを確定し、キーに空きがあれば登録する。空きが無ければノードを中央のキーで2つに分割する。中央のキーを親ノードに移し、その左右に分割したノードへのリンクを登録する。親のキーもいっぱいの場合は再帰的に上位のノードへ分割処理を繰り返していく。
多数の値を効率よく管理できるため、記憶装置の領域(ブロック)の管理などで広く応用されている。B+木やB*木などの派生構造が考案されており、リレーショナルデータベース(RDBMS)のインデックス管理やファイルシステムのブロック管理などに用いられている。
深さ優先探索 【DFS】
グラフや木構造を探索するためのアルゴリズムの一つで、それ以上先に進めない行き止まりのノードに出くわすまで経路を戻らずに隣接ノードを進んでいく方式。
グラフや木はあるノードから複数のノードへ経路が伸びている場合があり、すべてのノードを探索したい場合にどのような順番で辿っていくかについていくつかの戦略が考えられる。
深さ優先探索は探索を開始する頂点からの距離(深さ)が離れるように進んでいく方式で、それ以上進めない末端(木の場合は葉ノード、グラフの場合はすべての隣接ノードが探索済みの場合も含む)まで来たら、経路を遡って最初の未探索ノードへ進む。その先で末端に到達したら、再び経路を遡り…という手順を終了まで繰り返す。
最後(最も最近)に追加された候補を優先的に探索するLIFO(Last-In First-Out)方式で次に進むノードを決定するため、探索候補ノードの記録にはスタック(stack)というデータ構造が適している。関数の再帰呼び出しを用いると非常に簡潔にプログラムを記述できる。
もう一つの有力なアルゴリズムとして、頂点からの距離が同じノードを順番に訪ねていく方式があり、「幅優先探索」(BFS:Breadth-First Search)と呼ばれる。
幅優先探索 【BFS】
グラフや木構造を探索するためのアルゴリズムの一つで、探索を開始する頂点から近い順に探索する方式。
グラフや木はあるノードから複数のノードへ経路が伸びている場合があり、すべてのノードを探索したい場合にどのような順番で辿っていくかについていくつかの戦略が考えられる。
幅優先探索は探索を開始する頂点からの距離(深さ)が等しくなるように進んでいく方式で、出発点の隣接ノード(距離1)をすべて調べ、隣接ノードの隣接ノード(距離2)をすべて調べ、そのまた隣接ノード(距離3)を…という手順を終了まで繰り返す。
最初(最も過去)に追加された候補を優先的に探索するFIFO(First-In First-Out)方式で次に進むノードを決定するため、探索候補ノードの記録にキュー(queue)というデータ構造が適している。
もう一つの有力な探索アルゴリズムとして、それ以上先に進めない行き止まりのノードに出くわすまで経路を戻らずに隣接ノードを進んでいく方式があり、「深さ優先探索」(DFS:Depth-First Search)と呼ばれる。
アルゴリズム
ある特定の問題を解く手順を、単純な計算や操作の組み合わせとして明確に定義したもの。数学の解法や計算手順なども含まれるが、ITの分野ではコンピュータにプログラムの形で与えて実行させることができるよう定式化された、処理手順の集合のことを指すことが多い。
曖昧さのない単純で明確な手順の組み合わせとして記述された一連の手続きで、必ず有限回の操作で終了し、解を求めるか、解が得られないことが示される。コンピュータで実行する場合は、基礎的な演算、値の比較、条件分岐、手順の繰り返しなどを指示する命令を組み合わせたプログラムとして実装される。
数値などの列を大きい順または小さい順に並べ替える「整列アルゴリズム」、たくさんのデータの中から目的のものを探し出す「探索アルゴリズム」、データが表す情報を損なわずにより短いデータに変換する「圧縮アルゴリズム」といった基本的なものから、画像の中に含まれる人間の顔を検出する、といった複雑なものまで様々な種類のアルゴリズムがある。
同じ問題を解くアルゴリズムが複数存在することもあり、必要な計算回数や記憶領域の大きさ、手順のシンプルさ、解の精度などがそれぞれに異なり、目的に応じて使い分けられる。例えば、ある同じ問題に対して、原理が単純で簡単にプログラムを記述できるが性能は低いアルゴリズム、計算手順が少なく高速に実行できるが膨大な記憶領域を必要とするアルゴリズム、厳密な解を求めるものより何桁も高速に近似解を求めることができるアルゴリズムなどがある。
フローチャート 【流れ図】
工程や手順の流れを図示する手法の一つで、個々の段階を箱で表し、それらを順序や論理の推移に従って矢印や線分で結んだもの。
ITの分野では、コンピュータプログラムの設計やアルゴリズム(計算手順)の理解などのために、内部で行われる処理や演算の詳細な流れを流れ図に表すことが多い。プログラムに限らず、業務手順など様々な過程や手順の図示に応用できる。
一つの流れ図には開始と終了があり、その間に一つ以上の工程が含まれる。流れは分岐や繰り返しによって複数に枝分かれしたり戻ったりすることがあるが、途中どのような経路を通っても必ず一つの開始から始まって一つの終了で終わる。
流れ図で用いる部品の種類や図記号の形状はJIS X 0121で規格化されており、一般的にはこれを用いることが多い。主な部品として、開始や終了を表す「端子」(円・楕円・角丸長方形)、「処理」(長方形)、プログラムにおけるサブルーチンや関数などの「定義済み処理」(左右が二重線の長方形)、「入出力」(平行四辺形)、条件分岐などの「判断」(菱形)、繰り返しの範囲を示す「ループ端」(開始は上側、終了は下側の角が欠けた長方形)、他の図との出入り口を示す「結合子」(小さな丸)、処理の流れを示す「線」(右や下へは線分・左や上には矢印)などがある。
ソート 【整列】
複数のデータが並んだ列を、何らかの順序に基いて順番通りになるよう並べ替えること。数値を大きい順または小さい順に並べたり、文字をアルファベット順や五十音順に並べたり、日時を古い順または新しい順に並べ替えることが該当する。
複数の同じ種類の要素が一列に並んでいる場合に、すべての要素に一律に適用可能な順序の規則を用いて並べ替える操作を意味する。数値と日付のように異なる種類の要素が混在していたり、要素間にじゃんけんの出し手のような循環的な関係性がある場合には正しく整列することができない。
数を小さい方から大きい方へ並べる順序を「昇順」(ascending order)、その逆を「降順」(descending order)という。数以外の場合、アルファベットを「A」から「Z」へ、読み仮名を「あ」から「ん」へ、日付や時刻を古い方(過去)から新しい方(未来)へといったように、本来の並び順や自然な順序を昇順、逆を降順という。
ソートアルゴリズム
コンピュータによるデータ処理でもソートは頻繁に用いられる操作で、整列手順を定式化したものを「ソートアルゴリズム」(sorting algorithm)という。古くから活発に研究され様々な手法が考案されており、計算回数の少なさ(高速さ)や必要な記憶装置の容量、手順のシンプルさ(プログラムの短さ)などが異なる。
平均的に効率が良く、広く用いられるのは「クイックソート」(quick sort)と呼ばれる手法で、要素数がn倍になると平均の計算時間が n×log2n 倍になる。プログラミング言語に標準で組み込まれた配列を整列する関数などによく採用されている。
データ列に同じ値が含まれる場合、その出現順がソート前後で変わらない手法を「安定ソート」(stable sorting)、保存されるとは限らない(順序が入れ替わることがある)手法を「不安定ソート」(unstable sorting)という。
また、元のデータ列の格納領域のみを用いて操作が完結する手法を「内部ソート」(in-place sorting)、外部に別の領域を確保する必要がある手法を「外部ソート」(external sorting)という。組み込みシステムなど利用できるメモリ領域が限られる場合には、高速性よりも内部ソートであることが重視されることもある。
マージ 【併合】
融合する、併合する、合併する、混合する、結合する、統合する、などの意味を持つ英単語。ITの分野では、複数のファイルやデータ、プログラムなどを、決められたルールに従って一つに統合する操作を指すことが多い。
また、プログラミングやソフトウェア開発の分野では、バージョン管理システムなどで管理している開発中のプログラムなどに、新たにコードを追加したり、修正を反映させたりする操作をマージということがある。
データ列などをマージするという場合には、対象全体を単純に後ろに繋いでいくのではなく、データ構造の一貫性などを保ちながら要素を取り出して融合していく操作を指すことが多い。例えば、(1,3,5)と(2,4,6)をマージするという場合、単に前後に連結して(1,3,5,2,4,6)を得るのではなく、値の大小関係を考慮して(1,2,3,4,5,6)を得る操作を指す。
検索 【サーチ】
同種のものの集まりの中から目当てのものを探し出すこと。IT分野では、データの集合の中から指定した条件を満たすデータを探す処理や操作を指すことが多い。
以前から図書館で目当ての本を(人力で)探す行為などをサーチと呼んでいたが、コンピュータの発展や普及により、大量の情報を蓄積してプログラムによる自動処理で条件に合致する情報を探し出すことができるようになり、現代ではコンピュータで情報を探すことをサーチと呼ぶことが多い。
例えば、インターネット上のWebサイトで公開されている情報を収集し、指定したキーワードに関連するサイトやページを一覧表示する「Web検索エンジン」や、コンピュータのストレージ内に格納されたファイルを索引付けし、条件に一致するものを探し出す「ファイル検索」などが馴染み深い。
コンピュータによるサーチシステムは、どのような情報を対象に、どのような条件で探すことができるかによって様々な種類に分かれる。文書などの文字データを対象とする文字列検索、画像データを対象とする画像検索、動画データを対象とする動画検索などである。
情報科学・コンピュータ科学などの分野では、データ集合の中から指定の条件に一致するものを探す処理のことを「探索」と呼ぶことが多い。「線形探索」や「二分探索」のように、対象をどのような手順で探すかを定義したものを「探索アルゴリズム」という。
英語では “search” “find” “retrieve” などが「サーチ」に近い意味を持つ。“retrieve”(名詞形はretrieval)には「探し出して実際に持ってくる」という意味がある一方、“search” や “find” には「あるかどうか調べる」「見つけたもの(の名前や所在など)を知らせる」といったニュアンスがある。コンピュータによる情報検索という文脈では “search” をサーチに対応する概念とすることが多い。
選択ソート 【基本選択法】
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの最も基本的な手法の一つで、未整列の要素の中から最大あるいは最小のものを選択し、整列済みの列の末尾に追加していくもの。
数値の列を先頭から小さい順(昇順)に並べる場合を考える。まず、先頭から末尾までの間で最も小さい値を見つけ、先頭の値と交換する。次に2番目から末尾までの間で最も小さい値を見つけ、2番目の値と交換する。
以降も同様に、「n番目から末尾までで最も小さい値を見つけ、n番目と入れ替える」という操作を繰り返す。これを末尾の一つ前の値まで繰り返せば、先頭が最も小さく末尾が最も大きい数値の列が得られる。
列の元の状態によらず O(n2) の計算量がかかるため処理時間の予測はしやすいが、ソートアルゴリズムの中では最も遅いものの一つに分類される。木構造の一種である二分ヒープ木を用いて改良した手法を「ヒープソート」(heap sort)という。
整列したいデータ列以外の記憶領域を用意しなくてよいインプレースソート(内部ソート)で、同じ大きさの要素の順序の維持は保証されない不安定ソートである。挿入ソートなどと同じように、アルゴリズムの理解や実装が容易なため、対象データ列が短いことが分かっている場合などに利用されることがある。
バブルソート 【単純交換法】
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの最も基本的な手法の一つで、端から順番に隣接する要素同士を比較・交換していくもの。
すべての要素について隣接する要素と大きさを比較し、並べたい順番と逆転していたら両者を入れ替える。この手順を最高で要素数-1回繰り返すと並べ替えが完了する。要素の入れ替えが発生しなくなった時点で処理を打ち切ってもよい。
一般的な実装では、この処理を列の一方の端から反対の端まで順番に行うことが多く、繰り返しの度に未整列の要素の中で最も大きな(あるいは小さな)要素が列の端に移動していく様子を泡(バブル)が浮き上がっていく様に例えてこのような名称となった。
最良の場合の計算時間は O(n) と高速だが、最悪の場合の計算時間は O(n2) と整列法の中でも最も遅い部類に入り、平均して高速な手法とは言えない。ただし、要素の比較・交換は順序を問わず並列化しやすいという特徴があり、並列分散処理が可能な環境では高速化することができる。
整列したいデータ列以外の記憶領域を用意しなくてよいインプレースソート(内部ソート)で、同じ大きさの要素の順序が入れ替わらない安定ソートである。アルゴリズムの理解や実装が容易で、コードの記述量が少ない。実用上はあまり使われないが、整列法の学習ではほぼ必ず取り上げられ、効率化した派生アルゴリズムも多く考案されている。
マージソート 【併合ソート】
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの一つで、データ列を細かく分割し、整列しながら次第に併合(merge)していくもの。
最初にデータ列を半分、そのまた半分と分割していき、一つ一つのデータがバラバラになるまで分割する。その後、最初は単体のデータ同士を、続いて要素数が同じ列同士を順に併合していく。
併合する際は二つの列の先頭のデータを比較し、小さい(あるいは大きい)方を取り除いて併合列に追加する。二つの列の内部はすでに整列済みであるため、両方の列のデータが無くなるまでこの手順を繰り返すことで、整列済みの併合列を得ることができる。列が一つの併合されたら整列完了となる。
平均計算時間も最悪計算時間もO(nlogn)となる極めて高速なソートアルゴリズムだが、元のデータ列の他に作業用の記憶領域を必要とする。実装上の配慮により、同じ大きさの要素の順序が入れ替わらない安定ソートとすることができる。
挿入ソート 【基本挿入法】
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの最も基本的な手法の一つで、未整列の要素を一つずつ、整列済みの列の適切な位置に挿入していくもの。
数値の列を先頭から小さい順(昇順)に並べる場合を考える。まず、先頭から2つの値を比較して小さい方を先頭に、大きい方を2番目に置く。次に3番目の値を取り出し、先頭・2番目と順に比較し、適切な位置に挿入する。
4番目以降も同様にして、n番目の値を取り出して先頭からn-1番目までと順番に比較し、適切な位置に挿入する操作を繰り返す。これを末尾の値まで繰り返せば、先頭が最も小さく末尾が最も大きい数値の列が得られる。
n番目の値を挿入する際、それが整列済みの列の中で最も小さければ先頭の値との1回の比較で挿入位置が決定できるが、最も大きければ整列済みの値の数(n-1回)だけ比較を繰り返さなければならない。
すなわち、要素が整列済みに近い状態ならば高速に整列を完了でき、最良計算時間はO(n)となるが、逆順に並んでいる場合は比較回数が爆発的に増大し、最悪計算時間は O(n2) となってしまう。この欠点をある程度緩和したアルゴリズムとして「シェルソート」(Shell sort)がある。
整列したいデータ列以外の記憶領域を用意しなくてよいインプレースソート(内部ソート)で、同じ大きさの要素の順序が維持される安定ソートである。アルゴリズムの理解や実装が容易なため、対象データ列が短いことが分かっている場合などに利用されることがある。人間に並べ替えを行わせると、多くの人がまっさきに自然に思いつく方法であるとも言われる。
シェルソート 【Shell sort】
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの最も基本的な手法の一つで、挿入ソートを改良したもの。1959年にアメリカのコンピュータ科学者ドナルド・シェル(Donald Shell)が考案した。
挿入ソートは未整列の要素を一つずつ、整列済みの列の適切な位置を探して挿入していく手法である。与えられた列が整列済みに近ければ高速に整列できる一方、逆順に近い場合には極端に遅くなる弱点があった。
シェルソートでは等間隔で離れている飛び飛びの要素同士を一つのグループとし、グループ内で挿入ソートを行う。例えば、間隔が3なら3n番目のグループ、3n+1番目のグループ、3n+2番目のグループの3つに分け、それぞれの中で整列する。
このグループごとの整列を、次第に間隔を狭めながら何度も繰り返す。最後に間隔1ですべての要素を対象に挿入ソートを実行すれば、全体の整列が完了する。飛び飛びの整列を行うことで全体が大まかに整列され、挿入ソートの弱点である「逆順に近い状態」を緩和することができる。
間隔の選択の仕方、繰り返しごとの狭め方により計算時間が異なる。当初シェルが考案した手法では、要素数nに対して「n/2,n/4,…,1」のように繰り返しごとに半分になっていく方式だが、これだと最悪計算時間が O(n2) となってしまうことが知られている。様々な手法が提唱されており、実用上は (…,121,40,13,4,1) となる (3k-1)/2 などが用いられる。
挿入ソートでは完全な逆順の場合に O(n2) かかってしまうが、現在知られている最良の間隔決定法では最悪計算時間が O(nlog2n) となることが分かっている。最良計算時間はすでにソート済みの要素列を扱う場合で、挿入ソートと同じ O(n) である。
挿入ソートは同じ大きさの要素の順序が保存される安定ソートだが、シェルソートは順序の維持が保証されない不安定ソートである。整列したいデータ列以外の記憶領域を用意しなくてよいインプレースソート(内部ソート)である点は挿入ソートと変わらない。
クイックソート
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの一つで、分割統治法を応用したもの。最も高速な手法の一つで、1960年に英コンピュータ科学者アントニー・ホーア(Charles Antony Richard Hoare)氏が考案した。
大きな問題を小さな部分問題に分割していく「分割統治法」を利用した整列法で、データ列から適当に基準値を決め、これより大きいグループと小さいグループに分けるという手順を、分けた小さなグループに対しても再帰的に繰り返していく。
基準値の選び方には様々な方式があり、これによって比較・交換回数が左右されるが、あまり複雑な決定法だと基準値を選出するのに計算量を費やしてしまうため、単純に先頭やランダムな位置を選択することも多い。
n個の要素をソートする計算量は最良でも平均でも O(nlogn) と高速だが、最悪の場合は O(n2) になってしまう欠点もある。同じ計算量オーダーとなる整列法はヒープソートなどいくつかあるが、実際に試してみると平均的にクイックソートが高速であるとされる。
元のデータ列を格納した領域以外に別の記憶領域を必要としないインプレースソート(内部ソート)だが、通常は関数の再帰呼び出しを用いて実装するため、実用上はスタックの容量が O(logn) だけ必要となる。同じ大きさの要素の順序の維持は保証されない不安定ソートである。
例
例えば、(3,7,4,2,6,1,5)という整数列を小さい順(昇順)に並べ替える場合を考える。先頭の3を基準として、左右端から反対の端に向かって値を一つずつ基準と比較していき、左から探した3以上の値が右から探した3未満の値より左にあったら交換する。両者を比べて3以上が右にあったら探索終了となる。
3と1、7と2が交換され、(1,2,4,7,6,3,5)となる。2と4を比較して探索が終わったので、この間で2つのグループに分け、(1,2)-(4,7,6,3,5)のそれぞれに同じ操作を行う。(1,2)は(1)-(2)に、(4,7,6,3,5)は(3)-(7,6,4,5)に分かれる。
(7,6,4,5)に同じ操作を繰り返すと、(5,6,4)-(7) → (4)-(6,5)-(7) → (4)-(5)-(6)-(7) と分割されながら整列されていく。分割によってすべてのグループの要素数が1になったところで整列終了となる。このとき、端から順に小さい順に値が並んでいることが分かる。
ヒープソート
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの一つで、ヒープ構造と呼ばれる二分木の一種を構築して並べ替えを行うもの。
数値の列を先頭から小さい順(昇順)に並べる場合を考える。データ構造の一種である木構造(ツリー)を用意し、未整列のデータを一つずつ取り出して登録していく。親ノードは最大で2つまでの子ノードを持ち(二分木)、親ノードがいずれの子ノードよりも小さく(あるいは大きく)なるように調整しながら追加していく。
このような制約を設けた木構造を「二分ヒープ木」あるいは「ヒープ構造」という。すべてのデータを登録すると、根ノードは全体の中で最も小さいデータとなる。これを取り出して整列済み配列の先頭に入れる。
子ノードのうち、小さいノードを根ノードに移し、その子孫のノードも同様に再構成する。新しい根ノードは残りのデータのうち最も小さいため、これを取り出して整列済み配列に追加する。以下同様に、ヒープ構造からデータがなくなるまで同じ操作を繰り返す。
ヒープ構造は木構造用の制御データを用意しなくても配列内部で表現可能なため、実装上は未整列のデータ列を徐々にヒープ構造に置き換えていき、木が完成したら今度は徐々に整列済みデータ列に置き換えていく。
外部に操作用の記憶領域を用意しなくてよいインプレースソート(内部ソート)で、同じ大きさの要素の順序の維持は保証されない不安定ソートである。平均計算量が O(nlogn) と最も速いソート法の一つで、元のデータ順の影響も受けにくいが、実際にはクイックソートの方が高速になるとされる。
線形探索 【リニアサーチ】
データ探索アルゴリズムの一つで、配列などに格納されたデータ列の先頭から末尾まで順番に、探しているデータと一致するか比較していく手法。
最も単純なアルゴリズムで、配列などに格納されたデータ列の中から、まず先頭の要素を探しているデータと比較する。一致しなければ2番目の要素と比較する。これを末尾の要素まで繰り返し、途中でデータを発見したらそこで探索を終了する。
N個のデータ列の中から線形探索法する場合、最良のケースは先頭の要素と一致する場合で比較回数は1回、最悪のケースは末尾まで探してもデータが見つからなかった場合で比較はN回、平均の比較回数はN/2回となる。比較回数の平均値は要素数に正比例して増大する。
仕組みが単純なため短いプログラムコードで記述でき、コードを読んだ人が処理を理解しやすく、探索対象のデータ列以外に余分な記憶領域を消費せず、事前にデータ列のソート(大きい/小さい順に並べ直す処理)などの前処理を行う必要がないという利点がある。より高度なアルゴリズムに比べると平均の比較回数は多く、性能の高いアルゴリズムとは言えない。
二分探索 【2分探索】
データ検索アルゴリズムの一つで、一定の順序にソート(整列)済みのデータ群の探索範囲を半分に絞り込むを操作を繰り返すことで高速に探索を行う手法。
まず、データを降順(大きい順)あるいは昇順(小さい順)に並べ替え、探索したいデータが中央の要素より大きいか小さいかを調べる。これにより、データが全体の前半分にあるか後ろ半分にあるかを判定することができるため、存在しない側の半分は探索範囲から外すことができる。
半分になったデータ群の中央の要素と再び比較し、前半と後半のどちらにあるかを調べる。この操作を繰り返し行うことで、一回の操作ごとに探索範囲の大きさが半分になっていき、中央の要素が求めるデータに一致するか、探索範囲の要素数が一つになる(求めるデータは見つからなかったことが確定する)と探索は終了する。
値の大小は文字の索引順の前後関係などに適宜置き換えることにより、順序と比較手段を定義できればどのようなデータにも適用することができる。
n個のデータ群から平均でlog2n回の比較で探索を終えることができ、例えば1000個のデータを10回の比較で探索できる。原理は単純ながら高速なアルゴリズムである。ただし、要素があらかじめ整列済みである必要があるため、未整列のデータに適用するにはソートの分の計算時間も必要となる。
ハッシュ法 【ハッシュ探索】
データ探索アルゴリズムの一つで、対象となるデータから一定の手順で算出したハッシュ値を用いてデータ本体の代わりに比較に用いる方式。対象とするデータが長い場合に処理を高速化することができる。
ハッシュ値はハッシュ関数(hash function)によって算出される固定長のデータで、任意の長さのデータから算出することができ、同じデータからは必ず同じハッシュ値が得られる。ハッシュ表探索法ではまず各データのハッシュ値を算出し、探索対象のデータもハッシュ値に変換して、ハッシュ値同士で比較を行い探索する。
長い文字列データなど、毎回データ全体を比較すると比較処理自体に長い時間がかかるような場合に、短いハッシュ値で代用することにより比較処理を高速化することができる。また、広い値域を持つデータを短い配列などに格納して、高速に書き込みや読み出しを行うことができる。
ハッシュ値の算出は他のデータの存在を考慮せず行われるため、複数の異なるデータから同じハッシュ値が算出される衝突(collision)が起きることがある。同じハッシュ値を持つデータ群をシノニム(synonym)という。
シノニムを処理する方法としては、空いているハッシュ値にデータを振り分けて衝突を解消する「オープンアドレス法」や、同じハッシュ値を持つデータを線形リストとして保存する「直接連鎖法」などがある。
深さ優先探索 【DFS】
グラフや木構造を探索するためのアルゴリズムの一つで、それ以上先に進めない行き止まりのノードに出くわすまで経路を戻らずに隣接ノードを進んでいく方式。
グラフや木はあるノードから複数のノードへ経路が伸びている場合があり、すべてのノードを探索したい場合にどのような順番で辿っていくかについていくつかの戦略が考えられる。
深さ優先探索は探索を開始する頂点からの距離(深さ)が離れるように進んでいく方式で、それ以上進めない末端(木の場合は葉ノード、グラフの場合はすべての隣接ノードが探索済みの場合も含む)まで来たら、経路を遡って最初の未探索ノードへ進む。その先で末端に到達したら、再び経路を遡り…という手順を終了まで繰り返す。
最後(最も最近)に追加された候補を優先的に探索するLIFO(Last-In First-Out)方式で次に進むノードを決定するため、探索候補ノードの記録にはスタック(stack)というデータ構造が適している。関数の再帰呼び出しを用いると非常に簡潔にプログラムを記述できる。
もう一つの有力なアルゴリズムとして、頂点からの距離が同じノードを順番に訪ねていく方式があり、「幅優先探索」(BFS:Breadth-First Search)と呼ばれる。
幅優先探索 【BFS】
グラフや木構造を探索するためのアルゴリズムの一つで、探索を開始する頂点から近い順に探索する方式。
グラフや木はあるノードから複数のノードへ経路が伸びている場合があり、すべてのノードを探索したい場合にどのような順番で辿っていくかについていくつかの戦略が考えられる。
幅優先探索は探索を開始する頂点からの距離(深さ)が等しくなるように進んでいく方式で、出発点の隣接ノード(距離1)をすべて調べ、隣接ノードの隣接ノード(距離2)をすべて調べ、そのまた隣接ノード(距離3)を…という手順を終了まで繰り返す。
最初(最も過去)に追加された候補を優先的に探索するFIFO(First-In First-Out)方式で次に進むノードを決定するため、探索候補ノードの記録にキュー(queue)というデータ構造が適している。
もう一つの有力な探索アルゴリズムとして、それ以上先に進めない行き止まりのノードに出くわすまで経路を戻らずに隣接ノードを進んでいく方式があり、「深さ優先探索」(DFS:Depth-First Search)と呼ばれる。
ダイクストラ法 【Dijkstra's algorithm】
様々な経路が考えられる二地点間の最短距離を求めるアルゴリズムの一つ。地点間を繋ぐ辺に距離に相当する重みがある場合を対象に、効率的に最短経路を求めることができる。
始点と終点の間に様々な経由地点(ノード)が散らばっており、ノード間が様々な重みの辺(エッジ)で繋がっているときに、どの経路が最短となるかを求める手順を定めている。エッジの重みは0以上である必要があり、負数を含む場合は他のアルゴリズムが必要となる。
ダイクストラ法では各ノードに始点からの距離(到達経路に含まれる辺の重みの合計)を書き込み、処理の進行に伴って書き換えていく。始点の距離は0であり、終点を含めた始点以外のノードの距離はとりあえず「∞」(無限大)を書き込んで初期化しておく。
「その時点で距離が最小のノードの距離は確定し、そのノードを起点に隣接する(かつ未確定の)ノードの距離を算出し、既存の値より小さければ書き換える」という手順を繰り返す。初回で確定するのは始点の「0」で、始点の隣接ノードに辺の重みを書き込んでいく。
始点の隣接ノードの中で最小の距離のノードはそこで確定となり、次はそのノードに隣接し距離が未確定のノードに距離を書き入れていく。まだ一度も書き込んでいないノードは距離が∞なので隣接ノードからの距離に更新され、他の経路の値が存在するノードは新しい値がより小さければ更新する。
この手順を繰り返していくと、毎回その時点で最も距離が小さいノードが一つずつ確定していく。最終的には終点の値のみが未確定の状態となり、その時点で終点に書き込まれている値が始点から終点までの最短距離となる。各ノードについて最短距離の場合の一つ手前のノードを記録しておくことで、最短経路も知ることができる。
1959年にオランダのコンピュータ科学者エドガー・ダイクストラ(Edsger W. Dijkstra)によって考案されたアルゴリズムで、グラフ理論の基本的なアルゴリズムとしてよく知られる。ネットワーク上のパケットのルーティング、道路や交通機関の経路検索など実用上も広く応用されている。
形態素解析
自然言語で書かれた文を言語上の最小単位である形態素に分割し、それぞれの品詞や変化などを割り出すこと。ITの分野ではコンピュータによる自然言語処理の一つとして、かな漢字変換や全文検索、機械翻訳などで用いられる。
日本語や英語など人間が普段使っている自然言語において、文中で意味をなす最小の構成要素を形態素(morpheme)という。文がどのような要素によって構成されているかを調べるために、形態素の列に分解してそれぞれの文法上の属性(品詞の種類や活用形など)を明らかにしていく処理を形態素解析という。
例えば、“This is a pen.” という英文は “this”(代名詞)、“is”(be動詞)、“a”(不定冠詞) “pen”(一般名詞)のように分解できる。“apples”を“apple”(名詞)と“-s”(接尾辞/複数形)の組み合わせであるというように、一つの単語を接尾時・接頭辞や語幹などに分解する場合もある。
日本語では「これはペンです」を「これ」(代名詞)「は」(係助詞)「ペン」(一般名詞)「です」(助動詞)のように分解できる。文法上の要素に分解していくため、「食べた」は一語ではなく「食べ」(動詞/連用形)「た」(助動詞)に分かれる。
コンピュータによる形態素解析処理は、当該言語の文法規則や、単語や接辞などの要素を列挙した辞書データを用いて行う。英語などアルファベット圏の言語は単語ごとに短い空白をあける「分かち書き」をするため、基本的に単語の接辞や変化を調べるだけでよいが、日本語や韓国語などでは単語に分けず一文を続けて記すため、単語分割の段階で複雑な処理や大量の辞書データが必要となる。
また、自然言語では複数の異なる解釈が可能で、辞書や規則の機械的な適用だけでは一意に定まらない表現なども存在するため、慣用句や自然な表現を集めた文例データや、要素間の連結についての統計的なデータを用いて精度を向上させる場合もある。
構文解析
文の内容を解析し、その構成要素がどのような関係にあるかを明らかにすること。自然言語に用いる場合とコンピュータ言語に用いる場合で手法が大きく異なる。
コンピュータ言語の構文解析
プログラミング言語やマークアップ言語などのコンピュータ言語で書かれた文を構成要素に分解し、要素間の関係を元に特定のデータ構造に変換する操作を構文解析という。
コンピュータ言語で書かれたソースコードに「字句解析」(lexical analysis)を行い、言語仕様上意味を成す字句の最小単位であるトークンの列に置き換える。その後、言語の構文規則に従ってトークン間の関係性を解析し、構文木などのデータ構造として表す。狭義には後者のトークンの処理のみを構文解析とする場合もある。
得られた構文木から何が行われるかは言語の種類によって異なり、プログラミング言語であればオブジェクトコード(機械語のプログラム)の生成、マークアップ言語であれば画面描画、データベース言語であればデータベースへの操作などが行われることになる。
自然言語の構文解析
英語や日本語などの自然言語における構文解析では、単語単位に分解済みの文を対象に、文法や統語論を元に単語間の関係を決定し、何らかのデータ構造で表現する。
英語のように分かち書き(単語間を空白で離す)する言語では、与えられた文を空白によって即座に単語に分割することができるが、日本語などでは前処理として文を語彙や文法に基づいて単語に切り分ける「形態素解析」が必要となる。
構文解析は各種の自然言語処理の基礎技術として重要で、機械翻訳や要約生成、自然言語検索、音声アシスタントなど様々な分野に応用されている。
デシジョンテーブル 【判断表】
複数の判断条件の正否の組み合わせを列挙し、それぞれの場合についてどのような判断を下すかを一覧にまとめた表。
一般的な表現形式では、表の上半分を条件、下半分を判断(動作、行動ということもある)とし、左端の列に条件や判断の項目を列挙する。条件の行には右にその正否(当てはまるか否か)を列挙していくが、このとき各列の正否の組み合わせがすべて異なるようにする。判断の行には、各列の条件の組み合わせの時にどのような判断となるかを記載していく。
列の数は条件の組み合わせの数だけ必要なため、2の条件数乗となる。すなわち、条件が2つなら(条件A:Yes,条件B:Yes)(Yes,No)(No,Yes)(No,No)の4列だが、3つなら8列、4つなら16列といったように条件が増えることに2倍に増えていく。
決定表は様々な分野で用いられるが、ITの分野ではシステム開発などでシステムの挙動を指定するために仕様書などに記載したり、テスト時にテストケースと正しい結果の対応関係を分かりやすく整理するために用いられることが多い。
再帰 【リカーシブ】
あるものの定義や記述に、それ自身が含まれること。そのような定義を「再帰的定義」という。
例えば、フィボナッチ数列の定義 Fn+2=Fn+1+Fn は、数列のある項を算出するのに手前の項の値を用いている。このように、自身のある段階を定義するために、自らの別の段階や状態を参照するような構造を再帰という。
再帰が成り立つためには、再帰を用いずに定義される基底段階と、最終的に基底段階にたどり着くような各段階の導出手順が必要となる。いずれかが欠けた自己言及的な定義は無限後退や循環参照を引き起こし、各段階の状態が確定できなくなる。
プログラミングの分野では、関数やメソッドなどの処理内容の記述の中に、自身の呼び出しを行なうコードが含まれることを「再帰呼び出し」(recursive call:リカーシブコール)と呼び、そのような関数を「再帰関数」(recursive function)という。
こうした構造を用いて記述されるアルゴリズムを「再帰的アルゴリズム」(recursive algorithm)という。フィボナッチ数列の列挙や階乗の計算 n!=n×(n-1)! のように定義に再帰的な構造が含まれる場合には、再帰的なプログラム構造によってシンプルに実装することができる。
また、プログラムが取り扱うデータ構造について、要素として配列を格納した配列、要素として木構造を格納した木構造など、あるデータ構造の要素としてそのデータ構造が収まっているような入れ子状の構造を「再帰的データ構造」「再帰データ型」などと呼ぶことがある。
分割統治法
大きな問題を効率的に解く手法の一つで、問題全体を同じ構造の小さな問題に再帰的に分割していき、簡単に解けるサイズにした上で解いていく方式。
対象のデータが多いなど規模の大きな問題を、相似的な構造を持つ小さな部分問題に分割し、部分問題が大きい場合は再帰的に同じ分割手順を繰り返して問題のサイズをどんどん小さくしていく。
それ以上分割できない規模や簡単な手順で解ける規模になったら、これを解いて部分問題の解を求める。求めた多数の部分問題の解を分割と逆方向に順番に併合していき、全体を一つに統合すると最初の大きな問題の解となる。
様々な問題を解くアルゴリズム(計算手順)に応用される基本的な考え方で、コンピュータでは関数などの再帰呼び出しと組み合わせることで簡素な論理構造や短いプログラムで大きな問題を効率よく解くことができる。
値の比較・交換の少ない高速なソート(整列)アルゴリズムとして知られるマージソート(併合ソート)やクイックソートなどの応用例が有名である。
プログラミング
コンピュータに意図した動作を行わせるために、まとまった処理手順を作成し、与えること。作成された手順のことを「コンピュータプログラム」(computer program)あるいは単にプログラムという。
狭義には、プログラミング言語やそれに相当する仕組みや道具を用いて、人間が読み書きしやすい形式のプログラム(ソースコード)を記述していく「コーディング」(coding)作業を指す。広義には、その前後に行われる、設計や試験(テスト)、修正(デバッグ)、実行形式や配布形式への変換(コンパイルやビルドなど)といった一連の作業を含む。プログラミングを行う人や職種のことを「プログラマ」(programmer)という。
プログラムの作成
プログラミングを行うには、まず何をするプログラムを作るのかを明確に定義し、仕様や要件を自然言語で記述したり、大まかな処理の流れを箇条書きやフローチャートなどの図表を用いて設計する。集団でソフトウェア開発を行う場合はプログラムの記述者とは別の設計者が専門に作業を行い、仕様書や設計書などの形でまとめる場合もあるが、個人が小規模のプログラムを作成する場合はこの工程を頭の中で行い、作業や手順としては省略する場合もある。
どんなプログラムを作りたいか決まったら、これをコンピュータが解釈できるプログラミング言語を用いてソースコードとして記述していく。言語やプログラムの記述法には様々な種類があるが、手続き型の言語(手続き型プログラミング)の場合、実行すべき命令を先頭から順に書き下していく。必要に応じて、複数の命令をひとまとめにして名前をつけて呼び出せるようにしたり(関数やサブルーチンなど)、条件分岐や反復(繰り返し)などで命令の流れの制御を行う。
プログラムの実行
ソースコードそのものはコンピュータ(の処理装置)が解釈・実行できる形式ではないため、これを機械語(マシン語)のプログラムなど実行可能な形式に変換する必要がある。ソースコードを機械語などのコード(オブジェクトコード)に変換する工程をコンパイル(compile)と呼び、プログラムの起動処理やライブラリなど実行に必要なコードを連結する工程をリンク(link)という。これら一連の工程を行って実行可能ファイルやパッケージを作ることをビルド(build)という。
スクリプト言語(軽量言語)などの場合はこうした明示的な変換工程は不要で、ソースコードを機械語に変換しながら同時に実行するインタプリタなどの処理系で直に実行することができる。記述したコードをすぐ実行でき手軽だが、変換しながら実行するため実行可能ファイルを生成する場合より実行速度やメモリ効率では劣る。
プログラムの修正
作成したプログラムが一度で完全に思い描いたとおりに動作する場合もあるが、大抵は何らかの誤りや不具合を抱えているものである。このため、ビルドしたプログラムを実行してみてテスト(動作試験)を行い、仕様通りに動くか調べる。
誤り(バグ)が発見されると原因や解決策を考え、正しく動作するようにプログラムを書き換える(デバッグ)。バグには単純な記述ミスのようなものから、そもそも解くべき問題に対して選択した計算手順(アルゴリズム)が合っていないといった根本的なレベルのものまで様々な種類がある。
デバッグ作業が完了したら再びビルドとテストを行い、誤りが正されていることを確認する。このビルド→テスト→デバッグの繰り返しによって次第にプログラムの完成度や品質が上がっていき、実際に実用可能なプログラムに仕上げることができる。実際のプログラミングにおいては作業時間の多くがこの繰り返しの工程に費やされる。
コーディング規約 【コーディングルール】
ソフトウェア開発者がコンピュータプログラムのソースコードを記述する際に要請される、コードの書き方や形式に関する決まりごと。組織やプロジェクトごとに内部的に定める場合と、言語の開発元が標準を定める場合がある。
プログラミング言語の文法とは異なり、様々な書き方が可能な場合にどういった書き方(スタイル)にするかを集団内の約束として決めたものを指す。変数や関数などの命名規則や、利用してはいけない機能などの禁止事項、インデントやスペース、括弧や演算子などの記号の配置の仕方などで構成される。
企業の開発部門やオープンソースプロジェクトなど集団でプログラミングをする場合、各々ばらばらの流儀でコードを書くと他人の書いたコードを理解したり修正したりすることが難しくなる。コードの表記法をコーディング標準として統一しておくと、可読性や保守性が高まり、開発効率を向上させることができる。
どのような規約を定めるかは言語や開発環境の制約、組織やメンバーの考え方や方針により様々で、一律に良し悪しや優劣を定められるものではなく、集団が異なれば同じ項目でも異なる方針が採用されることもしばしばである。PythonのPEP 8のように言語側で標準のコーディング標準が用意されている場合もある。
具体的な項目としては、実行制御の入れ子(ネスト)構造に従った各行先頭の字下げ(インデント)の仕方(タブかスペースか、一段何文字分とするか等)、コードブロックの開始や終了を示す括弧や制御文の置き方(行末で開始するか、改行して行頭で開始するか等)、コメントの記述形式、変数や演算子などの前後に空白文字を置くか否か、三項演算子など可読性を落としがちな構文の使用を許容するか否か、などがある。
インデント
文章の行頭に空白を挿入して先頭の文字を右に押しやること。また、そのために左端に挿入された空白や、テキストエディタやワープロソフトの持つ字下げ機能のこと。
横書きの日本語は段落の先頭を一文字分字下げすることになっているため、文書作成ソフトなどにはそのための機能が用意されていることが多い。
ソースコードのインデント
プログラミングの分野では、プログラムの構造を見やすくするために制御構文の内側にある行などの先頭に一律に同じ幅の空白を挿入することを字下げという。
どの行が同じブロックに含まれるのか視覚的に分かりやすく表示することができ、プログラムの流れが理解しやすくなる。範囲の取り違えなどに起因するバグなどを減らす効果も期待できる。
あるブロックの中に別のブロックが含まれるという入れ子構造(ネスト)になっている場合、各行の字下げも入れ子の深さに応じて長くなっていく。これにより、プログラムの階層構造をコード中で視覚的に表すことができる。
字下げとして挿入されるのはタブ文字か連続した空白文字(スペース文字)で、タブ文字の場合は字下げの幅は表示する側のソフトウェアの設定により異なる。空白文字で表す場合は2~8文字程度の連続した空白で字下げする。
読む側で好みの幅を調整できるのでタブが好ましいとする人と、書く側で幅を決定して環境によらず同じように表示できるので空白文字が好ましいとする人の間で長年論争があり、また、いずれの場合も一段の字下げ幅を何文字分とするかで好みが分かれる。
ほとんどのプログラミング言語では字下げはソースコードの見た目の問題でありプログラムの意味には影響を及ぼさない(取り除いても同じように動作する)が、Pythonのように字下げによってプログラムの構造を記述する言語もある。
ネスト 【入れ子】
あるものの中に、それと同じ形や種類の(一回り小さい)ものが入っている状態や構造のこと。IT分野では、コンピュータプログラムやデータ構造において、ある構造の内部に同じ構造が含まれている状態のことを指す。
よく知られるのはプログラムの制御構造のネストで、if( 条件A ){ ... if( 条件B ){ ... } ... } といったように、条件分岐やループの内部に、別の条件分岐やループなどが含まれた制御構造を指す。複雑な条件による分岐や多重ループを記述するための基本的なテクニックとして多くのプログラミング言語で利用できる。
for文の中にfor文を記述するなど、同じ構文を入れ子状に繰り返すことを指す場合が多いが、while文の中にif文など、異なる制御構文を内部に記述することも含む場合がある。内側の構文の内部にさらに構文を重ねて、マトリョーシカのように何重も入れ子にすることができ、階層の多さを「ネストの深さ」と表現することがある。
サブルーチンなどのネスト
プログラミング言語の中には、サブルーチンやプロシージャ、関数、クラスなどのコードのまとまりをネストさせ、内部に同種のまとまりを定義することができるものもある。例えば、関数の内部に定義された別の関数を「関数内関数」「ローカル関数」などと呼び、クラスの内部に定義された別のクラスを「クラス内クラス」「インナークラス」「内部クラス」などという。
データ構造のネスト
あるデータ構造の要素として、そのデータ構造自身を埋め込むことができる場合があり、データ構造のネストを形成する。例えば、配列を構成する個々の要素が配列になっている多次元配列は配列のネストである。
配列の配列など、内部が再帰的に同じ構造になっているものを指すことが多いが、連想配列の要素が配列になっているものなど、制御構文の場合と同じように異なる構造が入れ子状になっている場合も含むことがある。
命名規則 【ネーミング規約】
変数名などコンピュータプログラムのソースコード上で開発者が名付ける識別名についての決まりごと。言語仕様や開発環境などによって定められているものと、ソフトウェア開発を行う組織やチームが内部的に定めるものがある。
クラス名やメソッド名、関数名、定数名、変数名など、プログラム上で定義して扱う対象に名前を付ける機会は多くあるが、複数人で開発を行う場合などにそれぞれが異なる考え方や基準で名前を付けると、互いのコードの可読性や視認性が損なわれ、開発効率や保守性の悪化につながる。名前の衝突や使い回しなどでバグが生じることもある。
そこで、名前の付け方に一貫したルールを設け、これに従って識別名を命名するようにするのが命名規則である。よく定義された命名規則に従うと、対象の意味や機能、使い方などが名前からある程度推測できるようになり、コード自体がドキュメントの役割を果たすようになる。検索や置換、ツールによる自動化なども行いやすくなり、デバッグや修正、追加開発の効率も向上する。
どのような規則を定めるかはプログラミング言語や開発環境の制約、組織やメンバーの考え方や方針によって様々であり、必ずしも良し悪しや優劣を論じられるものではなく、規格化された標準などがあるわけでもない。言語やフレームワークによっては仕様上定められている命名規則が存在する場合もある。
よく定められる項目としては、「isClickable()」のように先頭や末尾に付け加える特定の意味を持つ接頭辞や接尾辞(ハンガリアン記法)、大文字と小文字の使い方や組み合わせ方、複数単語の連結の仕方などがある。古くはメモリ容量節約などのため、名前の文字数の制限が定められることもあった。
キャメルケースとスネークケース
英語の複合語や、フレーズ(句)や文を一語に繋げて表記する際、“JavaScript” のように各構成語の先頭を大文字にする方式を「キャメルケース」(camel case)という。大文字部分が上に出っ張っているのをラクダ(camel)のこぶに例えた呼称である。
このうち、“getDate” のように先頭は小文字とする方式を「ローワーキャメルケース」(LCC:Lower Camel Case)、“GetWindow” のように先頭も大文字とする方式を「アッパーキャメルケース」(UCC:Upper Camel Case)あるいは「パスカルケース」(Pascal Case)という。
一方、「file_get_contents」のように単語間のスペース(空白文字)をアンダースコア(_)に置き換える方式を「スネークケース」(snake case)という。大文字がなく、長く一連なりに文字が続く様を地を這う蛇(snake)になぞらている。
ユーザビリティ 【使用性】
機器やソフトウェア、Webサイトなどの使いやすさ、使い勝手のこと。利用者が対象を操作して目的を達するまでの間に、迷ったり、間違えたり、ストレスを感じたりすることなく使用できる度合いを表す概念である。
国際規格のISO 9241-11では、使用性を「特定の利用状況において、特定の利用者によって、ある製品が、指定された目標を達成するために用いられる際の、有効さ、効率、利用者の満足度の度合い」と定義している。漠然とした「使いやすさ」よりは限定された概念で、ある人がある状況下である目的を達することがどれくらい容易であるかを表している。
使用性は利用者への情報やメッセージの提示の仕方やタイミング、言い回し、操作要素や選択肢の提示の仕方、操作の理解のしやすさや結果の想像しやすさ、操作のしやすさや誤りにくさ、誤操作に対する案内や回復過程の丁寧さ、利用者の操作に応じた表示や状況の変化(インタラクション)などの総体で構成される。
高い使用性のために必要な実践は対象の種類(機器・ソフトウェア・Webページ等)や想定される利用者の属性、文脈や利用目的によって異なるため個別性が高く、ある状況では良い事例とされたものが別の文脈では悪い事例になる場合もある。
開発者が期待する使用性が備わっているかどうか確かめるには、利用者(やそれに近い属性の人物)の協力を得て実際に使ってみてもらい、想定通りの操作が行われるか、利用者が不満や戸惑いを感じないかなどをテストするのが有効であるとされる。このような試験を「ユーザーテスト」(user testing)あるいは「ユーザビリティテスト」(usability testing)という。
保守性 【保全性】
機器やソフトウェア、システムなどが備える特性の一つで、所定の条件で修理や交換などの保守作業を実施することで、機能や状態が維持される性質。また、その容易さ。
機器やシステムなどの場合には、一定の水準の機能や性能を保つ上で、日常的にどのくらいの作業が必要になるかといった点や、一部が老朽化したり故障した際に、いかに容易に発見や修理、交換を行えるかといった点が中心となる。
ソフトウェアの場合には、誤りや不具合の発見・修正のしやすさや、事前に予定されていなかった仕様変更や機能追加などの行いやすさ、ソースコードの読みやすさといった点が中心となる。
モジュール分割
コンピュータプログラムを設計する際に、全体を何らかの基準に則って複数の部品に分割すること。この部品は特定の機能や構造を表す適切な大きさのプログラムのまとまりであり、これを組み合わせてプログラム全体を構成していく。
一定の方針に基いてモジュール分割を行うことにより、開発者にとってプログラムの構造が見通しやすくなり、複数人での分担や問題発生時の原因の発見、コードの再利用などが行いやすくなる。古くから様々な技法が提唱されている。
共通機能分割
プログラム全体を複数の部品(モジュール)に分割するための設計指針の一つで、プログラム中の様々な箇所で共通して行われる処理をモジュールとして切り出す方式を共通機能分割という。
プログラム中にはエラー処理のように、様々な処理の中で同じか似たような処理を行う箇所が存在する場合があり、これを共通の機能として分離して一つのモジュールにまとめ、必要な時に呼び出すようにするのが共通機能分割である。まず全体を他の手法でモジュール分割し、複数のモジュールに共通する部分を共通機能分割で取り出すといった利用法が多い。
TR分割 (トランザクション分割)
プログラム全体を複数の部品(モジュール)に分割するための設計指針の一つで、データの種類とその処理内容に応じて分割する方式をTR分割(トランザクション分割)という。
対象となるデータの種類と、そのデータに対する関連する一連の処理をトランザクションという単位にまとめ、プログラムをトランザクション単位で分割していく手法で、データの種類などによって処理の流れが複数に分岐する場合によく用いられる。
STS分割
プログラム全体を複数の部品(モジュール)に分割するための設計指針の一つで、データの入力(Source:源泉)、変換(Transformation)、出力(Sink:吸収)の3つに分割する手法をSTS分割という。
プログラム中でのデータの流れに着目し、プログラムへのデータの入力や取得、読み込みなどを行うモジュールと、データの計算や加工、変換などを行うモジュール、データの出力や表示、印刷、書き出しなどを行うモジュールに分割する。
これらのモジュールを直に繋いで流れ作業的に連続して実行する場合もあるが、これらの上位に制御用のモジュールを配置してデータの流れや実行状態の管理を行う場合もある。
ワーニエ法 (Warnier method)
プログラム全体を複数の部品(モジュール)に分割するための設計指針の一つで、入力データの構造を分析してプログラムの構造を決定していく方式をワーニエ法という。1970年代にフランスの情報科学者ジャン・ドミニク・ワーニエ(Jean-Dominique Warnier)氏によって考案された。
ワーニエ法では、データがいつ、どこで、何回使われるかを分析し、これを元に、順次(連結)、選択、繰り返しの3種類の制御構造を組み合わせて制御の流れを決めていく。これを図示したものをワーニエ図という。
ジャクソン法
プログラム全体を複数の部品(モジュール)に分割するための設計指針の一つで、入出力データの構造からプログラムの構造を決定していく方式をジャクソン法という。マイケル・ジャクソン(Michael A. Jackson)氏が1975年に発表した。
プログラムの入力データと出力データの対応関係を把握し、入力から出力が得られるようプログラムの構造を決定していく。その際、データやそれを扱うモジュールを、基本、連接、選択、反復の4つの要素を組み合わせて表現する。
メインルーチン
あるコンピュータプログラム全体の中で中心となる部分のこと。起動時に最初に実行されるエントリポイントが含まれる。
プログラムはオペレーティングシステム(OS)などによって起動されるが、起動して最初に実行するコードが含まれる部分がメインルーチンとなる。メインルーチンの最後のコードを実行し終えると、プログラムの実行も終了となる(他の箇所で終了することもできる)。
例えば、C言語のプログラムは「main」という関数から実行が開始される仕様になっており、このmain関数がメインルーチンとなる。多くのスクリプト言語ではプログラムの先頭およびそれに続く部分(オブジェクトや関数などの定義に含まれない部分)がメインルーチンとなる。
メインルーチンから呼び出して実行する手続きや関数、メソッドなどのコードのまとまりのことは「サブルーチン」(subroutine)という。サブルーチンの実行が終了すると、メインルーチンの呼び出し箇所に戻り、続きのコードが実行される。
利用者の操作など何らかの指示やきっかけに応じてプログラムが終了する構造にしたい場合には、メインルーチンが終わらないよう終了条件が満たされるまでループし続ける制御構造にすることがある。これを特に「メインループ」(main loop)という。
サブルーチン 【サブルーティン】
コンピュータプログラムの中で特定の機能や処理をひとまとまりの集合として定義し、他の箇所から呼び出して実行できるようにしたもの。単に「ルーチン」とも呼ばれる。
プログラム中の様々な状況や箇所で繰り返し必要となるような処理をサブルーチンとして名前をつけて一つの塊として定義することで、その処理を何度も繰り返し記述・複製する必要がなくなり、コード量の削減や開発効率の向上、記述ミスなどによる誤り(バグ)の減少などが期待できる。
サブルーチン内部の処理に反映させるため、呼び出し側から値を指定できるようになっている場合が多く、この値を「引数」(ひきすう/argument)という。また、処理結果として呼び出し元に値を返すことができる場合があり、この値は「返り値」あるいは「戻り値」という。返り値を持つサブルーチンは「関数」(function)と呼ぶのが一般的である。
かつてはプログラムが起動したとき最初に実行される主系統のコード集合を「メインルーチン」(main routine)、そこから呼び出される形で実行される副系統のコード群をサブルーチンと呼んで区別していたが、現在ではそのような構造に当てはまらない例も増えており、サブルーチンのことを単にルーチンと呼ぶことも多い。
サブルーチンに相当するコード集合は、プログラミング言語によっては「プロシージャ」(procedure)のように異なる名称で呼ばれることもある。オブジェクト指向プログラミングでは一般的に「メソッド」(method)という。返り値を持つか否かで名称が異なる言語(Pascalのプロシージャと関数など)や、C言語のようにすべてを関数と呼ぶ場合もある。
データ型
プログラミング言語などが扱うデータをいくつかの種類に分類し、それぞれについて名称や特性、範囲、扱い方、表記法、メモリ上での記録方式などの規約を定めたもの。
あるデータがどのような性質のもので、どのように取り扱うべきかを定めたもので、典型的なものには整数型や文字列型などがある。それぞれの変数や値のデータ型に応じて、それを適切に扱うためのプログラムコードが生成・適用される。
例えば、整数型の値について「1+1」という処理を実行すると、数値計算のコードが適用されて「2」という結果が得られるが、文字列型の値について「"1"+"1"」という処理を実施すると、文字列の連結処理が適用されて「"11"」という結果が得られる。
整数を文字列で除算しようとするなど、型が不整合な処理はエラーとなる。"1"という文字列型の値を1という整数型の値に変換するなど、異なる型へ一定のルールに基づいて変換することを「型変換」あるいは「型キャスト」(type casting)という。
プリミティブ型と複合型
様々なデータ型のうち、それ以上要素に分解できない最小単位のデータを格納する最も基本的なデータ型を「単純データ型」「プリミティブデータ型」などという。
言語によって用意されている単純型の種類は異なるが、文字型や文字列型、整数型、浮動小数点数型(あるいは固定小数点数型や実数型)、論理型(ブーリアン型)、日付・時刻型、バイナリ型などが用意されていることが多い。
ポインタ型や参照型などメモリ上の位置を格納する型や、関数型などプログラムをデータのように扱う型、データが「無い」ことを明示するvoid型など、特殊な型が用意されている言語もある。
浮動小数点数型に単精度や倍精度など異なる精度の型が用意されていたり、整数型がバイト長や符号の有無(負数を表現できるか否か)でいくつかの種類に分かれているなど、データの種類が同じでも仕様が異なる複数の型に分かれている場合もある。
一方、複数のデータ型を組み合わて定義された型や、複数の要素からなるデータ構造を格納するためのデータ型を「複合データ型」(complex type)という。配列や連想配列(ハッシュ、マップ、辞書)、リスト、タプル、集合型(セット)、列挙型などがこれに当たる。
組み込み型とユーザー定義型
言語仕様や標準ライブラリなどにあらかじめ用意されているデータ型を「組み込みデータ型」(ビルトインデータ型)、開発者が独自に定義したものを「ユーザー定義データ型」(user-defined type)という。
組み込み型は言語処理系が標準的に扱うことができ、演算子による演算を行ったり、基本的な操作や処理を行うための関数やメソッドが標準で提供されることが多い。
ユーザー定義型は単に既存の組み込みデータ型に別名を与えられるだけの場合もあるが、様々なデータ型を組み合わせた複合データ型を独自に定義できる機能を指すことが多い。演算子の処理内容を独自に定義(上書き)して、ユーザー定義型の値に対しても演算子を適用できる言語もある。
型宣言と型付け
プログラムの開発者がそれぞれの変数などのデータ型をプログラム上に明示することを「型宣言」(type statement)という。コード中で使用する変数などについて必ず事前に型宣言しなければならない言語と、型宣言しなくても変数などを使ってよい言語がある。
プログラムの実行前、ソースコードの記述やコンパイルの時点で型が決定されることを「静的型付け」(static typing)、実行時に実際の値に基づいて型が決定されることを「動的型付け」(dynamic typing)という。
型宣言が不要な言語の多くは動的型付けを採用しているが、「型推論」(type inference)機能により内部的に静的型付けを自動的に行う仕組みの言語もある。
変数
コンピュータプログラムのソースコードなどで、データを一時的に記憶しておくための領域に固有の名前を付けたもの。プログラム上で値を代入したり参照することができる。
変数につけた名前を「変数名」と呼び、記憶されているデータをその変数の値という。データの入れ物のような存在で、プログラム中で複数のデータを扱いたいときや、同じデータを何度も参照したり計算によって変化させたい場合に利用する。
変数をプログラム中で利用するには、これからどんな変数を利用するかを宣言(declaration)し、値を代入(assignment)する必要がある。コード中で明示的に宣言しなくても変数を利用できる言語もある。変数に格納された値を利用したいときは、変数名を記述することにより値を参照(reference)することができる。
変数の型
プログラム中で扱うデータは整数、浮動小数点数、文字列など様々なデータ型に分かれており、変数も特定のデータ型を持つ。多くの言語では宣言時に一つのデータ型を指定しなければならず、後から型は変えられないが、特定の型を指定しなくても処理系が適切な型を適用(型推論)してくれる言語や、代入などによって途中で型を切り替えることができる言語もある。
変数のスコープ
変数は宣言した位置などにより通用する範囲(スコープ)が決まっており、範囲の外から参照や代入を行うことはできない。プログラム全体を通用範囲とするものを「グローバル変数」(大域変数)、特定のサブルーチンや関数、メソッド、コードブロックなどの中でのみ通用するものを「ローカル変数」(局所変数)という。オブジェクト指向言語では「クラス変数」や「インスタンス変数」などに分かれる。
整数型 【int型】
プログラミング言語などで用いられるデータ型の一つで、整数の値を格納できるもの。多くの言語に実装されている最も基本的なデータ型で、ビット長や符号の有無などにより複数の種類に分かれている場合もある。
どのくらいの長さのデータで一つの整数を表現するかによって表現できる値の範囲が異なる。例えば16ビット(2バイト)符号なし整数型であれば、0から65,535(216-1)までの間に含まれる整数値を表現できる。
多くの言語では、“int” や “Integer” などの型名で示される整数型が16ビットあるいは32ビットを表し、8ビットや16ビットは “short” などの型名や修飾子で、32ビットや64ビットは “long” などで表されることが多い。言語によっては8ビットの任意のビット列を格納する “char” や “byte” などの型が用意されており、8ビット長の整数型としても利用できる。
C言語の場合は処理系によってshort、int、longの長さが異なるが、規格上はint16_tのようにビット長を明示した型名も用意されている。同じように “Int64” といった長さが明記されたデータ型を用いる言語もある。
符号付きと符号なし
扱う値の範囲の違いにより、0と正の整数のみを格納できる符号なし整数型(unsigned integer)と、負の整数も格納できる符号付き整数型(signed integer)が選択できる場合がある。
符号付き整数は最上位ビットが正負の符号を表しており、表現できる値の幅は符号なしと同じだが、絶対値の上限は半分となる。例えば、16ビット符号なし整数の範囲は 0~65,535 だが、16ビット符号付き整数の範囲は -32,768~32,767 となる。
実数型 【real型】
コンピュータで数値を扱うためのデータ型の一つで、実数を格納できるもの。数学における実数すべてを表現できるわけではなく、小数点以下の数を扱うことができる数値データ型という意味である。プログラミン言語などでは「real」「Real」「REAL」などの型名で示されることが多い。
コンピュータプログラムやデータベースでは、数値や文字列など様々な種類のデータについて、それぞれの表現形式や表現可能な範囲などを規定した「データ型」に則って取り扱う。実数型は数値データ型の一種で、小数点以下の数を含む数値を格納、計算することができる型である。
コンピュータでは一つのデータを表現するために確保するメモリ領域には限りがあるため、実数型といっても数学で扱うありとあらゆる実数を表現可能なわけではなく、最大値や最小値、最長の桁数などに制約がある。上限などはプログラミング言語やデータベース管理システムなどの仕様で規定されている。
実数型のうち、小数点を置く位置(小数点前後の数字の桁数)を固定したものを「固定小数点数型」(fixed-point number type)、小数点の位置が可変で値ごとに指定するようにしたものを「浮動小数点数型」(floating-point number type)という。他にも、整数で分母と分子の値を保持する有理数型などが用いられることがある。
ブーリアン型 【論理型】
プログラミング言語などに用意されているデータ型の一つで、「真」(true)と「偽」(false)の二種類の値だけを取りうるもの。
論理型の値は条件式や論理演算(ブール演算)の結果を表すことができ、また、論理型の変数や定数、リテラルをこれらの計算の項として式に含めることもできる。論理型の変数が利用できることで、例えば複雑な比較の結果をいったん変数に格納し、別の場所で繰り返し参照して処理を行う(その都度同じ比較処理を記述しなくてよい)といったことができるようになる。
論理型の値に対しては、「かつ」を表す論理和(言語によりAND、&、&&などと表される)、「または」を表す論理積(OR、|、||など)、「ではない」を表す論理否定(NOT、!、~など)、「等しい」を表す同値(=、==など)、「異なる」を表す非同値(!=、<>など)などの演算を適用できる。
リテラルの表記は言語によって異なるが、真は「true」「True」「TRUE」などと、偽は「false」「False」「FALSE」などと表記することが多い。論理型に相当する値を整数で代用し、0が偽、0以外が真とする言語や処理系もある。
文字型
C言語などに用意されている基本的なデータ型の一つで、一文字分の文字コードを格納するためのもの。
C言語で「char型」として知られる型で、古い言語仕様や処理系ではASCII文字コードを格納するための1バイト固定長となっている場合もあるが、現代ではUnicodeなどで多バイト文字を表現することを考慮して、2バイトや4バイト、あるいは1~4バイトの不定長として設計されていることもある。
C/C++言語のように実態が整数型で数値としての処理・演算もできる場合と、文字としてしか扱えない場合がある。文字型が用意されている言語では文字列は文字型の配列などとして表され、データ型としての文字列型は用意されていないことが多い(逆に、文字列型がある言語に文字型はない)。
一方、データベース管理システム(DBMS)の場合には、「CHAR型」という名称が固定長の文字列型を表すことが多い。SQL文などで「CHAR(10)」のように表記され、この例では10文字の固定長文字列を表す。
文字列型 【String型】
多くのプログラミング言語やデータベース管理システム(DBMS)に用意されている基本データ型の一つで、複数の文字の並びを一つの値として格納するもの。
文字を表す文字コードを連ねた文字列データを格納する型で、予め格納できる文字列の長さを指定する固定長文字列型(fixed length string)と、任意の長さの文字列を格納できる可変長文字列型(variable length string)がある。言語や処理系によっては一方しか無い場合もある。
古い言語や処理系ではASCII文字(いわゆる半角英数字・記号)しか格納できない仕様のものもあるが、近年ではUnicodeなどで表現さrた多バイト文字(漢字など)をそのまま格納できるようになっているものが多い。
一文字分の文字コードを格納するためのデータ型として文字型(character type)が用意されているC言語/C++言語などでは、組み込みデータ型としての文字列型が無く、文字型のデータの配列などの形で文字列を格納する。
抽象データ型 【ADT】
プログラミング言語で扱うデータ型の一種で、基本的なデータ型の変数を組み合わせたデータ構造と、そのデータ構造に対する操作(手続き)を一つのまとまりとして定義したもの。
様々な型の変数からなる集合体の構造を定義し、それらのデータに対して行うことができる演算や処理の手順を関数などの形で定義する。抽象データ型の変数を宣言すると、定義された構造に応じたデータの格納場所が用意され、格納したデータに対して定義された関数による操作を行うことができる。
例えば、プログラム中でスタック(stack)を扱う場合、スタック型の抽象データ型を定義して、配列などを利用してデータの格納場所を用意し、データの追加(push)や取り出し(pop)などの操作方法を定義する。スタックを利用したいときはスタック型の変数を宣言し、手続きを呼び出すだけでよく、実装の詳細は抽象データ型の定義の中に隠蔽され、利用者が気にする必要はない。
構造体 【構造型】
C言語などのプログラミング言語が持つデータ型の一つで、複数の異なるデータ型の変数を一つにまとめたもの。言語によっては似た機能が「ユーザー定義型」「レコード型」などの名称で提供されている場合もある。
構造型の定義は新たなデータ型を定義するようなもので、開発者は構造型の名前を決め、含まれる変数や配列などを列挙する。構造型に含まれる要素を「メンバ変数」(member variant)あるいは単にメンバと呼び、それぞれ固有の名前が与えられる。構造型の要素として定義済みの別の構造型を指定して入れ子にすることもできる。
構造型が定義できたら、変数を宣言するようにその構造体の実体を宣言することで実際にプログラム中で構造型を扱うことができるようになる。変数のように代入(全要素が代入される)したり、関数の引数や戻り値として使用することができる。
オブジェクト指向言語のクラスに似た概念で、メソッドを持たず継承できないクラスのようなものと考えることもできる。C言語の場合は構造型の定義や宣言を行うためにstruct文が用意されている。
代入
数学で文字を値や式で置き換えること。IT分野では、コンピュータプログラム上で変数に値を設定することを代入という。
例えば、プログラム上で整数型の変数xを宣言し、これに1を代入すると、以降のコードではxの値は1として扱われる。別の値を再代入すれば、以降xはその値となる。他の変数に格納された値を代入することもできる。
プログラミング言語にはデータ型(data type)の区別があり、整数の 1 と文字列の "1" は内部的に別の表現形式で表され、適用可能な操作も異なる。変数の型が固定される言語では異なる型の値を再代入することはできないが、スクリプト言語などでは代入によって値と型の両方を同時に変更できる場合もある。
代入を表す書式は言語によって異なるが、C言語やその記法を受け継ぐ多くの言語(JavaやJavaScriptなど)では「x=1;」のように等号(イコール記号)が代入を表す。条件式などで「もし等しければ」という比較を表す場合は、if(x==1) のように等号を2つ並べて「==」と記す。
この記法では、「xの現在の値に1を加算する」は「x=x+1;」のようになり、数学の等号とは意味が異なるため、初学者を混乱させるとして批判されることもある。このため、「=」を数式と意味が似ている比較に用い、代入は「:=」など別の記法にしている言語もある。
言語によっては、演算と代入を組み合わせ、変数の現在の値に指定の演算を行う「復号代入演算子」が用意されていることがある。例えば、加算「+」と代入「=」を組み合わせた加算代入演算子「+=」は、左辺の変数に右辺の値を加算する操作を表す。「x=x+1;」は「x+=1;」と書くことができる。
なお、英語では数学の代入は「代用」「置き換え」などを意味する “substitution” である一方、プログラミングの代入は「割り当て」を意味する “assignment” であり、異なる語、概念となっている。変数の substitution という場合は、変数名が記述された箇所を実際の値で置き換える操作などを表す。
算術演算子
プログラミング言語などで用いられる演算子のうち、四則演算(加減乗除)などの算術的な計算を行うもの。和を表す「+」、差を表す「-」などのこと。
ほとんどの言語では加減算は算術・数学と同じ「+」「-」を用いる。半角文字(ASCII文字)には乗算記号「×」と除算記号「÷」が用意されていないため、それぞれ「*」(アスタリスク)、「/」(スラッシュ)で代用することが多い。
一般の算術にはない記号として、剰余(割り算の余り)を求める演算子(C言語系の「%」など)や、累乗を求める演算子(BASIC系の「^」、PythonやJavaScriptの「**」など)が用意されている言語もある。
整数型の変数の値に1を加算するインクリメント演算子(C言語系の「++」など)や、同じく1を減算するデクリメント演算子(同「--」など)を算術演算に分類する場合もある。
比較演算子 【関係演算子】
プログラミング言語などで用いられる演算子のうち、二つの式や値の比較を行い、結果を真偽値(trueまたはfalse)で返すもの。一致・不一致や大小の比較などいくつかの種類がある。
用意されている比較の種類や記法は言語によって様々だが、数の一致や大小は数学の表記に倣って「=」(等しい)「>」(より大きい)「<」(より小さい)の組み合わせで記述する場合が多い。
その際、「~以上」(≧)は「>=」または「=>」、「~以下」(≦)は「<=」または「=<」とする。不一致(≠)は「!=」や「<>」などで表されることが多い。
「=」は代入の意味で用いられることもあるため、混同や誤用しないよう一致の比較演算を「==」などとする言語も多い。一致・不一致の演算子は数だけでなく文字や文字列、真偽値など様々なデータ型に用いられる。
異なるデータ型の比較
「1==“1”」のようなデータ型の異なる値同士の比較を許容する(自動的に一方の型に変換して比較する)言語と、これを禁じてエラーとして処理する言語がある。前者の場合、例えば「==」を実質的な内容の一致、「===」を内容とデータ型両方の一致(厳密等価演算子あるいは同値演算子と呼ばれる)として使い分ける言語もある。
複合的なデータ構造の比較
オブジェクト指向言語におけるインスタンスや、配列などの複合的なデータ構造などを比較できる言語もある。
その際、一致・不一致は「両方ともメモリ上の同一の実体を指し示している」(参照が一致している)ことを意味する場合と、「含まれるデータの型や値がすべて同じである」(内容が一致している)ことを意味する場合がある。どちらか一方の比較のみ可能な場合と、それぞれを異なる記法で書き分けるようになっている場合がある。
論理演算 【ブーリアン演算】
真(true)と偽(false)の二通りの状態を取る真偽値(真理値/ブール値)の間で行われる演算。コンピュータでは真を1に、偽を0に対応付けたビット演算として行われることが多い。
入力が一つの単項演算として、入力値の反対の値を出力する「否定」(NOT A:Aではない)がある。入力が二つの二項演算には、どちらかが真なら真を出力する「論理和」(A OR B:AまたはB)、両者とも真の時のみ真を出力する「論理積」(A AND B:AかつB)、両者が異なる時に真を出力する「排他的論理和」(XOR:eXclusive OR)がある。
電子回路などでは、論理和と否定を組み合わせた「否定論理和」(NOR:Not OR)、論理積と否定を組み合わせた「否定論理積」(NAND:Not AND)が用いられることもある。排他的論理和と否定を組み合わせた「否定排他的論理和」(XNOR)は値が同じとき真、異なるとき偽となるため「同値」(EQ:equal)とも呼ばれる。
<$Fig:logic|center|false>三項以上を計算する際は二項ずつの計算を繰り返すことで結果が得られる。その際、四則演算のように交換法則や分配法則、結合法則、ド・モルガンの法則などが成り立つ。すべての論理演算はNOT、AND、ORの三つの組み合わせで構成できるが、この三つはすべてNANDの組み合わせで構成でき、NANDだけですべての論理演算を記述できることが知られている。
コンピュータでは真偽値自体の演算(プログラミング言語におけるブール型の値の演算など)の他に、真を1、偽を0に置き換えてビット間で論理演算を行うことがある。ビット列について論理演算を行う場合は二つのビット列のぞれぞれ対応する位置にあるビット同士で論理演算を行う。
このような演算方式を真偽値の論理演算と区別して「ビット演算」(bitwise operation)と呼ぶこともある。なお、ビット演算には論理演算に相当する演算以外にも、シフト演算やローテート演算などビット列を左右に移動する操作もある。
プログラミング言語では算術演算などと並んで最も基本的な演算の一つとして論理演算が用意されていることが多く、論理演算子によって式を記述する。演算子は「&&」のような記号を用いる場合と、「and」のような英単語をそのまま用いる場合がある。C言語の「&」と「&&」のように、論理演算と対応するビット演算にはそれぞれ別の演算子が与えられていることが多い。
ビット演算
主にコンピュータ上で行われる演算の一つで、対象データをビット列(2進数の0と1の羅列)とみなして、ビットの移動やビット単位の論理演算などを行うもの。
コンピュータはすべての情報を内部的にはビット列として表しており、CPU(MPU/マイクロプロセッサ)にはビット演算用の命令が豊富に用意されている。機械語(マシン語)のプログラムでは様々な処理に用いられる演算であり、高水準言語のプログラムに直接記述されていなくても実際の処理では内部的に多用されている。
ビット単位の論理演算
ビット演算は大きく分けて二種類あり、その一つはビット単位の論理演算である。NOT演算はビット列の論理否定で、各ビットの「0」を「1」に、「1」を「0」に反転させる。「NOT 0101」の結果は「1010」となる。
AND演算は二つのビット列の同じ位置同士のビットで論理積(両方1の場合のみ1となる)を求める演算で、「0011 AND 0101」の結果は「0001」となる。OR演算は同様にビットごとの論理和(いずれかが1の場合に1となる)を求める演算で、「0011 OR 0101」の結果は「0111」となる。XOR演算はビットごとの排他的論理和(片方のみが1の場合に1となる)を求める演算で、「0011 XOR 0101」の結果は「0110」となる。
ビットシフト
もう一つのビット演算はビットの位置を入れ替える操作であり、一方向に単純に移動するシフト演算と、ビット列の先頭と末尾を繋いで循環させるローテート演算(循環シフト/環状シフト/ビット回転)に分かれる。
シフト演算はビット列の各桁を右(下位ビット方向)または左(上位ビット方向)に指定した数だけずらす操作で、「0010」を右に1ビットシフトすると「0001」に、左に1ビットシフトすると「0100」となる。
全ビットを一律に移動する動作を「論理シフト」(logical shift)、右シフトの際に最上位ビットを動かさずに保存する動作を「算術シフト」(arithmetic shift)という。算術シフトは最上位ビットを符号ビットとする符号付き整数を処理するのに適している。
端に追いやられたビットは消滅するが、CPU内部ではキャリーフラグと呼ばれる記憶領域に捨てられたビットの値がセットされ、後続の命令で参照できるようになっていることが多い。反対側から新たに出現するビットは原則として「0」にセットされるが、算術右シフトでは符号ビットのコピーが補充される。
ローテート
ローテート演算は、ビット列の最上位ビットの左隣を最下位ビット、最下位の右隣を最上位とみなして円環状にシフトする操作で、右端に追いやられたビットは左端に、左端に追いやられたビットは右端に出現する。例えば、「1001」を右に1ビットローテートすると「1100」に、左に1ビットローテートすると「0011」となる。
最上位ビットと最下位ビットの間にキャリーフラグが挟まっているとみなし、左端あるいは右端からキャリーにセットされた内容が出現する特殊なローテート演算が用意されている場合もあり、「キャリー付きローテート」と呼ばれる。
ビット演算子
プログラミング言語にはビット演算用の演算子が用意されている場合がある。言語によって仕様は異なるが、C言語の演算子の体系を引き継いでいる言語(C++言語やJava、JavaScriptなど)では多くが共通している。
これらの言語では、NOT演算は「~x」、OR演算は「x|y」、AND演算は「x&y」、XOR演算は「x^y」、左シフトは「x<<y」(xが対象ビット列、yが移動量)、右シフトは「x>>y」のように表記する。ローテートのための演算子は用意されていない。
制御構造 【制御フロー】
コンピュータプログラムで、命令が実行される流れを定めたもの。また、プログラミング言語の仕様や構文のうち、命令の流れを定義することができるもの。
命令の出現順、記述順の通りに順番に命令を実行する「順次構造」(sequence)、条件によって実行する命令の流れがいくつかに分岐する「選択構造」(selection)あるいは「分岐構造」、同じ命令の流れを繰り返し実行する「反復構造」(iteration)あるいは「繰り返し構造」(repetition)の3つを基本とする考え方が多い。
また、方法論や言語の違いにより、これらに加えて、プログラム中の任意の別の箇所に実行の流れを移す「無条件分岐」(ジャンプ命令、goto文)や、別の命令群に流れを移し、終わると元の場所に流れを戻す「サブルーチン」(呼び出し、コール)、プログラム終端以外の箇所で実行を終わらせる「停止」(終了)などを加える場合もある。
プログラミング言語における制御構造
機械語やアセンブリ言語(ニーモニック)のようなCPUの構造に忠実な低水準言語では、命令実行の流れを制御する命令として無条件ジャンプ命令と条件ジャンプ命令しか用意されていないことが多く、他の制御構造はこれらと他の命令を組み合わせて実装する。
人間に分かりやすく抽象的なプログラム構造を記述できる高水準言語では、選択や反復を記述するための制御文が用意されていることが多い。言語によって名称や仕様は異なるが、選択構造は「if文」(二分岐)や「switch文」(多分岐)などで、反復構造は「for文」「while文」「do-while文」などで記述することができる。
選択構造 【分岐構造】
コンピュータプログラムの命令実行の流れの一つで、実行時に評価する条件によって、次の命令を実行するか、指定されたメモリ上の位置に移行するか分岐するもの。
コンピュータのCPUがプログラムを実行する際、特に指定がなければ命令を先頭から順に実行するが、分岐命令が存在する場合、特定の条件が満たされたらメモリの指定番地に実行位置を変更(ジャンプ)し、以降はそこから順に命令を実行していく。
このような実行制御を「条件分岐」と呼び、プログラムに複雑な処理をさせたい場合は必須の機能となる。一方、条件が満たされる間だけ同じ個所を繰り返し実行する制御構造もあり、「反復構造」あるいは「繰り返し構造」という。
反復構造 【繰り返し構造】
コンピュータプログラムの命令実行の流れの一つで、指定の条件が満たされている間、特定の個所を何度も繰り返し実行するもの。
コンピュータのCPUがプログラムを実行する際、特に指定がなければ命令を先頭から順に実行するが、繰返し処理になっている場合、指定の条件が満たされている間、指定範囲の末尾の命令を実行したら範囲の先頭に戻り、その範囲を繰り返し実行する。
同じ処理を様々な対象に次々に適用したい場合などに用いられ、プログラムに複雑な処理をさせたい場合には必須の機能となる。一方、特定の条件が満たされたらメモリの指定番地に実行位置を変更(ジャンプ)する制御構造もあり、「選択構造」あるいは「分岐構造」という。
プロシージャ
「手続き」という意味の英単語で、コンピュータプログラム内で複数の命令や処理などを一つにまとめ、外部から呼び出し可能にしたものをこのように呼ぶことがある。
全体として何らかの特定の処理や機能を実現するために作成されるもので、繰り返し必要になるコードをまとめておくことで何度も似たようなコードを記述しなくて済むようになり、プログラムの保守性や再利用性も高まる。
このようなコードのかたまりを作成する仕組みを何と呼ぶかはプログラミング言語によって異なり、ルーチン(routine)、関数(function/ファンクション)、メソッド(method)なども似たような仕組みを指す(言語により意味や仕様はそれぞれ異なる)。PascalやVisual Basicのように呼び出し元に値を返さないものをプロシージャ、返すものを関数と呼んで区別する場合もある。
関数 【ファンクション】
コンピュータプログラム上で定義されるサブルーチンの一種で、数学の関数のように与えられた値(引数)を元に何らかの計算や処理を行い、結果を呼び出し元に返すもののこと。
プログラム上で関連する一連の命令群を一つのかたまりとしてまとめ、外部から呼び出せるようにしたサブルーチンやプロシージャ(手続き)の一種である。呼び出し時に引数(ひきすう/argument)と呼ばれる値を指定することができ、この値をもとに内部で処理を行って、結果を返り値(かえりち/return value)あるいは戻り値(もどりち)として呼び出し元に通知する。
プログラミング言語によって、返り値を持つものを関数(ファンクション)、処理を行うだけのものをサブルーチンやプロシージャとして区別する場合もある(Pascalなど)が、C言語やJavaScriptのようにすべてが関数で引数や返り値が省略可能になっている言語もある。
多くのプログラミング言語は開発者が自由に関数を定義してプログラム中で呼び出せる構文や記法を定めているほか、算術関数や文字列処理などよく使われる基本的な関数言語仕様や標準ライブラリなどの中であらかじめ実装済みとなっている(組み込み関数)。
関数といっても数学のように計算を行うものには限られず、「利用者に入力を促して入力値を返す」関数といったものもあり得る。途中で画面に何かを表示するなど、引数や返り値と直接関係ない処理を行ってもよい。
プログラムは内部に変数の値など実行状態を持つため、これを反映して同じ引数から異なる返り値が得られる場合もある。また、関数が行う処理によって状態が変化することもあり、これを関数の持つ「副作用」という。多くの算術関数のように副作用のない関数もある。
引数
プログラム中で関数やメソッド、サブルーチンなどを呼び出すときに渡す値のこと。渡された側はその値に従って処理を行い、結果を返す。オペレーティングシステム(OS)の操作などで利用者がコマンドを実行する際に指定するパラメータ(コマンドライン引数)などを指すこともある。
仮引数と実引数
関数などを定義する際に外部から受け取った値を表す変数などを「仮引数」(formal argument)、関数を呼び出す側が実際に指定した値を「実引数」(actual argument)という。
例えば、2つの数を受け取って和を返す関数 function sum(a, b){ return a + b; } があるとき、aやbを仮引数という。一方、この関数を呼び出すコード s=sum(1,2); における1や2が実引数となる。1はaに、2はbに代入されて関数内の処理が実行される。
値渡しと参照渡し
プログラミング言語の引数には「値渡し」(call by value)と「参照渡し」(call by reference)があり、どちらもサポートしている言語と片方のみサポートしている言語がある。
値渡しは変数の内容をコピーして渡す方法で、渡された関数などが変数の内容を変更しても、元の変数には影響がない。参照渡しは変数の所在を表す情報を渡す方法で、渡した側と渡された側が同じ変数を共有するため、呼び出された側で変更を加えると呼び出し側にも変更が反映される。
戻り値 【返り値】
プログラム中で呼び出された関数やメソッド、サブルーチンなどが処理を終了する際に、呼び出し元に対して渡す値。計算結果の報告などのために用いられる。
関数などが処理を行った結果として呼び出し元に報告される値のこと。反対に、呼び出し元から関数などに対してパラメータとして渡す値のことは「引数」(ひきすう、argument)という。
戻り値は計算結果の数値や処理結果のデータなどが代表的だが、処理が正しく終了したかどうかを表す真偽値やコード番号、メッセージなどを返す場合もある。多くの言語では「return x+y;」(変数xとyの和を返却する)のようにreturn文(リターン文)と呼ばれる記法で返す値を指定する。
ほとんどのプログラミング言語では戻り値は一つしか返すことができないが、変数への参照やメモリアドレス(ポインタ)を返したり、配列などの複合的なデータ構造、データ型に値を格納して返すことで、複数のデータの集合を返すことができるようになっていることが多い。C言語のvoid型関数のように、明示的に何も返さないよう指定できる言語もある。
関数などを定義する際に戻り値のデータ型もあらかじめ宣言するようになっていることが多く、呼び出し側で受け取る変数の型も揃える必要がある。言語によっては、同じ名前だが引数と戻り値のデータ型が異なる複数の関数やメソッドなどを同時に定義し、引数の型によって自動的に使い分ける機能(オーバーロード)が利用できる場合もある。
ローカル変数 【局所変数】
コンピュータプログラム中のあるコードブロック(関数やメソッドなど)の内部で宣言され、その範囲内でのみ有効な変数。
プログラミング言語の多くは、サブルーチンや関数、メソッドなどの形で複数のコードを束ねたまとまり(ブロック)を作ることができるが、そのようなブロックの内部でのみ通用する変数のことを局所変数という。
通常、あるブロック内で変数を宣言すると、自動的にそのブロックを有効範囲(スコープ)とする局所変数となり、ブロック内のコードからのみ参照や変更ができるようになる。関数内で別の関数を定義するといった入れ子構造の記述が可能な場合、内側のブロックから外側のブロックの局所変数にアクセスできるかどうかはブロックの種類や言語仕様により異なる。
一般的に局所変数の寿命はブロックの開始(あるいは変数宣言)から終了までで、関数などの実行が終了して呼び出し元に制御が移ると関数内の局所変数の内容は破棄されるが、言語によっては内容を維持するよう指定する事ができる場合もある(静的ローカル変数)。
どのような種類のブロックで局所変数を使用できるかは言語によって異なるが、関数やメソッドなどをスコープとする局所変数はほとんどの言語に存在する。繰り返しや条件分岐などの制御文で指定される範囲をスコープとする局所変数を宣言できる言語も存在する。
一方、同じプログラムのどこからでも参照や書換が可能な変数を宣言できる言語もあり、そのような変数をグローバル変数(global variable)という。
オブジェクト指向プログラミング 【OOP】
コンピュータプログラムの構造、構成法の一つで、関連するデータの集合体と、それを操作する手続きを「オブジェクト」(object)と呼ばれるひとまとまりの単位として一体化し、オブジェクトの組み合わせとしてプログラムを記述する手法。
オブジェクト指向プログラミングではオブジェクトの定義と、オブジェクト間の関係、相互作用を記述することによりプログラムを構築していく。オブジェクトにはそれぞれ固有のデータ(属性/プロパティ)と手続き(メソッド)があり、外部からのメッセージを受けてメソッドを実行し、データを操作する。オブジェクトに付随するデータの操作は原則としてすべてオブジェクト中のメソッドによって行われる。
オブジェクトは外部に公開されたメソッドにより機能を提供する。内部の状態を表す変数なども、外部からの参照・操作が必要なものだけが専用の手続きによってアクセス可能となり、それ以外は外から見えない存在となる。
このように、関連するデータと手続きを一つの単位にまとめることを「カプセル化」(encapsulation)、外部に対して必要な情報や手続きのみを提供することを「情報隠蔽」(information hiding)という。外から直に参照や操作をする必要のない内部の状態や構造は秘匿される。
主流のクラスベースのオブジェクト指向プログラミングでは、オブジェクトの雛形を「クラス」(class)として記述し、これをプログラムの実行時に「インスタンス」(instance)として実体化し、データの保存や操作を行う。
あるクラスを元に一部の振る舞いを改変したり新しい機能を追加した別のクラスを作成する「継承」(inheritance)を活用することで、ライブラリや既存のプログラムから必要な機能を流用し、足りない部分だけ新たに記述するといったスタイルで開発を進めることができる。
派生したクラスでは既存のメソッドの振る舞いを必要に応じて改変することができ、外部から同じメソッドを呼び出した際に各オブジェクトがそれぞれ自らに適したコードを実行してくれる。このような性質を「ポリモーフィズム」(polymorphism/多態性)という。
オブジェクト指向によるソフトウェア開発は、異なるプログラムを組み合わせたり、後で部分的に再利用したりするのが容易になるという特徴があり、現代では多くのプログラミング言語にオブジェクト指向的な記述を可能にする仕様が取り入れられている。オブジェクト指向を主要な言語仕様としているものは特に「オブジェクト指向プログラミング言語」(オブジェクト指向言語)と呼ばれることもある。
クラス
級、階級、等級、格、類、分類、種類、学級、科目、授業などの意味を持つ英単語。ITの分野では、オブジェクト指向プログラミングにおけるオブジェクトの雛形や、何らかの階級や分類を表す名称の一部としてよく用いられる。一般の外来語としては学校などの学級の意味でよく使われるほか、商品やサービスの等級や格を表すこともある。
オブジェクト指向プログラミングのクラス
オブジェクト指向では、互いに関連するデータと、データに対する操作(メソッド)を一つの「オブジェクト」(object)と呼ばれる単位に一体化(カプセル化)して取り扱う。あるオブジェクトがどのようなデータとメソッドから作られるのかを定義した雛形をクラスという。
プログラムの実行時にはクラスを元にメモリ空間上に具体的なオブジェクトが生成される。この実体化されたオブジェクトのことを「インスタンス」(instance)という。同じクラスから複数のインスタンスを生成することができ、それぞれ異なる内部状態を持つことができる。
クラスには、オブジェクト内部で取り扱うデータ(フィールド/メンバ変数)の名称やデータ型、アクセス可能な範囲(クラス外から参照・操作可能か否かなど)を宣言する。同様にメソッド(メンバ関数)の名称や引数、処理内容の詳細、アクセス範囲も記述する。
データや手続きは通常はインスタンスに属するが、クラスそのものに属するものを宣言することができる。クラス自体に属するデータを「クラス変数」(静的フィールド/静的メンバ変数)、クラス自体に属する手続きを「クラスメソッド」(静的メソッド)という。
クラスの継承
クラスベースのプログラミング言語では、あるクラスを元に一部を改変して別のクラスを定義することができ、これをクラスの「継承」(inheritance)という。このとき、元になったクラスを「親クラス」(parent class)「スーパークラス」(superclass)「基底クラス」(base class)などと呼び、新たに定義されたクラスは「子クラス」(child class)「サブクラス」(subclass)「派生クラス」(derived class)などという。
抽象的・汎用的なクラスを元に具体的な機能を付け足したクラスを派生させていくことで、大規模なソフトウェアを効率的に開発することができる。言語によっては親クラスのメソッドを子クラスが同じ名前で別の内容に差し替えることができる。このように、同じ名前がクラスによって異なる内容を指すことを「ポリモーフィズム」(polymorphism:多態性)という。
メソッド
方法、方式、手法、やり方、などの意味を持つ英単語。ITの分野では、オブジェクト指向プログラミングにおけるオブジェクトに対する手続きのことや、通信プロトコルにおける要求の種類などのことをメソッドということが多い。一般の外来語としては、一定の形式として確立した奏法、教授法、指導法、その他様々な技法のことを「○○メソッド」のように言う。
オブジェクト指向プログラミングのメソッド (メンバ関数)
オブジェクト指向プログラミング(OOP)では、データと手続きを「オブジェクト」(object)として一体化(カプセル化)して定義、利用する。この、オブジェクトに内包された手続き(データに対する処理内容を記述したプログラム)のことをメソッドという。言語によっては「メンバ関数」などということもあるが、ほぼ同じものを指す。
メソッドはそのオブジェクトに対する操作内容の詳細が実装されており、外部からメソッドを呼び出して起動することにより、その内容が実行される。操作の詳細をオブジェクト内部に隠蔽することができ、プログラムの再利用性や生産性を高めやすくなると言われている。
インスタンスメソッドとクラスメソッド
一般的なメソッドは実行時に展開されるクラスのインスタンス(instance)に付属する「インスタンスメソッド」(instance method)で、所属するインスタンスのプロパティに対する操作などを行うことができる。「メンバメソッド」(member method)と呼ばれることもある。
一方、言語によってはクラス自体に付属する「クラスメソッド」(class method)を定義できる場合があり、クラス変数(静的変数/スタティック変数)の操作や参照、あるいは特に内部状態を必要としない基本的・汎用的な機能の提供などのために用いられる。「静的メソッド」(static method/スタティックメソッド)と呼ばれることもある。
メソッドのオーバーライド
一般的なクラスベースの言語ではメソッドはクラスの一部として定義される。あるクラスの内容を引き継いで一部を変更して別のクラス(サブクラス/派生クラス)を定義する際、元のクラスにあるメソッドと同名のメソッドを定義して別の内容に置き換える場合がある。
この操作をメソッドの「オーバーライド」(overriding)と言い、同名のメソッドがクラスによって異なる振る舞いをすることを「多態性」(polymorphism:ポリモーフィズム)という。サブクラスで機能を追加・変更する必要がある場合などに利用する。引数の型や数を派生元クラスのメソッドに揃えなければならないなどの制約を課している言語もある。
HTTPリクエストメソッド
通信プロトコルのHTTPでは、クライアントからサーバへ要求(リクエスト)を行う際、その種類を示すデータのことをメソッドと呼んでいる。主なメソッドとして、資源の送信を要求する「GETメソッド」、資源の受信(クライアント側から送信)を要求する「POSTメソッド」、資源本体ではなく資源についての情報(メタデータ)を要求する「HEADメソッド」などがある。
コンストラクタ 【構築子】
オブジェクト指向プログラミング言語において、クラスをインスタンス化する際に実行される特別なメソッド。インスタンスの初期化処理などを記述する。
言語により仕様や定義の仕方は異なるが、C++言語やJavaではクラス定義の内部でクラス名と同名のメソッドを定義すると、それがコンストラクタとして呼び出される。厳密にはコンストラクタにメソッド名はなく内部的には無名のメソッドとして取り扱われる。コンストラクタのための予約語が決められていて、これを名前とするメソッドを定義する言語もある。
コンストラクタ内では他のインスタンスメソッドと同じように任意の処理を記述することができるが、プロパティ(メンバ変数)の初期値の設定などを行うのが一般的である。インスタンスの初期化を超えてあまり複雑な機能を持たせるべきではないとされる。
コンストラクタの呼び出しは、そのクラス外のコード上でnew演算子などを用いて、「クラス名 変数名=new クラス名(引数);」のように変数宣言と同時に行うことが多い。生成されたインスタンスは宣言された変数に代入され、以降のコードで操作可能になる。
多くの言語では他のメソッドと同じように引数を指定することができ、インスタンス化する側のコードからパラメータを渡すことができる。一方、通常は生成したインスタンスへの参照が返り値として呼び出し側に渡されるため、他のメソッドのようにreturn文などで返り値を指定することはできない。
コンストラクタとは逆に、不要になったインスタンスを破棄する直前に実行する特殊なメソッドを定義できる言語もあり、「デストラクタ」(destructor)と呼ばれる。インスタンスが消滅する際に必要な後処理などを記述し、実行後はインスタンスが消滅してメモリが解放される。
メンバ変数 【データメンバ】
オブジェクト指向プログラミング(OOP)で、オブジェクトに所属する変数のこと。言語によっては「プロパティ」(property)「フィールド」(field)などと呼ばれることもある。
オブジェクト指向では互いに関連する属性(データ)と操作(手続き)を「オブジェクト」(object)として一体化して取り扱う。このうち、オブジェクトの状態を表すデータを格納する変数をメンバ変数という。
メンバ変数のうち、個々のインスタンスに所属するものを「インスタンス変数」(instance variable)、クラス自体に所属するものを「クラス変数」(class variable)あるいは「静的メンバ変数」(static member variable)「静的フィールド」(static field)という。
インスタンス変数は実行時にインスタンスを生成すると領域が確保され、インスタンスの内部状態を保持するのに用いられる。同じクラスに属していてもインスタンスが違えば互いに異なる変数として扱われる。インスタンスが破棄されると消滅する。
クラス変数はクラス自体に付属する変数で、クラスごとに単一の領域が与えられ、プログラムの実行開始から終了まで存続する。大域的に参照・変更できるクラス自身の状態を保持したり、実行時に内容を変更する必要がない定数の定義などに用いられることが多い。
オーバーライド
乗り越える、~に優先する、覆す、圧倒する、などの意味を持つ英単語。ITの分野では、ある場所で定義された設定や手続き、属性などを、別の定義で上書きすることを指すことが多い。
オブジェクト指向プログラミング(OOP)では、親クラス(スーパークラス/基底クラス)で定義されたメソッドを、そのクラスを継承した子クラス(サブクラス/派生クラス)で独自に定義しなおして上書きすることをオーバーライドという。子クラスで機能を追加する必要がある場合などに利用する。引数の型や数を元の関数などに揃えなければならないなどの制約を課している言語もある。
プログラミング以外でも、ある対象にあらかじめ定義された設定などを、利用者が独自に書き換える操作などのことをオーバーライドという。デフォルト設定(既定値)から一部を変更したり、対象の複製や派生などに伴って受け継いだ設定値などを変更する場合などが該当する。
オーバーロード
過負荷(にする)、過重積載(する)、過重負担(をかける)、などの意味を持つ英単語。IT分野ではプログラミング言語におけるメソッドや演算子などの多重定義を指すことが多い。
多重定義
プログラミングの分野で、同名の複数の関数やメソッド、演算子などを定義し、引数や被演算子の数やデータ型などに応じて使い分けることができる仕組みのことをオーバーロードという。「多重定義」と訳される。
関数やメソッドのオーバーロードでは、処理内容が同じか似ているが、引数の型や数が異なる同名の関数やメソッドを複数定義しておき、呼び出し側の引数の記述(これをシグネチャという)に応じて、対応するものが選択されて呼び出される。
言語によっては演算子のオーバーロードが可能なものもあり、被演算子(演算対象の変数やリテラル)のデータ型などに応じて使い分けることができる。例えば、「+」という記号で表される演算子を、整数や実数の場合は算術和を求める、文字列型のデータの場合は連結する、といったように挙動を変えることができる。
Webサーバ 【ウェブサーバ】
Webシステム上で、利用者側のコンピュータに対しネットワークを通じて情報や機能を提供するコンピュータ。また、そのような機能を実装したソフトウェア(Webサーバ・ソフトウェア)。
Webはクライアントサーバ型のシステムで、利用者が操作するWebクライアントと、クライアントの求めに応じてデータや機能を提供するWebサーバが連携して動作する。クライアントにはWebブラウザが用いられることが多いが、利用者が直に操作しないクローラー(ボット)なども存在する。
Webサーバはクライアントからの求めに応じて自身の管理するファイルを送信したり、内部で何らかの処理を行ったり、クライアントから受信したデータを保存したりすることができる。クライアントから要求やサーバからの応答は「HTTP」(Hypertext Transfer Protocol)という通信規約(プロトコル)に基づいて行われる。
クライアントからのサーバの指定、サーバ内の資源の指定は「http://~」あるいは「https://~」で始まる「URL」(Uniform Resource Locator)という記法が用いられる。例えばブラウザで「https://www.example.jp/corp/about.html」の表示を指示すると、「www.example.jp」というWebサーバへ接続を行い、「/corp/about.html」という位置にあるファイルの送信を要求する。
利用者の操作や入力をブラウザから受け取って処理を行い、その結果を反映した応答データを動的に生成して返す機能もあり、アプリケーションソフトのように対話的に機能を利用するシステムを作ることができる。これを「Webアプリケーション」と呼び、多くのネットサービスの実装方式となっている。
Webサーバソフトウェアには様々なものがあるが、汎用のWebサーバとして人気のものとしてはオープンソースの「Apache HTTP Server」や「nginx」などの人気が高い。企業向けの製品としては米マイクロソフト(Microsoft)社の「Internet Information Services」(IIS)がよく用いられる。
Webクライアント 【Web client】
Webサーバへ要求を送り、データや機能を引き出して利用するソフトウェア。Webブラウザやクローラー(ボット)などの総称。
WebではHTTP(Hypertext Transfer Protocol)と呼ばれるプロトコル(通信規約)が用いられるが、これはクライアントサーバ型の仕組みを採用しており、WebクライアントがWebサーバに要求(リクエスト)を送り、サーバがこれに答えて応答(レスポンス)を返すという手順を繰り返して通信する。
最もよく利用されるWebクライアントは人間が対話的に操作する「Webブラウザ」(web browser)である。利用者の指定したWebサーバからWebページを受信して表示・印刷したり、利用者から操作を受け付けてWebサーバに要求として伝えたり、入力したデータをWebサーバに送信したりすることができる。
人間が対面で利用するためのソフトウェアだけでなく、システムやアプリケーションが内部的に用いるHTTP通信プログラムや、検索エンジンなどで利用するためにWebページや関連コンテンツを自動的に収集して回る「Webクローラー」(ロボット、ボットなどとも呼ばれる)などもWebクライアントの一種である。
HTTPでは、Webクライアントが自らの名前やバージョンなどをサーバに申告する「User-Agent:」ヘッダが用意されており、クライアントが動作しているコンピュータやオペレーティングシステム(OS)の種類、クライアントの名称や開発元、バージョン番号などをサーバ側である程度把握することができる。ただし、この項目は自己申告であるため、自作のクローラーを一般的なWebブラウザであるかのように偽装する開発者などもおり、完全に正しく識別できるわけではない。
リッチクライアント
Webアプリケーションのクライアントとして、Webブラウザで単純なWebページを表示する方式を超える表現力や操作性を備えたシステムを用いること。専用のアプリケーションソフトを利用する場合とWebブラウザで高度な機能や拡張技術を用いる場合がある。
Web上でクライアントサーバ型のシステムを実装しようとすると、Webサーバが静的なHTMLによるWebページを生成してWebブラウザに送信し、利用者はページ内のフォームなどに入力してサーバへデータを送信、ページが再生成されて送り返されてくる、といった形の操作感となる。
専用のクライアントソフトを利用する場合に比べ、入力のたびにいちいちページ遷移するため動作がもたつき、画面の表示内容の表現力や操作要素の機能などもHTML/CSSの仕様の範囲に制限されるため乏しくなってしまう。
リッチクライアントはこのようなWebクライアントの欠点を補い、Webアプリケーションの利点を残しつつクライアント側の機能を強化したもので、WebブラウザでHTMLを表示する以上の豊富な機能を利用することができる。リッチクライアントを用いたWebアプリケーションをRiA(Rich Internet Application)ということがある。
主な実現方式は3種類に大別でき、AjaxのようにHTML/CSS/JavaScriptというWebページの枠組みの中で操作性を向上させる方法、FlashやJavaアプレット、ActiveXコントロール、SilverlightのようにWebブラウザに機能拡張を組み込む方法、Adobe AIRやBiz/Browserのようなブラウザ以外のソフトウェアを用いる方法がある。
Ajax 【Asynchronous JavaScript + XML】
あるWebページを表示した状態のまま、別のページや再読込などを伴わずにWebサーバ側と通信を行い、動的に表示内容を変更する手法。ページ上でプログラムを実行できるプログラミング言語JavaScriptの拡張機能を用いる。
従来、Webページの内容にサーバから受信したデータを反映させるには、デザインなどが同等の別のページを読み込んで新たに表示させるか、同じページをリロード(再読込)してサーバからページごと受信し直す必要があった。
AjaxではJavaScriptのHTTP通信機能(XMLHttpRequestあるいは同等のWebブラウザの拡張API)を用い、ページ内で実行されるプログラム中からサーバとの間でHTTP通信を行い、内容のロードを行う。通信方式はWebページの読み込みと同じHTTPによるURL指定を用いるため、Webサーバ側からはブラウザが新たなページの送信要求をしてきたように見える。
XMLHttpRequestはプログラムの実行と非同期(asynchronous)に通信を行い、サーバからの応答の受信が完了すると指定された関数を実行するという仕組みになっている。サーバと通信する間、プログラムの流れや利用者を待たせずに済む。また、受信したデータはデフォルトではHTMLを含むXML形式のオブジェクトとして処理される。
Ajaxとは「非同期にXMLデータをJavaScript上で送受信できる」という意味の略語だが、設定によりHTTP通信を同期して扱う(通信完了まで一時停止する)ことも、受信したデータをXMLではなく単純なテキストデータ(プレーンテキスト)として扱うこともできる。これらも便宜上Ajaxのバリエーションの一種とみなされている。
Apache 【Apache HTTP Server】
世界的に最も普及しているWebサーバ(HTTPサーバ)ソフトウェアの一つ。 非営利団体のアパッチソフトウェア財団(Apache Software Foundation)が開発しており、オープンソースソフトウェアとして公開している。
古くから開発・公開されてきた人気の高いWebサーバで、安定性や機能の豊富さ、対応ソフトウェアの多さなどが評価され、企業から個人まで様々な用途で利用されている。LinuxやWindows、macOSを始め様々なオペレーティングシステム(OS)上で動作し、いくつかの著名なOSでは、そのOSでの動作に最適化された高性能なプログラムを利用することができる。
モジュールによる機能拡張
拡張機能をモジュールとして追加できる構造となっており、公式にいくつかの機能が配布されているほか、第三者が自由にモジュールを開発・導入することができる。
特定のプログラミング言語を利用するためのモジュールや、企業が自社製品と連携するためのモジュールなど様々なものが開発されている。「mod_perl」「mod_rewrite」「mod_cgi」など、モジュール名は慣習として「mod_機能名」という形式になっている。
Apacheはオープンソースとしてソースコード自体が配布されているため、実行可能(バイナリ)形式へのコンパイル時にあらかじめモジュールを組み込み、Webサーバ本体に一体化させて動作させる「静的リンク」を行うことができる。別にコンパイルしたモジュールを実行時に連携させる「動的リンク」より導入は手間だが、高速に動作させることができる。
歴史
初版は1995年に公開された。それ以前に普及していた「NCSA HTTPd」というWebサーバの開発が停滞したことから、有志がその不具合の解消や改良を行うパッチ(patch:継ぎ当て)プログラム集として開発した。
名称の由来として、NCSA HTTPdにパッチを継ぎ当てた “A patchy web server” (つぎはぎのWebサーバ)をアメリカ大陸先住民のアパッチ族(Apache)に掛けたものであると説明されることが多いが、当時の開発者グループの中心メンバーだったブライアン・ベーレンドルフ(Brian Behlendorf)氏によれば、“Apache”という名前は突然ひらめいたもので、しばらくしてから別のメンバーにそのような語呂合わせを指摘されたとしている。
Apache Software Foundation
後に同氏を中心に非営利団体のApache Software Foundationが結成され、パッチ集から独立したWebサーバソフトウェアとして全面的に再開発された。同財団はApache以外にもサーバ向けソフトウェアを中心に様々なオープンソースソフトウェアの開発・配布を手がけている。
Apacheをオープンソースとして開発・配布するために考案されたライセンス(利用許諾契約)である「Apacheライセンス」(Apache License)は著名なオープンソースライセンスの一つとして広く普及している。
BNF 【Backus-Naur Form】
コンピュータが扱う人工言語の文法を定義する際に用いられるメタ言語(言語を記述するための言語)の一つ。コンピュータ言語の多くはその仕様をBNFで定義している。
BNFは言語内で意味を持つ記号列と、それがどのような内容を取りうるのかを「<記号>::=定義」という構文を用いて列挙していく。左辺値に現れる記号は右辺値で変換可能な「非終端記号」で、右辺値にしか現れない記号はそれ以上変換できない「終端記号」である。
定義には「<居住自治体>::=<都道府県> <市区町村>」のようにスペースで区切って複数の要素の組み合わせ(連接)を置いたり、「<真理値>::=true|false」のように縦棒(|)で区切って複数の要素の選択を表すことができる。BNF内で定義する記号列は山括弧(<>)で括り、括られてない記号列は定義対象の言語における表記とみなされる。
BNFは構文を形式的に定義するための言語で、意味を規定するものではないため、BNFだけで言語のすべてを定義することはできない。プログラミング言語の定義だけでなく、プロトコルやデータ形式、マークアップ言語の定義などにも使われる。マークアップ言語として最も普及しているXMLも、その構文はBNF(正確には拡張BNF)で規定されている。
BNFは1959年にアメリカ人のジョン・バッカス(John Backus)氏が提案し、デンマーク人のピーター・ナウア(Peter Naur)氏が修正を加え、1960年にプログラミング言語「ALGOL」(ALGOL 60規格)の仕様定義のために初めて採用された。現在ではオリジナルのBNFに拡張が加えられた「拡張BNF」(EBNF)が使われることが多いが、EBNFには変種や独自拡張が多く、どの版を使用しているかに注意を払う必要がある。
メタ言語
言語を定義したり、言語についての情報を記述したりするための言語。“meta-” は「高次の」「超~」などを意味する接頭辞で、「言語の言語」を意味する。
ITの分野では、プログラミング言語などの人工言語の語彙や文法などを記述したり定義したりするための人工言語や記法などのことをメタ言語ということが多い。例えば、プログラミング言語の定義などに用いられるBN記法(BNF/EBNF)や、特定用途のマークアップ言語を定義することができるマークアップ言語であるXMLやSGMLなどがよく知られる。
また、言語の文法など言語そのものを記述するのではなく、ある言語による表現(あるプログラミング言語によるプログラムコードなど)を生成するために用いられる別の言語や、元の言語の仕様を拡張・変更した言語のことをメタ言語ということがある。
例えば、TypeScriptやCoffeeScriptなどのスクリプト言語で記述されたプログラムはそれ自体が解釈・実行されるのではなく、いったんJavaScriptのプログラムに変換(トランスパイル)されてから実行される。このような場合に、これらの言語をJavaScriptのメタ言語であるという。
プログラミング言語
主に人間がコンピュータプログラムを記述、編集するために用いる人工言語。作成したプログラムは機械語による記述に変換した後、コンピュータで実行できるようになる。
プログラム言語でプログラムを開発することを「プログラミング」(programming)、プログラム言語で記述したプログラムを「ソースコード」(source code)という。語彙、文法、記法などが自然言語よりも厳密に定義されており、記述したソースコードはソフトウェアによって自動的に解析、処理、変換などすることができる。
コンパイラとインタプリタ
プログラム言語は人間にとって理解、記述しやすい語彙や文法で構成された言語であり、そのままではコンピュータ(のCPU)が解釈、実行することができないため、ソフトウェアによってCPUが実行可能な言語(機械語、マシン語)によるプログラムに変換して実行される。
開発時や導入時などに一度にまとめて変換処理を行うことを「コンパイル」(compile)、そのような変換ソフトを「コンパイラ」(compiler)という。実行時に変換と実行を同時並行で行うソフトウェアを「インタプリタ」(interpreter)という。
高水準言語と低水準言語
プログラム言語は人間にとっての理解のしやすさや機械語に対する抽象度の高さによって分類されることがあり、機械寄りの言語を「低水準言語」(low-level language)あるいは「低級言語」と呼び、人間寄りの言語を「高水準言語」(high-level language)あるいは「高級言語」という。
機械語の命令コードと一対一に対応する命令語を用いてプログラム言語を行う低水準言語のことを特に「アセンブリ言語」(assembly language)と呼び、機械語への変換ソフトを「アセンブラ」(assembler)という。
プログラミングパラダイム
プログラムをどのようなものとして捉え、構築していくかについて一定の設計思想やルールがある場合が多く、これを「プログラミングパラダイム」(programming paradigm)という。複数の書き方が可能な言語は「マルチパラダイム」であるという。パラダイムに基いて言語を分類することもある。
手続きを順番に記述していく「手続き型言語」(procedural language)あるいは「命令型言語」(imperative language)や、関連するデータ群と手続き群を一つのまとまりとして捉える「オブジェクト指向言語」(object-oriented language)、プログラムを関数の組み合わせとして捉える「関数型言語」(functional language)、データ間の関係や論理を記述していく「論理型言語」(logic programming language)などの種類がある。
また、主な利用目的や主要な処理系の実装方式により分類することもあり、記述や実行の手間を軽減して迅速にプログラム開発ができる「スクリプト言語」(script language)あるいは「軽量言語」(LL:Lightweight Language)、特定の分野や処理に特化した「ドメイン固有言語」(DSL:Domain Specific Language)などの分類がある。
機械語 【マシン語】
コンピュータのマイクロプロセッサ(CPU/MPU)が直接解釈・実行できる命令コードの体系。0と1を並べたビット列として表され、人間が直に読み書きしやすい形式ではない。
プロセッサは設計段階でどのような命令番号(オペコード)が与えられたらどのように動作するかが決められている。機械語のプログラムは基本的に命令番号を実行順に並べたデータとなっており、個々の命令には必要に応じて処理すべき対象となるデータ(オペランド)などを付記する。
機械語はプロセッサに直接命令を与える言語であるため、プロセッサの持つすべての機能を利用することができる。どのようなプログラミング言語で記述されたプログラムであっても、ソフトウェアによる変換や調整を経て最終的には機械語のプログラムとしてプロセッサに渡され実行される。
ニーモニックとアセンブリ言語
人間が命令番号そのものを暗記して直にプログラムを記述するのは容易ではないため、各番号に意味を類推しやすいアルファベットの並び(ニーモニック)を一対一に対応付け、これを用いてプログラムを記述する手法が用いられる。このようにして作られたプログラミング言語をアセンブリ言語(assembly language)という。
アセンブリ言語によるプログラミングはハードウェアを直に制御でき、短く高速なプログラムを記述することができるが、大規模で複雑なプログラムや大人数での分業などには向いていない。OSやデバイスドライバなどハードウェアを直接的に制御する必要のあるプログラムや、極めてシビアに実行速度が求められる場面などで部分的に用いられることが多い。
命令セットとプログラムの互換性
命令番号と動作の対応関係、および各命令に付随するオペランドの形式などを定めた体系は命令セットアーキテクチャ(ISA:Instruction Set Architecture)あるいは単に命令セットと呼ばれ、同じ命令セットを持つプロセッサ間では互いに同じ機械語プログラムをそのまま実行することができる。
一般に、同じメーカーの同じ製品シリーズのプロセッサ製品間は同じ命令セットを共有し、新しい製品に新たな命令が追加されるようになっており、異なるモデルや世代の製品間でも同じ機械語プログラムを動作させることができる。異なるメーカーが同じ命令セットを実装した製品を開発する場合もあり、互換プロセッサなどと呼ばれる。
命令セットが異なるプロセッサ間では同じ機械語プログラムは動かないため、プログラムのソースコードからコンパイルなどの処理を行ってそのプロセッサの命令セットによって記述された機械語プログラムを生成する必要がある。
アセンブリ言語
プログラミング言語の類型の一つで、コンピュータのCPU(MPU/マイクロプロセッサ)が直接解釈・実行できる機械語(マシン語)と正確に対応する命令語で構成された言語。
人間が実用的に使用できるプログラミング言語で最も機械に近い低水準(低級)な言語で、具体的な仕様はプロセッサの機種(命令セットアーキテクチャの種類)ごとに異なる。
コンピュータはCPUがプログラムとして与えられた機械語の命令列を順番に実行することで処理を行うが、機械語の命令は「オペコード」(opcode)と呼ばれる識別番号(正確にはビット列)で表されるため、これを直に人間が記述してプログラムを作ることは困難で、無理に書いたとしても後から読み解くのが難しく、書き間違いも起きやすい。
そこで、それぞれのオペコードに対応する「ニーモニック」(mnemonic)と呼ばれる短いアルファベットの命令語を定義し、これを用いてプログラムを記述する手法が考案された。あるプロセッサのオペコードの体系に対応するニーモニックの集合を定義したものを、そのプロセッサに対するアセンブラ言語という。
例えば、米インテル(Intel)社の8086プロセッサにおいて、指定されたレジスタの値を指定されたメモリ番地に書き込む命令は「10001000」というビット列で表され、十進表記では136、16進表記では88となるが、これに「mov」というニーモニックを対応付ければ何をする命令なのか分かりやすい。
オペコードとニーモニックの対応関係
機械語の場合、値を代入するという同じ動作でもオペランド(引数)として指定される対象の組み合わせ(即値→レジスタ、レジスタ→レジスタ、レジスタ→メモリなど)によって異なるオペコードが割り当てられている場合がある。これらは動作に即して同じニーモニックで表されることが多く、オペランドの組み合わせから適切なオペコードに変換される。
このため、オペコードとニーモニックは必ずしも正確に一対一には対応していないが、ある命令セットを完全に実装したアセンブリ言語では、どのオペコードにも必ず対応するニーモニックが用意されている。
アセンブラ/アセンブル
アセンブラ言語で記述されたソースコードはそのままでは実行できないため、アセンブラ(assembler)と呼ばれるソフトウェアで機械語のプログラムに変換されてから実行される。この変換処理をアセンブル(assemble)という。
アセンブラは機械語への置き換えだけでなく、マクロの展開や、シンボル名を実際の値やメモリアドレスに置き換えたりといった処理も行なう。
ニーモニックの体系はアセンブラに実装されるため、同じ命令セットに対応したアセンブラでもアセンブリ言語は異なっていることがある。ただし、通常はプロセッサの開発元が命令セットの仕様を公開・提供する際に標準のニーモニックを公表するため、これに沿った実装が行われる。
高水準言語 【高級言語】
プログラミング言語の分類の一つで、抽象的な語彙や記法、構文などを用いて処理を記述することができる言語の総称。
「高水準」「高級」とは優れた言語という意味ではなく、機種やOSなどに固有の要素を極力排し、抽象度の高い記述が可能であることを表しており、アプリケーションソフトの開発などに用いられる言語の多くは高水準言語に分類される。
これに対し、コンピュータ(CPU)が直接解釈・実行できる機械語(マシン語)や、機械語と一対一に対応するアセンブリ言語などのことは「低水準言語」(low-level programming language)あるいは「低級言語」と呼ぶ。ここでの「低」はハードウェアに近いという意味である。
高水準言語は英語など自然言語の語彙や構文を利用したり、数式に似た記号や記法などを取り入れることにより、人間が記述・読解しやすい構造となっている。言語仕様はハードウェアやOSの仕様とは切り離された抽象的なものになっており、様々な環境で同じように動作する汎用的なソフトウェアの開発に向いている。
一方、ハードウェアへの直接的なアクセスやハードウェア固有の機能の利用は制限されており、また、CPUの振る舞いを細かく記述して性能を引き出すことも難しい。デバイスドライバのように装置を直接制御するような用途や、複雑で高度な機械の制御ソフトのように応答時間に強い制約があるような環境にはあまり向いていない。
高水準言語を使って人間の記述したプログラム(ソースコード)はそのままではコンピュータが解釈できないものであるため、変換ソフトウェアによって機械語による実行可能なプログラム(オブジェクトコード)に変換されて実行される。開発時にまとめて変換するものを「コンパイラ」(compiler:翻訳者の意)、実行時に逐次変換しながら並行して実行するものを「インタプリタ」(interpreter:通訳者の意)という。
手続き型言語 【命令型言語】
プログラミング言語の分類の一つで、コンピュータが実行すべき命令や手続きを順に記述していくことでプログラムを構成する言語。
命令は一つずつ記述して並べることもできるが、多くの言語では複数の命令をひとまとまりの手続きに連結し、外部から一つの大きな命令のように呼び出せるようにする機構を備えている。この手続きは言語により「プロシージャ」(procedure)、「サブルーチン」(subroutine)、「関数」(function)、「メソッド」(method)などと呼ばれる。
コンピュータ(のCPU)が直に解釈・実行できる機械語(マシン語)のほとんどは命令型の言語体系となっており、CPUが行うべき処理の内容を一つずつ命令として記述して順に並べることによりプログラムを構成する。手続型言語は機械語をより人間に扱いやすく翻訳したものと言え、機械語そのものでは記述が難しい複雑な構造のプログラムや大規模なプログラムの開発を容易にしてくれる。
広義の手続型言語には、手続きと関連するデータを一つの単位にまとめるオブジェクト指向の手続型言語を含むが、文脈によっては「手続型言語」が非オブジェクト指向型の手続型言語を指し、オブジェクト指向言語と対比される場合がある。
在来型の手続型言語にはAdaやFortran、ALGOL、PL/I、C言語、COBOL、BASIC、Pascalなどがあり、オブジェクト指向型の手続型言語にはC++言語やJava、C#、Visual Basic、Perl、Python、Ruby、JavaScript、PHP、Go言語、Rustなどがある。
一方、手続型言語あるいは命令型言語とは異なる体系の言語を「非手続き型言語」(non-procedural language)あるいは「宣言型言語」(declarative language)と総称する。命令の列挙以外の方法でプログラムを構成する言語で、「関数型言語」(functional language)や「論理型言語」(logic programming language)、「問い合わせ言語」(query language)などを含む。
Fortran 【Formula Translating System】
科学技術計算などでよく用いられるプログラミング言語の一つ。1954年に米IBM社のジョン・バッカス(John W. Backus)氏が考案した言語で、世界で最初の高水準プログラミング言語であるとされる。
手続き型言語で、複素数型を組み込みデータ型として利用できたり、数式を数学での表現に近い形で記述できるなど、数値計算プログラムを記述しやすいようにできている。また、科学技術分野で長年用いられてきたことから数値計算ライブラリなどが豊富に蓄積・整備されている。
当時の大型コンピュータではパンチカードでプログラムの入力を行っていたため、1行が80桁固定で、1~6桁目はラベルやコメント宣言、7~72桁目がプログラム本文、73~80桁目が注釈などと決まっていた。他にも変数名が6文字以内など古いコンピュータ設計に基づく制約があったが、Fortran 90以降では現代的な仕様に生まれ変わっている。
歴史
コンピュータプログラムの作成にアセンブリ言語しか使えなかった当時、初の本格的な高水準言語として好評を博した。1960年代には各コンピュータ会社が自社機向けに派生仕様や専用の開発環境などを提供しはじめたため、1966年にANSI(米国規格協会)が標準規格(FORTRAN 66)を定めた。
コンピュータ技術の発展とともにFORTRAN 77、Fortran 90、95、2003、2008、2018と標準仕様は今日まで継続的に改訂され続けている。近年の規格ではオブジェクト指向や並行処理についての仕様が追加される一方、時代遅れの古い仕様が削除されている。
初期のコンピュータはアルファベット小文字に対応していなかったことなどから、当初は「FORTRAN」(印刷物などではO以降が小さいサイズの大文字=スモールキャピタルとなる)と表記されたが、Fortran 90以降では「Fortran」表記が規格上の正式名称であるとされる。
COBOL 【COmmon Business Oriented Language】
会計処理や事務処理に適したプログラミング言語の一つ。コンピュータが企業や官公庁の事務処理に応用され始めた1960年代から使われている言語で、現在でも長年使われている会計システムなどで広く利用されている。
汎用の手続き型プログラミング言語で、英文に似た語彙や構文を採用しているのが大きな特徴である。例えば、「変数Xに1を足す」という処理は、数式に近い記法を採用する他の多くの言語では「X:=X+1」といったように記述するが、COBOLではこれを「ADD 1 TO X」と、処理内容を英文で記述したような表記が可能となっている(数式を利用した構文も用意されている)。
これにより、処理内容を厳密に英文で定義・記述することができれば、これを元に容易にCOBOLプログラムを作成することができ、また、出来上がったプログラムは英文を読み下すように内容を理解することできる。
一方、他の言語に比べ記述が冗長になりがちで、他言語に親しんだ開発者などは処理の流れが把握しにくいと感じることもある。処理内容によっては、記述の冗長さのために一見何をしようとしているのか分かりにくい難解なコードとなってしまうこともある。
歴史
COBOLの最初の仕様は、1959年から60年にかけて、アメリカ政府と大手コンピュータメーカーなどで組織する委員会「CODASYL」(Conference on Data Systems Languages)によって策定された。米政府発注のシステム開発プロジェクトで広く採用されたことから普及し、米国内のみならず日本を含む各国で大型汎用機(メインフレーム)の事務処理システム開発用の言語として定着した。
非常に歴史が長く基本設計の古い言語であるため、古臭い技術の代表として槍玉に挙げられることも多いが、2進化10進数の固定小数点数で極めて誤差の小さい金額計算ができるなど、現代の言語には見られない優れた特徴もある。2010年代にも標準規格の改訂が行われ、処理系の提供が続いている。
COBOLに熟達した技術者の引退が進み、近年では会計処理などでも新規開発のプロジェクトはJavaなど現代的な言語が採用される例が増えているが、官庁や大企業の既存システムの改修や更改などを中心に、現在も数多くのCOBOLプログラムが開発・運用・保守され続けている。
Pascal 【Philips’ Automatic Sequence Calculator】
主にコンピュータ科学の教育などに用いられるプログラミング言語の一つ。1968年にスイスのコンピュータ科学者ニクラウス・ヴィルト(Niklaus Wirth)氏によって考案された。命名の由来は17世紀の著名なフランスの哲学者ブレーズ・パスカル(Blaise Pascal)。
ALGOLの流れを汲む手続き型のプログラミング言語で、構造化プログラミングに適した制御構造(while文、while文、repeat-until文、case文など)や、簡潔で軽量な言語仕様で知られる。基本的な記法は同じALGOL系のC言語などに近く、文と文の区切りにはと同じ「;」(セミコロン)を用い、引数は()で括って列挙する。
制御文の範囲などを指定するためにbegin文とend文で複数の文を括って複合文(コードブロック)を定義できる。複数の処理をまとめて外部から呼び出せるようにするサブルーチンの機構もあり、procedure文で手続き(戻り値なし)を、function文で関数(戻り値あり)を定義できる。
すべての変数のデータ型をコード中であらかじめ宣言して使用する(強い)静的型付け言語で、整数型(integer)、実数型(real)、文字型(char)、論理型(Boolean)、列挙型(type)などを利用できる。
組み込みのデータ構造(複合データ型)として配列、文字列(文字型の配列)、集合型、レコード型(C言語の構造体に近い)などを備える。変数宣言はC言語などと異なり var 変数名:型名; という形式を用い、変数名はカンマ(,)で区切って複数並べることができる。後にGo言語や一部のJavaScript拡張などが似た記法を採用している。
多くのPascal処理系はコンパイラによって実行可能形式に変換する方式を用いており、初期のPascalコンパイラはPascal自身によって書かれたという。ポインタなど低レベル(ハードウェア寄り)の仕様も組み込まれており、教育用を想定しながら実用的なプログラム開発にも使うことができる。
1980年代を中心に大学の情報科学、コンピュータ科学などの課程で教育用によく利用された。パソコン向けの処理系として米ボーランド(Borland)社(当時)の「Turbo Pascal」なども発売され、最初期のMacintosh向け開発環境の標準のプログラミング言語にも用いられるなど一定の人気を博した。
中でもオブジェクト指向についての拡張を施した「Object Pascal」を採用した米ボーランド(Borland)社(当時)の開発ツール「Delphi」(デルファイ)はパソコン向けの開発環境として非常に人気があった。
Delphi (デルファイ)
米エンバカデロ・テクノロジーズ(Embarcadero Technologies)社が開発・提供しているソフトウェア開発環境およびプログラミング言語。元は米ボーランド(Borland)社の製品として知られていたが、2008年に同社の開発ツール部門がエンバカデロ社へ売却された。
開発作業の一部をグラフィックス表示とマウス操作で行うことができるビジュアル開発環境(RADツール)の草分けで、Pascal言語にオブジェクト指向の拡張を施した独自のDelphi言語(以前はObject Pascalと呼ばれていた)によりコードを記述する。当初はWindows専門の開発環境だったが、現在では同じソースコードでmacOS(Mac OS X)やiOSなど向けのプログラムを生成することもできる。
BASIC 【Beginners’ All-purpose Symbolic Instruction Code】
プログラミングの入門・教育のためによく利用された汎用の手続き型プログラミング言語の一つ。1960年代に開発された古い言語だが、現代でも「VBA」(Visual Basic for Applications)などの形で利用されている。
初期のBASIC言語および処理系は、他の本格的なプログラミング言語の多くで必要となるプログラム冒頭の各種の宣言などがほとんど不要で、利用者の必要とする処理を記述するだけでプログラムとして成立する点や、変数宣言を省略していきなり変数を使用してよい点、文字列の扱いが容易で文字列操作の機能が豊富な点など、容易にプログラミングを始められる仕様や特徴が盛り込まれていた。
最初に開発されたのは実行可能ファイルへの変換が必要なコンパイラ型の言語処理系だったが、記述したプログラムを即座に実行してみることができるインタプリタ型の処理系が多く開発され、手軽さからホビー用途や教育用途で特に歓迎された。
一方で、プログラムの構造化のための制御構文など、複雑・大規模なプログラムを整然と記述するための機能が不足し、外部のプログラムを取り込んで利用する機能なども存在しない処理系が多いなど、本格的なソフトウェア開発にはあまり向いていないとされる。
歴史
1964年に米ダートマス大学のジョン・ケメニー(John G. Kemeny)氏、トーマス・カーツ(Thomas E. Kurtz)氏によって考案された。当時の大型コンピュータで大学生などがプログラミングを学ぶのに用いられた。
1970年代後半にパソコン(当時日本ではマイコンと呼んでいた)が発明され普及し始めると、オペレーティングシステム(OS)とソフトウェア開発・実行環境を兼ねた基盤的なソフトウェアとしてBASIC処理系が提供されるようになり、主にホビー用途で主要なプログラミング言語として広まった。
日本ではNECのPC-8001向けの「N-BASIC」、PC-8800シリーズ向けの「N88-BASIC」、富士通のFMシリーズ向けの「F-BASIC」、MSXパソコン向けの「MSX-BASIC」、ファミリーコンピュータでプログラミングができる「ファミリーベーシック」などが提供され、ホビープログラマを中心に人気を博した。
各社が自社の機種やOSに合わせて独自に処理系を開発・提供したため、メーカーごとの仕様の違い(自然言語になぞらえて「方言」と呼ばれる)が大きく、ある機種向けのBASICプログラムは他メーカーの機種ではそのままでは動作しないことが多かった。
米マイクロソフト(Microsoft)社はBASIC言語を元に「QuickBASIC」を、さらにこれを発展させて「Visual Basic」を開発し、自社の主要なソフトウェア開発ツールとして派生言語と共に自社製品の多くに組み込んで提供している。これは記法や一部の機能は初期のBASIC言語を踏襲しているが、大幅な拡張や機能の追加によりほとんど別物となっている。
C言語 【C language】
広く普及している手続き型の高水準プログラミング言語の一つ。汎用的な言語で様々な分野で広く利用されているが、特にオペレーティングシステム(OS)などハードウェアを直接制御するプログラムの開発で利用される機会が多い。
特徴と用途
繰り返しや条件分岐、関数定義など構造化プログラミングを実現するための制御構文を多く備え、実行位置を任意の箇所に変更する構文(いわゆるgoto文)を排除した見通しの良いプログラムを記述することができる。自由度が高く拡張性が高いが、プログラムの安全性を高める配慮はあまりなく、よく仕様を理解して注意深く記述することが求められる。
波括弧 { } で括った複数の文を一つの文とみなすコードブロックの仕組みや、セミコロン(;)による文の区切り、「++」「!=」のように記号文字を組み合わせた演算子表記など、C言語で採用された記法の多く(必ずしもCオリジナルではなくそれ以前の言語から移入されたものも多い)は、その後現れた多くのプログラミング言語が踏襲している。
メインメモリ(RAM)のアドレスを直に指定したり変数に格納して操作することができる「ポインタ」(pointer)や、プログラム中にアセンブリ言語を埋め込んで記述することができるインラインアセンブラなど、低水準(ハードウェア寄り)の制御が可能な仕組みが用意されている。
C言語は高速性やハードウェア制御が必要なソフトウェアの開発に用いられることが多く、オペレーティングシステム(OS)やドライバソフト、他のプログラミング言語の言語処理系(スクリプト言語のインタプリタなど)、電子機器の組み込みシステムの制御ソフトウェアなどの開発によく用いられる。
実行環境と移植性
C言語で記述したプログラム(ソースコード)はコンパイラと呼ばれるソフトウェアによって機械語のプログラム(オブジェクトコード)に変換されて実行される。様々な機種やOS向けの開発環境で標準的にCコンパイラが提供されており、最も対応環境が多く移植性の高い言語の一つである。
ただし、環境によって標準ライブラリが提供する関数などが異なったり、ハードウェアの仕様に依存するコードがそのままでは動作しない場合があるため、他の環境へ移植する際には書き換えやプリプロセッサによる条件付きコンパイルなどの調整が必要なことが多い。
歴史
C言語の最初の仕様は1972年に当時のAT&T社ベル研究所でデニス・リッチー(Dennis M. Ritchie)氏とブライアン・カーニハン(Brian W. Kernighan)氏によって発表された。初期のUNIXはC言語で記述されており、UNIXにはC言語の処理系が同梱されていたためUNIX系OSと共に広まっていった。
言語仕様は1989年にANSI(米国国家規格協会)によって「ANSI C」と通称される標準規格となった。1990年にISO(国際標準化機構)とIEC(国際電気標準会議)によってISO/IEC 9899となり、日本でも1993年にISO標準を訳したものがJIS(日本産業規格)の一部として標準化(JIS X 3010)されている。
標準規格は機能の追加など改版を重ねており、当初の標準規格を制定年から「C90」、1999年の改訂版(ISO/IEC 9899:1999)を「C99」といったように通称する。2011年版の「C11」、2018年版の「C18」あるいは「C17」(仕様が固まったのが2017年のため)、2023年版の「C23」が知られている。
「C」という名称の由来は、当時存在した「B」という言語を改良したものであることからとされる。後にC言語の仕様にオブジェクト指向などの仕様を追加した「C++」言語が開発され、現在ではC++言語が用いられることが多い。
R言語
統計解析に適した仕様を持つプログラミング言語の一つ。プログラミングの専門家でなくても短い記述で大量のデータを効率よく処理できるよう配慮されている。標準の処理系はオープンソースソフトウェアとして公開されている。
基本的な文法や記法は、同じ統計処理言語のS言語や関数型言語のSchemeなどの影響を受けているが、C言語のような手続き型の書式やオブジェクト指向についての仕様も規定されている。データ処理や統計解析に特化した言語であるため、汎用プログラミング言語のようなアプリケーション開発には向かない。
ユニークな仕様として「ベクトル処理」があり、ベクトル(vector)と呼ばれるリストや配列に似たデータ構造にデータを格納し、関数による一括処理やベクトル同士の演算という形で多数のデータを対象とする処理を簡潔に記述することができる。汎用言語ではfor文などでループ処理を記述する場面でも、一行のベクトル処理で済ませられることが多い。
ベクトルだけでなく配列(array)、行列(matrix)、リスト(list)、表に相当するデータフレーム(data frame)、時系列データ(time series)など様々なデータ構造、文字型、論理型、複素数を表現可能な数値型などのデータ型に標準で対応する。関数をデータとして扱う高階関数も利用できる。
統計やデータ処理についての機能が標準で豊富に組み込まれており、基本的な統計関数、検定関数、多変量解析のための関数(因子分析、主成分分析、クラスタリングなど)、様々な確率分布における確率密度や累積分布、確率点、乱数を求める関数、線形回帰モデル、分散分析モデル、欠損値(N/A)を表す定数、サンプリング関数などが用意されている。
グラフなど図表の描画機能も充実しており、解析結果を印刷物でも使用可能な品質の図表や画像に表すことができる。PNGやJPEGなどの画像ファイル、PDFやLaTeX、PostScriptなどの文書ファイルとして書き出す機能も標準で備えている。
標準に存在しない機能は「パッケージ」として追加することができる。世界中の開発者が作成したパッケージが「CRAN」(The Comprehensive R Archive Network)と呼ばれるインターネット上の集積所で公開されており、簡単な操作でパッケージの取得や開発環境への導入、更新などを行うことができる。
オブジェクト指向言語 【オブジェクト指向プログラミング言語】
プログラミング言語のうち、互いに関連するデータの集合とそれらに対する手続き群をひとまとめにした「オブジェクト」(object)をプログラムの基本的な構成単位として扱うことができるもの。
オブジェクト指向プログラミング(OOP:Object-Oriented Programming)はコンピュータプログラムの構成法の有力な一方式で、データと手続き一体化したオブジェクト群を定義していき、それらが互いに指示やデータを送り合うことにより処理を進めていく。
オブジェクト指向言語はこのような開発方式に必要な諸機能を言語仕様として備えているものを指し、オブジェクトの雛形であるクラス(class)やプロトタイプ(prototype)、および内部のメソッド(method)やプロパティ(property)を定義する構文や、オブジェクトのインスタンス化、メソッド呼び出し、メッセージ交換などの機能を提供する。
オブジェクトの定義にクラスを用いる言語とプロトタイプを用いる言語に分けられ、C++言語やC#、Javaなどは前者、JavaScriptやRuby、Pythonは後者に分類される。
C言語を拡張してオブジェクト指向性を持たせたC++やObjective-C、ML(Meta-Language)を拡張したOCaml、Pascalを拡張したObject Pascalのように、既存の言語にオブジェクト指向性を追加した言語もある。
オブジェクト指向という性質は手続き型や関数型などプログラミング言語における他のスタイルと共存することができる。オブジェクト指向の手続き型言語が多いが、前述のOCamlのように関数型かつオブジェクト指向の言語などもある。
Java
様々な分野で人気の高いオブジェクト指向プログラミング言語の一つ。旧サン・マイクロシステムズ(Sun Microsystems)社が開発したもので、同社を買収した米オラクル(Oracle)社が開発を引き継いでいる。
C言語に似た表記法を採用しているが、過去の言語の仕様を受け継がず新たに設計されており、特にオブジェクト指向プログラミングを前提として言語仕様が整理されている点が大きな特徴となっている。強力なセキュリティ機構や豊富なネットワーク関連の機能が標準で用意されており、ネットワーク環境で利用されることを強く意識した仕様になっている。
Javaで開発されたソフトウェアは特定のコンピュータの機種やオペレーティングシステム(OS)などに依存することなく、基本的にはどのようなプラットフォームでも動作する。ただし、JNI(Java Native Interface)のようなインターフェースを通じてOSなどの機能を直接呼び出したり、ある開発環境に固有のライブラリやAPIを利用しているプログラムは特定の環境でしか動作しない。
同社では標準の開発環境としてJDK(Java Development Kit)、統合開発環境(IDE)としてNetBeans、実行環境としてJRE(Java Runtime Environment)をそれぞれ開発・配布しているが、これ以外にも他社やオープンソースプロジェクトなどによって多種多様な開発・実行環境が提供されている。
エディションと用途
Javaには対象機種や用途ごとにライブラリやAPIの標準仕様のセットを定めた複数のエディションがあり、様々な規模や特性のシステムで使い分けられている。最も汎用性が高く一般的な環境向けはJava SE(Standard Edition)で、パソコン上のデスクトップアプリケーションの開発などに用いることができる。
企業の情報システム向けにはJava EE(Enterprise Edition)が提供され、サーバ上で実行されるWebアプリケーションなどの開発に適した機能が用意されている。組み込みシステム向けにはJava ME(Micro Edition)があり、デジタル家電や携帯情報機器などに組み込まれる特定用途の小型コンピュータシステムの開発が可能となっている。
バイトコードと仮想マシン
Javaで記述されたソースコードは、コンパイル時にJavaバイトコードと呼ばれる中間コードにいったん変換される。ソフトウェアはバイトコードの状態で配布され、実行時にはJava仮想マシン(JVM)と呼ばれるソフトウェアによって、実行するプラットフォームに対応した実行可能形式(ネイティブコード)に変換され、実行される。
機種やOSごとの仕様の違いは仮想マシンが吸収するため、開発時にはプラットフォームの違いを意識しなくてよい。ただし、コードの実行そのものにかかる負荷に加えてネイティブコードへの変換のために処理時間やメモリ領域を必要とするため、実行速度やメモリ容量に厳しい要件がある用途では注意が必要となる。
JVM言語
Java仮想マシン(JVM)およびJavaバイトコードの仕様はJava言語自体の仕様とは独立しており、また仕様は公開されているため、Java以外の言語からJVMのバイトコードへ変換(コンパイル)して実行形式のファイルを得ることもできる。
そのようなJVMによる実行方式を前提に開発されたプログラミング言語や言語処理系のことをJVM言語と総称する。単体の言語としてはScalaやGroovy、Kotlin、Clojureなどが有名で、既存の言語をJVM言語化する言語処理系としてはRubyを利用するJRubyやPythonを利用するJythonがよく知られる。
C++言語
広く普及しているオブジェクト指向型の高水準プログラミング言語の一つで、C言語を拡張したもの。ハードウェア制御やオペレーティングシステム(OS)の一部など、システムに深く根ざしたプログラムの開発に用いられる。
Cにオブジェクト指向関連の仕様などを追加したもので、Cの仕様を引き継いだ上位互換となっており、ほとんどのCプログラムはそのままC++プログラムとしても有効である。高度で抽象的な機能と低水準(ハードウェア寄り)な機能を兼ね備えた汎用的なプログラミング言語として、様々な用途で広く普及している。
Cにはない要素として、クラスの定義や継承などのオブジェクト指向プログラミングのための要素や、関数や演算子のオーバーロード(多重定義)、テンプレート、仮想関数、例外処理、名前空間などが追加されている。プログラムの部品化や再利用がしやすく、複雑・大規模なプログラムを開発するのに向いている。一方で、仕様が肥大化・複雑化しすぎ、プログラムが難解になっているとの批判もある。
Cと同じように、記述したプログラムはコンパイラと呼ばれるソフトウェアによって機械語のプログラムに変換されて実行される。様々なCPUやオペレーティングシステム(OS)向けの開発環境で標準的にC++コンパイラが提供されており、最も対応環境が多い言語の一つとなっている。
C++言語は1983年にAT&T社ベル研究所(当時)のビャーネ・ストロヴストルップ(Bjarne Stroustrup)氏が考案したもので、1998年にISO/IEC 14882として標準化された。日本でも2003年にISO標準を和訳したものをJIS規格(日本工業規格)の一部として標準化している。ISO標準は何度か改訂されており、俗にそれぞれの制定年を取って「C++98」「C++03」「C++11」「C++14」「C++17」「C++20」「C++23」などと呼ばれることもある。
「C++」という名称の由来は、C言語に存在する算術演算子の一つで、整数型の変数の値に1を加えるインクリメント演算子「++」から。Cの仕様を引き継いで機能を拡張した言語は他にもあり、C++と同じくオブジェクト指向的な拡張を施した「Objective-C」が有名である。
Go言語
米グーグル(Google)社が開発・公開しているプログラミング言語の一つ。従来のC++言語の用途の一部を置き換えることを想定し、コードの記述の簡潔さや理解しやすさと、プログラム実行の高速性やリソース利用の効率性の両立を目指している。主要な処理系はオープンソースとして公開されている。
基本的な文法や記法はC言語やJavaに近く、大規模開発にも適用しやすいよう静的型付けとなっているが、スクリプト言語のように短い記述で目的を達するよう配慮されている。Cのようなメモリ破壊やメモリリークが起きないよう言語レベルでメモリの安全性が確保され、実行時にはガーベジコレクションが行われる。
標準の言語処理系はコンパイラで、オペレーティングシステム(OS)上で直接実行できるネイティブコードに変換してから実行する。実行環境に仮想マシンなどをあらかじめ用意する必要はない。コンパイル速度を重視しており、Goコンパイラは一般的なC/C++コンパイラよりはるかに高速である。開発効率と実行速度の高いレベルの両立を目指している。
「Goroutine」(ゴルーチン)という並行処理のための仕組みが整備されており、実行時に極めて軽量なスレッド(プログラム実行の流れ)を生成し、複数のCPUコアをフル活用して効率的に並行処理ができるようになっている。強力なコンピュータで動作するサーバソフトウェアを開発する場合などに有用である。
標準ライブラリの機能を充実させ開発者が自前で記述しなければならないコードを極力減らす一方、現代的なプログラミング言語の多くに共通する機能の一部をあえて採用しない方針を取っている。これには例外処理、継承、ジェネリクス、アサーション、オーバーロード、暗黙の型変換などが含まれる。
Go言語はネットワークシステムやWebアプリケーションなどのサーバ側プログラム、システム上で直に動作するコマンドラインツールや常駐プログラム(デーモン)などの開発に適しているが、デスクトップアプリケーションやモバイルアプリを開発するためのパッケージなども公開されており様々な用途に使用することができる。
2007年頃からGoogle社内のソフトウェア開発を効率化するために設計が始められ、2009年に正式発表、2012年に標準処理系の初版が公開された。著名なソフトウェア開発者のロバート・グリーズマー(Robert Griesemer)、ロブ・パイク(Robert C. Pike)、ケン・トンプソン(Kenneth L. Thompson)の三氏が仕様策定を主導している。Linux、macOS、Windows、各種BSD系OSなどに対応しており、処理系はBSDライセンスに基づいてオープンソースとして公開されている。
スクリプト言語 【軽量言語】
プログラミング言語の一種で、オペレーティングシステム(OS)やアプリケーションソフトの動作や機能などをプログラムの形で記述できるもの。転じて、実行可能形式への変換作業などを省略・自動化したり、少ない記述量でも実行できるなど、仕様や開発手順が簡略化された言語の総称を表すこともある。
ソフトウェアの動作の自動化などを行なうプログラムを記述する言語は「マクロ言語」とも呼ばれ、手動で操作するには面倒な定型的あるいは反復的な処理を自動化したり、複数の機能を組み合わせて目的に沿った新しい機能を作り出すために使われる。ソフトウェアの機能の一部として提供され、そのソフトウェアの外では実行できないことが多い。
一方、汎用的なスクリプト言語は、ちょっとしたプログラムをすぐに記述・実行できるよう仕様を簡略化した言語で、明確な定義は無いが、以下のような特徴を持っていることが多い。
本格的なプログラミング言語の多くで要求される、使用するモジュールなどの宣言やプログラムの大枠の構造などの記述などを省略することができる。ただし、これらは仕様としては組み込まれ、本格的なプログラムを開発する場合などには必要になることもある。
また、人間が記述したソースコードを機械語など実行可能なプログラム形式へ変換(コンパイル)したり、ライブラリファイルを結合(リンク)するなどの手順を明示的な操作として行う必要がなく、記述したプログラムを即座に実行できるようになっている。ソースコードを読み込み、実行形式に変換しながら同時に実行する言語処理系を「インタプリタ」(interpreter)という。
特定のソフトウェア環境上で動作するスクリプト言語としては、Flashで用いられるActionScript(JavaScriptのFlash方言)、Microsoft Officeの各アプリケーションで用いられるVBA(Visual Basic for Applications)、UNIX系OSのシェル上で実行されるシェルスクリプト、macOSの操作を自動化するAppleScript、Webサーバで用いられるPHPやJSP、ASPなどがよく知られる。
汎用的に様々な環境や用途で用いられるスクリプト言語としてはPythonやRuby、Perlなどが有名である。JavaScriptのようにWebブラウザに対するマクロ言語のような用途として発明されながら、拡張や移植を重ねて汎用的な言語として様々な機能や実行環境を獲得した例もある。
ECMAScript
国際的な標準化団体のEcma International(エクマ・インターナショナル)が策定しているJavaScriptの標準規格。ECMA-262として規格書が発行されており、同様のものがISO/IEC 16262やJIS X 3060としても標準化されている。
一般にJavaScriptとしてよく知られるスクリプト言語について、基本的な記法や文法、式、宣言、関数、変数、データ型、コンテナ、組み込みオブジェクト、例外処理などの仕様を定めている。近年の拡張ではクラスやモジュール、非同期処理についても盛り込まれている。
環境に左右されない汎用的な言語のコア部分についての規格であるため、WebブラウザにおけるDOM操作や、特定のプロトコルによるネットワーク通信、ローカル環境でのファイル入出力と言った個別具体的な機能のAPIなどは標準化の対象外となっている。
JavaScriptやその派生言語(AltJS)、処理系の多くはECMAScript標準に独自の拡張やAPIを追加した構成となっている。独自仕様を用いずECMAScript仕様のみで記述したプログラム部品などは言語や処理系の種類を超えて横断的に動作する。
EcmaではECMAScriptの拡張仕様を本体とは別に標準化している。これまでに2004年にECMA-357として発行された「E4X」(ECMAScript for XML)、2012年にECMA-402として発行された国際化API(ECMAScript Internationalization API)、2013年にECMA-404として発行された「JSON」(JavaScript Object Notation)がある。
バージョンと表記
初版は1997年に発行された。当時、JavaScriptは多くのWebブラウザが標準で実装しているスクリプト言語として広く普及し、次第にブランザ以外にも利用が広まったが、開発元による仕様の差異が大きかったため、標準化団体による標準規格の策定を求める声が高まっていた。
これまでに何度も改定を重ね、複数の版(Edition:いわゆるバージョン番号に相当)が発行されている。現在では多くのJavaScript処理系や対応製品、JavaScript互換言語が「ECMAScript X準拠」(Xは版数や発行年)と、ECMAScriptへの対応水準を表明している。
2011年の5.1 Editionまでは版数で識別される(ECMAScript 1/2/3/5.0/5.1)が、2015年の6th Editionからは「ECMAScript 2015」(6th)、同2016(7th)、同2017(8th)、同2018(9th)、同2019(10th)、同2020(11th)のように発行年による表記・区別が一般化している。
Perl 【Practical Extraction and Report Language】
簡潔な記述や柔軟性、拡張性の高さが特徴のプログラミング言語の一つ。いわゆるスクリプト言語の草分けの一つで、UNIX系OSを中心に広く普及している。
基本的な文法や記法やC言語に似ているが、多様で自由度が高く、記号などを組み合わせた簡潔な記法が用意されている。言語仕様の一部に正規表現を取り込むなど、テキスト(文字)処理のための豊富な機能が用意されている。連想配列(ハッシュ)やリファレンス(変数などのメモリ上の位置を扱う機能)など高度な機能も標準で用意されている。
積極的に新しい機能を取り入れる開発姿勢でも知られ、オブジェクト指向プログラミングを可能にする拡張や、プログラムのモジュール(部品)化およびモジュールの読み込み機能、Unicodeなど多言語環境への対応、スレッド、クロージャ、リフレクション、ガベージコレクションなどが追加された。
Perlモジュールのオープンな集積場所(アーカイブ)として「CPAN」(Comprehensive Perl Archive Network)が用意されており、世界中の開発者がこれまでに開発した様々な機能のモジュールが公開されている。標準の開発ツールの一部としてCPANにアクセスしてモジュールを入手・導入するソフトウェアが提供されており、様々なモジュールを自分のプログラムの一部として取り込むことができる。
公式の言語処理系(「perl」と小文字で表記する)にはソースコードを読み込みながら同時に実行するインタプリタが含まれ、コンパイルやビルドなど手間や時間のかかる作業を省略して記述したプログラムを即座に実行してみることができる。
この処理系はオープンソースソフトウェアとして公開されており、誰でも自由に入手、利用、改変、再配布などすることができる。当初はUNIX系OS向けに開発されていたが、人気の高まりとともにWindowsなど数多くの環境に移植され、様々な機種やオペレーティングシステム(OS)で利用可能となっている。
Perlの最初のバージョンは1987年にラリー・ウォール(Larry Wall)氏が発表したもので、UNIXでの簡易なテキスト処理プログラムやシステム管理プログラムを開発する言語として人気を博した。インターネットが普及し始めると、Webサーバで動的にプログラムを実行して結果をWebページとして送信するCGI(Common Gateway Interface)の開発言語として広く普及した。
PHP 【PHP : Hypertext Preprocessor】
Webサーバの機能を拡張し、動的にWebページを生成するために用いられるプログラミング言語の一つ。いわゆるスクリプト言語あるいは軽量言語(LL:Lightweight Language)の一つで、実行環境をWebサーバに組み込んで利用されることが多い。
C言語やJava、Perlの影響を受けた記法や構文を採用した手続き型のプログラミング言語で、平易な仕様で学習しやすく、簡潔な記述でプログラムを開発することができる。
クラスを用いたオブジェクト指向や例外処理などに対応しているほか、標準で外部のデータベースシステム(DBMS)へ接続する機能が提供され、データベースと連携したWebアプリケーションを容易に開発することができる。
実行方式
大きな特徴の一つとして、HTMLファイルの雛形(テンプレート)の中に特殊な記法を用いてサーバ側で実行するプログラムコードを埋め込む形で記述することができる。
このファイルへのアクセス要求があると、WebサーバはPHP側のコードを実行し、実行結果を雛形のHTMLコード中の所定の場所に埋め込んで閲覧者へ送信する。このような仕組みはASP(Active Server Pages)/ASP.NETやJSP(Java Server Pages)などでも採用されている。
PHPの実行環境はWebサーバソフトの拡張モジュールなどとして組み込んで利用されるのが一般的で、CGI/FastCGIやサーバ固有のAPI(ISAPIなど)を通じて起動される。Apache HTTP ServerやMicrosoft Internet Information Services(IIS)など主要なWebサーバの多くに標準で対応しており、PHPで開発されたアプリケーションは様々な環境で同じように稼動させることができる。
フレームワークの利用
PHPによるWebアプリケーションの開発はゼロから独自に行われることもあるが、多くは「フレームワーク」と呼ばれる骨組みを用いて行われる。アプリケーションの基本的な骨格や雛形を汎用的な形にまとめたもので、少ないコード記述で迅速に開発を進めることができる。
多くのフレームワークがオープンソースとして公開されており、長年に渡り開発され続けている著名なものだけでも「Zend Framework」「Laravel」「CakePHP」「CodeIgniter」「Symfony」「FuelPHP」などの種類がある。
パッケージの利用
PHPで記述したプログラムをパッケージとして部品化したり、外部のパッケージを取り込んで利用する機能があり、インターネット上には世界中のボランティア開発者が公開している汎用的なパッケージを集積した「PEAR」(PHP Extension and Application Repository)と呼ばれるサイトが存在する。
標準の開発ツールにはPEARにアクセスしてパッケージを入手・導入するソフトウェアが添付されており、必要な機能を提供するパッケージを取り込んで自分のプログラムに組み込んで利用することができる。また、C言語で開発された拡張モジュールを公開している「PECL」(PHP Extension Community Library)というサービスもある。
歴史
PHPの最初のバージョンは1995年にラスマス・ラードフ(Rasmus Lerdorf)氏によって公開された。PHPという名称は「Personal Home Page Tools」の略とされたが、1998年のPHP 3.0からは「PHP: Hypertext Preprocessor」という表記が用いられている。
公式の処理系は米ゼンド・テクノロジーズ(Zend Technologies)社が開発している「Zend Engine」(ゼンドエンジン)で、オープンソースソフトウェアとして公開されており、誰でも自由に入手、利用、改変、再配布などすることができる。
Python
簡潔で読みやすい文法が特徴的な汎用の高水準プログラミング言語の一つ。いわゆるスクリプト言語の草分けの一つで、UNIX系OSを中心に広く普及している。近年では初学者向けの学習用途、統計処理やAI関連のプログラム記述用途として用いられることも多い。
基本的な特徴としては、豊富なデータ型とコンテナ型、ガベージコレクション、Unicodeによる多言語対応、プログラムのモジュール(部品)化による他のプログラムへの容易な組み込み、プログラムの仕様の文書化(ドキュメンテーション)を支援する機能などがある。
ユニークな特徴としては、多くの言語では人間にとってプログラムを読みやすくするために便宜的に行われるインデント(字下げ)を言語仕様上の構文の一つとして採用しており、ブロックの範囲を示すのに用いられる。
言語自体の文法や語彙、記法な最小限のシンプルなものに抑えられているが、対照的に、極めて広範囲の分野に渡り豊富な機能を提供する標準ライブラリが用意されている。当初は手続き型言語とオブジェクト指向言語の特徴を備えた言語として設計されたが、関数型言語の要素の多くを取り入れ、様々なスタイルのプログラミングが可能なマルチパラダイム言語として知られている。
他の言語や環境との連携機能も充実しており、Pythonからアクセスできない低レベルの機能をC言語で記述して拡張モジュールとして組み入れる仕組みが提供されているほか、Javaライブラリを利用できる実行環境の「Jython」や、Microsoft .NET環境で.NET Frameworkの機能を利用できる「IronPython」などの処理系もある。
標準の言語処理系(CPython)にはソースコードを読み込みながら同時に実行するインタプリタが含まれ、コンパイルやビルドなど手間や時間のかかる作業を省略して記述したプログラムを即座に実行してみることができる。この処理系はオープンソースソフトウェアとして公開されており、誰でも自由に入手、利用、改変、再配布などすることができる。
Pythonの最初のバージョンは1991年にオランダのグイド・ヴァン・ロッサム(Guido van Rossum)氏によって発表された。現在ではWebアプリケーションの開発用言語として人気が高いほか、データ処理や統計解析などの分野でよく利用されることで知られる。
Ruby
まつもとゆきひろ(Matz)氏が開発を創始した著名なオブジェクト指向プログラミング言語。主な処理系(実行環境)としてソースコードをそのまま実行に移せるインタプリタを採用したスクリプト言語の一種である。
プログラムの書きやすさや読みやすさを重視し、シンプルで洗練された構文や記法を基本としている。既存の様々な言語の要素を取り込み、実用的な用途にも十分使用できる利便性を備えている。
スクリプト言語ながら、クラス定義やMixin、値をすべてオブジェクトとして扱うなどの仕様を備えた本格的なオブジェクト指向言語となっており、プログラムの部品化(モジュール化)や再利用、大規模ソフトウェアの開発などにも適用可能となっている。
他にも、正規表現などテキスト処理が充実しているほか、例外処理、演算子のオーバーロード、クロージャ、イテレータ、ガベージコレクション、マルチスレッドなど豊富な機能や仕様を備えている。
初期には先行するスクリプト言語のPerl(パール)を意識して開発されていたこともあり、UNIX系OSでのシステム管理用スクリプトなどの開発に用いられることが多かったが、21世紀に入るとWebサーバ上で動作するWebアプリケーションの主要開発言語として脚光を浴びた。
特に、Rubyをベースに最小限のコード記述で迅速にデータベース連動Webアプリケーションを開発できる「Ruby on Rails」(ルビーオンレイルズ)は実用的なフレームワークとして広く普及し、後続のWebアプリケーションフレームワークにも多大な影響を与えた。
開発は1995年に始まり、言語仕様は2011年にJIS X 3017としてJIS規格となったほか、2012年にISO/IEC 30170として国際標準化されている。MRI(Matz' Ruby Implementation)やYARV(Yet Another Ruby VM)といった公式の処理系はオープンソースソフトウェアとして公開されている。Javaで実装されたJRuby、.NET Framework向けのIronRuby、macOS向けのMacRuby、組み込みシステム向けのmrubyなど多様な処理系が公開されている。
CLR 【Common Language Runtime】
米マイクロソフト(Microsoft)社がWindowsのプログラム実行環境などとして推進している.NET(ドットネット)で、対応プログラムを実行するための動作環境のこと。同社の.NET Frameworkなどが該当する。
.NET対応のソフトウェアは、様々なプログラミング言語で書かれたソースコードから、いったん共通中間言語(CIL:Common Intermediate Language)による形式に変換されて利用者のもとに配布される。CILのみで構成され、特定の機種やOSなどに依存するコードを含まないプログラムを「マネージドコード」(managed code)という。
CIL形式のプログラムを解釈し、コンピュータが直に実行可能な機械語によるプログラムに変換して実行するソフトウェアが共通言語基盤である。利用者は自らのコンピュータやOSに対応した共通言語基盤を用意しておけば、.NET向けソフトウェアを利用することができる。
共通言語基盤は一種の仮想マシン(VM:Virtual Machine)を中核とするシステムで、CILプログラムを実行時コンパイル(JITコンパイル)して起動する。例外処理、ガーベジコレクション、スレッド管理などの機能を提供する。通常は.NETの標準クラスライブラリ(BCL:Base Class Library)やアプリケーションフレームワーク(ASP.NETやWPFなど)と同梱されて.NETの実装として提供される。
CLI (Common Language Infrastructure/共通言語基盤)
米マイクロソフト(Microsoft)社が推進する.NETの実行環境(CLR)および対応プログラムの記述言語(CIL)の標準仕様を定めた規格。同社による実装を.NET Frameworkという。
機種やOSに依存しないプログラムの開発・実行環境を実装するために必要な諸技術の仕様を定めている。.NETプログラムの配布形式であるCIL(Common Intermediate Language/共通中間言語/MSIL/IL)の仕様と、開発に用いるプログラミング言語に求められる共通仕様、実行環境(CLR)が実装すべき仕様を定めている。
.NET対応プログラミング言語間で共通して利用されるデータ型の仕様を定めたCTS(Common Type System/共通型システム)、実行プログラム内にコードについての情報を埋め込むメタデータの形式、対応プログラミング言語に要求される共通仕様CLS(Common Language Specification/共通言語仕様)、CILプログラムをネイティブコードに変換して実行するVES(Virtual Execution System/仮想実行システム)の仕様などが含まれる。
共通言語基盤規格は同社が提出した標準案をもとに2001年に当時のEMCA(現Ecma International)によってEMCA-335として標準化され、2003年に同様の内容がISO/IEC 23271として国際標準となった。日本では2006年に同規格を翻訳したJIS X 3016が策定されている。
マークアップ言語
文書の本文中に構造や見栄えなどを指定するデータを埋め込む形で記述することができる人工言語。テキストデータにタグを埋め込むHTMLやXMLがよく知られているが、バイナリデータに埋め込む言語など様々な種類がある。
ソフトウェアにとって単純なテキストデータは文字が端から端まで一列に並んだデータに過ぎないが、マークアップ言語を用いることで、見出しや段落を設けたり、文字色などの見栄えを指定する制御情報を埋め込むことができ、構造的な文書データとすることができる。
データ中に特定の記法で埋め込まれた制御データを「マークアップ」(markup)という。テキストエディタなどを用いて人間が表示・編集することができ、専用のソフトウェアを用いて整形済みの状態を表示したり、その状態のまま編集できるもの(WYSIWYGエディタ)もある。
HTMLやTeX、Markdown、Wiki記法のように文書を構成するためのマークアップ言語が有名だが、画像データやソフトウェアの設定ファイルなどへの応用例もある。また、SGMLやXMLのように、特定の対象や用途に特化したマークアップ言語を作り出すための汎用の言語もあり、ベクター画像を記述するSVGのように、XMLから派生した特定用途のマークアップ言語は数多く存在する。
言語によって構文や記法、指定できる内容などは異なっている。例えば、文書中に見出しを設定するには、HTMLでは「<h1>見出し</h1>」のように、TeXでは「\section{見出し}」、MarkDownやWiki記法では「# 見出し」のように記述する。HTMLやXMLで用いられる、「<」と「>」で囲まれた標識を「タグ」(tag)という。
HTML 【HyperText Markup Language】
Webページを記述するためのマークアップ言語。文書の論理構造や表示の仕方などを記述することができる。Webブラウザは標準でHTML文書の解釈・表示が行える。
HTMLでは、文書の一部を“<”と“>”で挟まれた「タグ」と呼ばれる特別な文字列で囲うことにより、文章の構造や修飾についての情報を文書に埋め込んで記述することができる。例えば、HTMLファイル中で <br> と書かれた場所はブラウザなどにおける表示では改行が行われ、<h1>HTMLの概要</h1> のように括られた箇所は大見出しとみなされ(通常の設定では)上下の要素から少し離れた独立した行に大きくて太い文字で表示される。
様々な機能や意味を持つタグが定義されており、文章の中で表題や見出し、段落の区切りを指定したり、箇条書きの項目を列挙したり、縦横に項目が並んだ表を定義したり、文書の一部として画像や音声、動画を埋め込んだり、他の文書へのハイパーリンクを設定したりすることができる。
HTML文書の構造
典型的な構造のHTMLは冒頭にHTMLのバージョンなどを示すDOCTYPE宣言があり、以下ページ全体がhtml要素(htmlタグで括られた領域)となる。
html要素内にはhead要素とbody要素に分かれ、head要素には文書についての情報が記述される。ページタイトルや言語、文字コード、他の文書との繋がり、読み込むスタイルファイルやスクリプトファイルなどを指定する。body要素が表示されるページの本体で、具体的な内容が記述される。
他の言語の混在
他の言語による記述をHTML要素として文書中に記述することができる。例えば、CSS(カスケーディングスタイルシート)による要素の見栄えの記述を文書中にまとめて記したい場合は<style>と</style>で括られた領域に記述することができる。
また、<script>と</script>で囲った領域にはJavaScriptという簡易なプログラミング言語を用いてスクリプトを記述することができ、ページがブラウザなどに表示された後に実行される。
これら別の言語による記述はHTMLタグ中の属性(style属性やonclick属性)の値として記述することもできる。
歴史
HTMLは元々SGML(Standard Generalized Markup Language)の簡易版として生まれ、最初の標準規格は1993年にIETFによって発行された。1994年にW3Cが設立され、以降の改訂はW3Cが担当している。
当初は主に文章の論理構造を記述する言語だったが、Webの普及が進むにつれて要素の見栄えに関する仕様がブラウザメーカー主導で相次いで追加されていった。その後、表示の仕方を記述する専用のスタイル言語としてCSS(Cascading Style Sheet)が考案され、文書の論理的な構造の記述をHTMLに、見栄えの記述をCSSに分離すべきとされるようになった。
2000年前後には汎用的なマークアップ言語であるXML(Extensible Markup Language)に準拠するよう一部の仕様を改めたXHTMLへの移行が企図されたが普及せず、以後も独立した規格として維持されている。
開始タグ
HTMLやXMLなどのマークアップ言語で、文書内の要素を括るタグのうち開始側のもの。「<div id="section1">」といったように先頭にタグ名、続いて属性を記述する。
Webページなどの記述に使われるHTMLやXMLなどのマークアップ言語では、元になる文書に「<」と「>」で囲まれた標識を埋め込むことにより、表示ソフトに対して文書構造や書式、文字飾りなどを指示したり、画像や他の文書へのリンクを埋め込むことができるようになっている。
この標識のことを「タグ」(tag)と呼び、対になる二つのタグで文書内の部分を挟むことで、その部分についての情報を埋め込むことができる。要素の開始を宣言する先頭側のタグを「開始タグ」、要素の終了を宣言する末尾側にあるタグを「終了タグ」という。
開始タグは「<」(大なり記号)に続けて「a」「div」「span」などの要素名(タグ名)で始まり、空白を挟んで「href="#section1"」といった形式で属性を記述する。属性は空白で区切って複数記述することができ、タグの末尾は「>」(小なり記号)で閉める。
「<p>」のように属性を記述せずタグ名のみとする場合もある。「</タグ名>」という形式の終了タグとセットで記述され、挟まれた部分が要素を構成するが、hr要素など文書の一部を指定する必要のないタグは終了タグが存在せず、「<hr>」のように開始タグのみで要素を構成する。XMLやXHTMLでは終了タグのない単体のタグは「<br />」のように「/>」で閉じるルールがあるが、HTMLには開始タグと同じように書けばよい。
終了タグ
HTMLやXMLなどのマークアップ言語で、文書内の要素を括るタグのうち終了側のもの。「</div;>」といったように「/」(スラッシュ)に続けてタグ名を記述する。
Webページなどの記述に使われるHTMLやXMLなどのマークアップ言語では、元になる文書に「<」と「>」で囲まれた標識を埋め込むことにより、表示ソフトに対して文書構造や書式、文字飾りなどを指示したり、画像や他の文書へのリンクを埋め込むことができるようになっている。
この標識のことを「タグ」(tag)と呼び、対になる二つのタグで文書内の部分を挟むことで、その部分についての情報を埋め込むことができる。要素の開始を宣言する先頭側のタグを「開始タグ」、要素の終了を宣言する末尾側にあるタグを「終了タグ」という。
終了タグは「<」(大なり記号)に続けて「/」(スラッシュ)、タグ名が続き、「>」(小なり記号)で閉める。要素の終了を示すことのみが目的であるため、開始タグのように属性など追加の情報を記述することはない。
終了タグは開始タグとセットで用いられ、挟まれた部分が要素を構成するが、hr要素など文書の一部を指定する必要のないタグは終了タグが存在せず、「<hr>」のように開始タグのみで要素を構成する。XMLやXHTMLでは終了タグタグのない単体のタグは「<br />」のように「/>」で閉じるルールがあるが、HTMLには開始タグと同じように書けばよい。
DTD 【Document Type Definition】
SGMLやXML、HTMLなどのマークアップ言語で記述された文書の冒頭などに記載される、その文書で用いる要素などを定義した部分。また、そのような宣言文を記述するための記法や文法を定めた言語(スキーマ言語)の一つ。
その文書の中に用いることができる要素(タグ)や、要素が持つことのできる属性、要素間の順序・包含関係などの規則を列挙したもので、ソフトウェアが文書を処理する際にDTDを参照し、文書内の要素が適切に記述されているかを検証することができる。
DTDは文書自体の冒頭に記述する場合と、冒頭にDTDを記述した外部ファイルへの参照(リンク)を記述し、ソフトウェアに読み込ませる場合がある。後者は「DOCTYPE宣言」とも呼ばれ、言語の規格発行元などがインターネットで公開しているDTDのURLなどを記載することが多い。
DTDはSGMLで規定されたもので、SGMLから派生したXMLやHTMLでも用いられてきたが、XMLではDTDに代えて他のスキーマ言語(RELAXやXML Schemaなど)を用いることが増えた。HTML5ではDTDによる文書型定義は廃止され、現在は用いられていない。
SGML 【Standard Generalized Markup Language】
文書の構造やデータの意味などを記述するマークアップ言語を定義することができるメタ言語の一つ。現代ではほとんど使われていないが、Webページを記述するHTMLを生み出す元になった言語としてよく知られる。
文書を文字(テキスト)形式で記述し、本文中に「<」と「>」で囲まれた「タグ」(tag)と呼ばれる文字列を埋め込むことで文書の構造やデータの意味などを記述する。このような本文中に制御データを埋め込む記述方式を「マークアップ」(markup)という。
例えば、文書中に「SGML入門 1500円」と書かれているだけでは、コンピュータはそれが何の情報か、要素間にどういう関係があるのか判断できないが、「<item type="book"><title>SGML入門</title><price>1500円</price></item>」のようにマークアップしてあれば、これらが書名と価格であると判断して処理に反映させることができる。
メタ言語としてのSGML
タグにどのような種類があり、それぞれどんな属性を持つのかなどといった仕様は「DTD」(Document Type Definition:文書型定義)というテキスト形式のデータで記述する。DTDは「スキーマ言語」というSGML自体とは別の記法・構造を持つ専用の言語で記述する。
DTDが違えばタグの種類も違うため、DTDが異なる文書は同じSGMLで記述されていても別のマークアップ言語で記述された文書のようになる。つまり、SGMLはそれ自体が特定の目的や文書形式のためのマークアップ言語なわけではなく、特定用途のマークアップ言語を定義することができる「メタ言語」(言語のための言語)であると言える。
構造と見栄えの分離
文書の表示の仕方は「スタイルシート言語」と呼ばれる言語で文書本体とは別に定義することで、文書の構造の記述と見栄えの記述を分離している。標準規格として「DSSSL」(Document Style Semantics and Specification Language)という言語が定められている。
出力先によってスタイルシートを切り替えることで、同じ文書でもそれぞれに適した見栄えに整形することができる。例えば、ソフトウェアで画面上に表示する場合と、ページ単位で区切って印刷する場合に、文書本体を編集しなくてもそれぞれ読みやすい見た目に整形できる。この仕組みを応用して、元になるSGMLデータからWebページやPDF文書など別の形式に変換するシステムも提供されている。
歴史
1979年、特定のソフトウェアやデータ形式に依存せずに文書の電子化やコンピュータ上での管理を行うために、米IBM社が原型となる「GML」(Generalized Markup Language)を考案した。これを元に、1986年に国際標準化機構(ISO)が「SGML」の名称でISO 8879として仕様を標準化した。
初期にはIBM社の社内文書の電子管理や、米軍で航空機マニュアルの電子化を行う際の標準データ形式として採用された。その後、大量の文書の作成・管理に悩む各国の軍や公的機関、研究機関、防衛産業、航空機産業、製薬産業などが文書管理の電子化を進めるために導入した。
Webページを記述するマークアップ言語である「HTML」(Hypertext Markup Language)は、当初はSGMLで定義されたマークアップ言語の一つだった。後に、SGMLの複雑で巨大な仕様を簡略化し、処理の困難な部分を改善したメタ言語として「XML」(Extensible Markup Language)が考案され、現在ではSGMLが構想していた用途にはXMLを用いるのが一般的となっている。
XML 【Extensible Markup Language】
文書やデータの意味や構造を記述するためのマークアップ言語の一つ。汎用性、拡張性が高く、用途に応じて独自のマークアップ言語を定義することができる。
マークアップ言語とは「タグ」(tag)と呼ばれる特定の記法の文字列で地の文に情報の意味や構造、装飾などを埋め込んでいく人工言語のことで、XMLは利用者が独自のタグを定義できることから、マークアップ言語を作成するためのメタ言語とも言われる。
XMLの表記法
XMLにおけるタグはHTMLやSGMLなどと同じように「<」(小なり記号)と「>」(大なり記号)に囲まれた文字列で、「<」に続く先頭部分が要素名(タグ名)を表し、続いてスペース区切りで属性が「 属性名="値"」という形式で列挙される。
タグには「<要素名>」という形式の開始タグと「</要素名>」という形式の終了タグがあり、両者に挟まれた領域が要素の内容(タグによる指定の有効範囲)となる。内容を含まず単体で完結したタグもあり、「<要素名 属性群 />」のようにタグの末尾を「/」とする。
用途と関連規格
XMLにより統一的な記法を用いながら独自の意味や構造を持ったマークアップ言語を作成することができるため、ソフトウェア間の通信・情報交換に用いるデータ形式や、様々な種類のデータを保存するためのファイルフォーマットなどの定義に使われている。
XMLを応用して特定の種類やデータや用途のために定義された標準的なマークアップ言語もある。ベクター画像を記述するための「SVG」(Scalable Vector Graphics)、数式を記述するための「MathML」、Webページを記述するHTMLをXMLの仕様を満たす形式に改めた「XHTML」、各種のオフィスソフトの文書を記述するための「Office Open XML」および「ODF」(OpenDocument Format)などである。
また、XMLを様々な場面で利用しやすいよう、関連技術の規格も数多く存在する。文書を表示する際の書式や装飾などを指定する「XSL」(Extensible Stylesheet Language」や「XSLT」(XSL Transformations)、ハイパーリンク機能を実現する「XLink」や「XPointer」、XMLベースの言語の仕様を記述するためのスキーマ言語である「XML Schema」や「RELAX」、XMLをプログラムで利用するためのAPIである「DOM」(Document Object Model)や「SAX」(Simple API for XML)などである。
DOM 【Document Object Model】
XML文書やHTML文書を構成する要素をコンピュータプログラムで参照したり操作したりするための仕組み。また、文書の構成要素を木構造(ツリー構造)で表したデータモデル。
HTMLやXMLで記述されたWebページなどの構成要素(見出し、段落、領域、画像、リンクなど)を木構造のモデルで表し、それらの配置や見栄えなどを定めた属性情報などを参照、操作する手法を定めている。
Webブラウザなどに実装されており、ページ上にJavaScriptなどで記述されたスクリプトからページ内の各要素を読み取ったり、内容や設定の変更、要素の追加や削除などを行う標準的な手段として用いられる。
文書をDOMで表したデータは、文書の最上位の要素を頂点として、各要素が包含関係に従って枝分かれしていく木構造(ツリー構造)となっている。これを「DOMツリー」(DOM tree)と呼び、元の文書における各要素を「ノード」(node)という。
DOMはWeb標準を策定する業界団体WHATWG(Web Hypertext Application Technology Working Group)が「DOM Living Standard」という随時更新される規格として発表している。2019年以前はW3C(WWW Consortium)が「DOM Level 1」から「DOM Level 3」までの標準規格を発行していた。
SOAP 【Simple Object Access Protocol】
ネットワーク上でWebサービス間やサーバとクライアントがメッセージを交換しあって連携するためのプロトコル(通信規約)の一つ。メッセージの記述にXMLを、データ伝送に主にHTTPを用い、Webサービスの提供や利用に適している。
システム間で処理の依頼や応答、データの受け渡しを行うための仕様で、「XML-RPC」から発展した技術である。特定のシステムに固有の技術を用いず、Web標準を応用して構成されており、WindowsとLinuxなど様々な環境が混在していても相互運用性を確保することができる。
SOAPメッセージ/SOAPエンベロープ
SOAPで送受信されるXML形式のデータを「SOAPメッセージ」(SOAP message)という。SOAPメッセージであることを示すため一番外側を「エンベロープ」(envelope:封筒)と呼ばれるタグで覆った構造になっているため、「SOAPエンベロープ」とも呼ばれる。
エンベロープの内側には宛先などの制御情報を記述する「SOAPヘッダ」(SOAP header)、送受信したい内容本体が記述された「SOAPボディ」(SOAP body)が並んでいる。これをHTTPなどのプロトコルで送り合うことで、異なる種類のシステム間で処理要求や応答などを伝達することができる。
SOAP自身はXMLベースの規格でプロトコルには依存せず、適切なヘッダを付加することにより様々なプロトコルによる送受信が可能になっている。最も一般的なHTTP経由での場合は、通常のHTTPヘッダに加えて「SOAPAction」というヘッダを付加し、送り先のURLをHTTPヘッダに含められるようになっている。
SOAPヘッダ/SOAPボディ
SOAPメッセージ内で制御情報などを記述する冒頭部分を「SOAPヘッダ」(SOAP header)という。伝達内容の本体であるSOAPボディに記述した内容の宛先や認証情報、改竄防止のためのハッシュ値、セッションID、その他関連する属性情報が記述される。不要な場合は省略できる。
SOAPによって相手方のシステムへ渡される伝達内容そのものを記述した部分を「SOAPボディ」(SOAP body)という。具体的なデータや処理の依頼(リクエスト)や、それに対する応答内容(レスポンス)などが格納される。データ形式や内容はアプリケーションによって異なり、SOAP規格自体では関知しない。
関連仕様
SOAPで実装されたWebサービスの呼び出し方、引き渡すパラメータの種類やデータ型などのインターフェース情報は「WSDL」(Web Services Description Language)呼ばれるXMLベースの言語で記述され、サービスの利用者に公開される。
様々なWebサービスのWSDL文書を集め、どこでどのようなWebサービスが利用できるのかといった情報を収集して利用者が検索・発見できるようにしたデータベースもあり、「UDDI」(Universal Description, Discovery and Integration)と呼ばれる。
SOAPを基盤に、「WS-Addressing」や「WS-Security」「WS-Reliability」「WS-Routing」など、名称が「WS-」で始まる様々なプロトコルやメッセージ規格が機能や用途に応じて策定されており、これらを含めたSOAPベースの技術全体を指してSOAPという場合もある。
歴史
SOAPの仕様は1999年に米マイクロソフト(Microsoft)社などが発表したもので、2000年5月にW3Cが最初の標準規格を勧告した。2000年台前半には企業システムのWebサービス化と共に同社製品などの対応も進んだ。
しかし、WS-*プロトコル群などを含む巨大で複雑な仕様が次第に敬遠されるようになり、「REST」と呼ばれるシンプルな設計原則に則った軽量なWebサービスのAPI仕様「RESTful API」の方が好まれるようになった。現在では同社のWinRMがWS-Managementに対応している程度で、ほとんどのWeb APIはRESTful APIとして提供されている。
SVG 【Scalable Vector Graphics】
XMLの記法を用いて画像を図形の集合として表現する記述言語の一つ。ベクター形式の画像ファイル形式の一つでもあり、ファイルに保存する場合の標準の拡張子は「.svg」。
画像を画素(ピクセル)の集まりとして表現するビットマップ形式(ラスター形式)に対し、ベクター形式は画像を線や面などの図形の集合として表現する。ビットマップ画像のように写実的で細密な表現には向かないが、変形や合成が容易、拡大・縮小しても輪郭などが荒くならない(スケーラブルである)といった特徴がある。
主な仕様
SVGは汎用のマークアップ言語であるXML(Extensible Markup Language)を応用した言語の一つで、テキストデータとして図形を記述する。HTMLなどと同じように山括弧「<」「>」(正確には半角の大なり記号と小なり記号)で囲まれた「タグ」(tag)と呼ばれる表記法を用いてデータを記述していく。
図形描画のための要素として、直線(line)、矩形(rect)、円(circle)、楕円(ecllipse)、多角形(polygon)、折れ線(polyline)などが用意されているほか、パス(path)要素を用いて任意の曲線(ベジェ曲線)を描くこともできる。位置やサイズの指定は平面座標系で行われるため、3次元コンピュータグラフィックス(3DCG)の記述・描画を行うには座標変換などの処理を別に行う必要がある。
色やグラデーションの指定、文字の配置、光源の設定、様々な画像効果を加えるフィルタ、要素の拡大・縮小・回転・変形、アニメーションなどに関する要素も利用できる。画像の一部として外部のSVGデータを呼び出して合成したり、ビットマップ画像と重ね合わせを行うためのレイヤー機能も盛り込まれている。
SVGの利用
SVGは単体の画像ファイルとして用いる場合の他に、XML文書やHTML文書の一部として記述する場合もある。Webブラウザなど閲覧するソフトウェアが対応していれば、文書内の要素の一つとして他の要素と同じように埋め込まれて表示される。
HTMLファイルからは、JPEGやPNGのようなビットマップ画像と同じようにimg要素で外部のSVGファイルを呼び出して埋め込み表示するか、svg要素で直にHTML中に記述することもできる。近年ではWebページ上でグラフやイラスト、アイコン、ロゴ、図形などを表示したい場合によく用いられる。
SVGの歴史
1990年代末、Webが一般に広く普及すると、Webページ上で図形描画を行いたいというニーズが高まり、米アドビ(Adobe)社などの企業連合が「PGML」(Precision Graphics Markup Language)を、米マイクロソフト(Microsoft)社などの企業連合が「VML」(Vector Markup Language)をそれぞれ提唱した。
標準化団体のW3Cでは両案を含む6件のベクター画像仕様を検討の上、新たな記述言語としてSVGを開発した。初版の草案(ドラフト)は1999年に公表され、2001年に正式に勧告されたが、当時最大シェアのInternet Explorerが標準で対応せず表示にプラグインなどを必要としたこともあり、当初はあまり普及しなかった。
2010年代になるとGoogle ChromeやMozilla Firefox、Apple Safariなどが標準対応するようになり、SVG活用の機運が高まった。2008年にはSVG Tiny 1.2、2011年にはSVG 1.1第2版(初版の誤記修正版)、2018年にはSVG 2がそれぞれ公表されている。2012年にはW3CのSVG Tiny 1.2を邦訳した「JIS X 4197:2012 変倍ベクタグラフィックス SVG Tiny 1.2」がJIS規格となった。
SAX 【Simple API for XML】
ソフトウェアからXML文書を利用するためのAPIの標準仕様の一つ。アプリケーションとXMLパーサの間の機能の呼び出し手順などを定めている。Java向けに開発されたが他の言語でも利用されている。
XML文書の内容に応じて開発者の規定した操作を呼び出すイベント駆動型のAPIとなっている。XMLパーサはXML文書を先頭から一行ずつ順に読んでいき、要素が現れる度に対応する操作を呼び出して処理を実行する。
XMLにおける標準的なAPIにはWebブラウザなどで馴染み深い「DOM」(Document Object Model)も広く知られている。DOMがXML文書全体を読み込んでツリー構造に変換するのに対し、SAXは読み込みながら必要な処理を随時呼び出す形で処理を進める。
DOMに比べると限られたメモリ容量で軽快に動作し、処理の並列化なども行いやすいとされる。一方、文書の構造をたどって任意の位置の要素を対象に操作を行うといった処理は苦手であり、DOMの方が適しているとされる。
XML Schema 【XSD】
XML文書の構造を定義するスキーマ言語の一つで、Web技術の標準化を進めるW3C(World Wide Web Consortium)が勧告したもの。XML自体を用いてスキーマを記述する。
XML(Extensible Markup Language)はSGMLなどと同じ「マークアップ言語を作ることができるマークアップ言語」(メタ言語)であり、要素名や属性名、属性値などの体系を作成することにより、具体的な対象や目的のための独自のマークアップ言語やファイル形式を作成することができる。
元になるマークアップ言語の記法や文法を用いて応用言語を定義する枠組みを「スキーマ」(schema)と呼び、スキーマ言語を用いて定義される。例えば、SGMLを用いてHTMLを定義したときには、スキーマ言語としてDTD(Document Type Definition)が使われた。
XML SchemaはXMLのためのスキーマ言語として開発されたもので、主にDTDの欠点の克服を企図した仕様となっている。XML Schema自身がXML文法に従って記述される(DTDはSGMLとは全く異なる記法を用いる)ため、新たに構文規則を習得する必要がなく、XMLの解釈や処理のためのプログラムを使い回すことができる。
また、DTDにはない属性値のデータ型の指定が可能になったほか、名前空間(ネームスペース)に対応し、複数の異なるマークアップ言語を同じ文書内で共存させ、要素ごとに言語を切り替えて用いることができる。
XML Schemaの仕様は米マイクロソフト(Microsoft)社の「XML Data」や、米コマースワン(Commerce One/当時)社の「SOX」(Schema for Object-Oriented XML)などの提案が元になっており、2001年にW3Cが最初の標準を勧告した。
2012年のバージョン1.1からはXML向けスキーマ言語の総称との紛らわしさを解消するため「XML Schema Definition Language」(略称XSD)と呼ばれるようになった。XML向けのスキーマ言語には他にもDTDやRELAX NGなどの有力な選択肢がある。
XHTML 【Extensible HyperText Markup Language】
Webページの記述などに用いられるマークアップ言語であるHTML(HyperText Markup Language)をXMLの仕様に従って定義しなおした規格。W3C(World Wide Web Consortium)によって標準化された。
HTMLもXMLも汎用のマークアップ言語「SGML」(Standard Generalized Markup Language)から派生した言語だが、それぞれ異なる歴史的経緯から考案されたもので、HTMLの記法・仕様はXMLと整合していなかった。
そこで、HTMLをXMLとして有効なマークアップ言語(XMLアプリケーション)として再定義した言語としてXHTMLが策定された。HTMLとしてWebブラウザでの閲覧などが可能である一方、XML向けの様々なソフトウェアなどでXML文書として取り扱うことができる。ページ内にSVGやMathMLなど他のXML派生言語の記述を埋め込んで共に利用することもできる。
歴史
2000年にHTML 4.01を元に開発された「XHTML 1.0」規格が勧告された。実質的な機能や仕様はほぼHTML 4.01と同じだが、文書の先頭に必ずXML宣言を記述する必要がある点や、要素名や属性名を小文字で書く点、終了タグが省略できない(もともと終了タグのないタグは空要素タグを用いる)点など、XMLが要請する規約が盛り込まれている。
その後、携帯電話など機能の限定された機器向けに仕様を絞り込んだ「XHTML Basic」や、仕様をモジュール(部品)化して開発者が選択できるようにした「Modularization of XHTML」など、HTMLとは異なる独自の拡張が行われ、標準規格のHTMLからXHTMLへの移行、一本化が模索された。
しかし、XMLおよび派生言語の開発・利用が当初想定したほど広がらなかったこともあり、XHTML 2.0の策定は中止となった。HTMLに取って代わる単体の独立した言語としてのXHTMLは事実上終焉したが、HTML5規格ではサブセットとしてHTML5をXMLに適合させたXHTML5が定義されている。
XHTML 【Extensible HyperText Markup Language】
Webページの記述などに用いられるマークアップ言語であるHTML(HyperText Markup Language)をXMLの仕様に従って定義しなおした規格。W3C(World Wide Web Consortium)によって標準化された。
HTMLもXMLも汎用のマークアップ言語「SGML」(Standard Generalized Markup Language)から派生した言語だが、それぞれ異なる歴史的経緯から考案されたもので、HTMLの記法・仕様はXMLと整合していなかった。
そこで、HTMLをXMLとして有効なマークアップ言語(XMLアプリケーション)として再定義した言語としてXHTML Basicが策定された。HTMLとしてWebブラウザでの閲覧などが可能である一方、XML向けの様々なソフトウェアなどでXML文書として取り扱うことができる。ページ内にSVGやMathMLなど他のXML派生言語の記述を埋め込んで共に利用することもできる。
歴史
2000年にHTML 4.01を元に開発された「XHTML Basic 1.0」規格が勧告された。実質的な機能や仕様はほぼHTML 4.01と同じだが、文書の先頭に必ずXML宣言を記述する必要がある点や、要素名や属性名を小文字で書く点、終了タグが省略できない(もともと終了タグのないタグは空要素タグを用いる)点など、XMLが要請する規約が盛り込まれている。
その後、携帯電話など機能の限定された機器向けに仕様を絞り込んだ「XHTML Basic Basic」や、仕様をモジュール(部品)化して開発者が選択できるようにした「Modularization of XHTML Basic」など、HTMLとは異なる独自の拡張が行われ、標準規格のHTMLからXHTML Basicへの移行、一本化が模索された。
しかし、XMLおよび派生言語の開発・利用が当初想定したほど広がらなかったこともあり、XHTML Basic 2.0の策定は中止となった。HTMLに取って代わる単体の独立した言語としてのXHTML Basicは事実上終焉したが、HTML5規格ではサブセットとしてHTML5をXMLに適合させたXHTML Basic5が定義されている。
XHTML 【Extensible HyperText Markup Language】
Webページの記述などに用いられるマークアップ言語であるHTML(HyperText Markup Language)をXMLの仕様に従って定義しなおした規格。W3C(World Wide Web Consortium)によって標準化された。
HTMLもXMLも汎用のマークアップ言語「SGML」(Standard Generalized Markup Language)から派生した言語だが、それぞれ異なる歴史的経緯から考案されたもので、HTMLの記法・仕様はXMLと整合していなかった。
そこで、HTMLをXMLとして有効なマークアップ言語(XMLアプリケーション)として再定義した言語としてXHTML Modularizationが策定された。HTMLとしてWebブラウザでの閲覧などが可能である一方、XML向けの様々なソフトウェアなどでXML文書として取り扱うことができる。ページ内にSVGやMathMLなど他のXML派生言語の記述を埋め込んで共に利用することもできる。
歴史
2000年にHTML 4.01を元に開発された「XHTML Modularization 1.0」規格が勧告された。実質的な機能や仕様はほぼHTML 4.01と同じだが、文書の先頭に必ずXML宣言を記述する必要がある点や、要素名や属性名を小文字で書く点、終了タグが省略できない(もともと終了タグのないタグは空要素タグを用いる)点など、XMLが要請する規約が盛り込まれている。
その後、携帯電話など機能の限定された機器向けに仕様を絞り込んだ「XHTML Modularization Basic」や、仕様をモジュール(部品)化して開発者が選択できるようにした「Modularization of XHTML Modularization」など、HTMLとは異なる独自の拡張が行われ、標準規格のHTMLからXHTML Modularizationへの移行、一本化が模索された。
しかし、XMLおよび派生言語の開発・利用が当初想定したほど広がらなかったこともあり、XHTML Modularization 2.0の策定は中止となった。HTMLに取って代わる単体の独立した言語としてのXHTML Modularizationは事実上終焉したが、HTML5規格ではサブセットとしてHTML5をXMLに適合させたXHTML Modularization5が定義されている。
スタイルシート
文書データの見栄えに関する情報のみを記録・定義したデータやファイルなどのこと。これを入れ替えたり編集することで、文書自体の内容はそのままに見栄えだけを変更することができる。
文書内の各文字要素(見出しや本文など)について、字体(フォント)や大きさ、文字色、字間や行間、下線や斜体などの修飾を定義することができる。画像など他の要素について枠線や陰影などの表示形式を定義したり、文書内での各要素のレイアウト規則などを記述する場合もある。
ワープロソフトなどの文書作成ソフトでは、用途などに応じてあらかじめ複数のスタイルシートを作成しておくことにより、文書作成の度に個別に要素の見栄えを定義しなくても、適したスタイルシートを選択・適用するだけで望みの表示スタイルに変更することができる。
また、帳票や記入用紙などの定型的な書類や、互いに関連性や共通性のある複数の文書を作成する場合などにも、同じスタイルシートを適用することで文書間の見栄えに統一感を持たせることができる。
Webページのスタイルシート
Webページの記述に用いられるHTMLなどにもスタイルシートの概念があり、一般的にはCSS(Cascading Style Sheets)と呼ばれる専用の言語によりスタイルシートを記述する。単にスタイルシートといった場合はCSS形式のデータやファイルなどを指すことが多い(XSLなど他の方式も存在する)。
HTML文書にスタイルシートを適用すると、文書本体から表示形式やレイアウトなどに関する情報を分離し、文書の構造だけをHTMLファイル本体に記述することが可能になる。
これによって、HTML文書の論理的な構造が把握しやすくなるほか、サイト内の複数のページで同じスタイルを共有でき、変更を一括して適用するなどの効率的な管理ができるようになる。
CSSのみを記した単体のファイル(.cssファイル)を用意してHTMLファイルからlink要素などで指定する方法が一般的だが、HTMLファイル内部にstyle要素で記述する方法(<style>(CSS文)</style>)や、HTML要素の属性(attribute)として開始タグのstyle属性に記述する方法(<div style=“(CSS文)”>...</div>)も用意されている。HTML内に記述する場合は他ページとの共有という利点は損なわれる。
CSS 【Cascading Style Sheets】
Webページの要素の配置や見栄えなどを記述するための言語。HTML文書に追加して見た目をコントロールすることができ、文書の外部から読み込んで適用することもHTML文書中に埋め込んで記述することもできる。
Web規格では、文書内の文字情報と論理的な構造(見出しや本文、箇条書きなど)、画像など文字以外の要素の組み込みなどはHTMLで記述し、それらの画面上での位置関係や見た目の指定、装飾などはCSSで記述した「スタイルシート」により指定することとされている。
CSSによるスタイル指定はHTML文書中に直接記述することもできるが、外部のファイルにまとめて記述してHTMLから呼び出す形が望ましいとされる。CSSをファイルに格納する際の標準の拡張子は「.css」である。
基本的な書式
基本的な書式は「要素の一致条件 {プロパティ名1:値1;プロパティ名2:値2;…}」というもので、文書内で条件に一致する要素に対し、各プロパティに値が適用される。例えば「p{font-size:16px}」という指定は文書中に登場するHTMLのp要素のfont-sizeプロパティ(文字サイズ)を16ピクセルに指定することを表す。この文を必要なだけ列挙して文書の書式を設定する。
指定できるプロパティは要素の大きさや配置、要素間の位置関係や空白、要素の境界線や余白、要素間の間の空白や周囲の余白、文字の大きさや文字や行の間隔、書体(フォント)の種類や変形(太字や斜体、上付き、下付きなど)、箇条書き(リスト)の表示書式、背景色や背景画像など多岐にわたる。
HTMLタグが親子関係(包含関係)にある場合、多くの設定値は親要素に指定されたものが子要素、孫要素に引き継がれ、子要素で指定されたものが追加されていく。このように設定値が上から下へ伝播していく様子を階段状の滝を意味する “cascade” (カスケード)になぞらえてこのような名称となった。
見栄えにCSSを用いることでHTML文書に直接見栄えを記述することを避け、文書の論理的な構造をHTMLに、見栄えに関連する情報をCSSに分離することができる。構造のみ、あるいは見栄えのみを修正することが容易になり、対象機器などに応じてCSSを切り替え、それぞれに適した表示や印刷を行えるようになる。
セレクタ
CSSで要素の指定に用いられる一致条件を「セレクタ」(selector)という。要素型(タグ名)やクラス、ID、属性値、先頭からの順番など、様々な指定方法が用意されている。
「div」「a」などアルファベットから始まるものはHTMLの要素型(タグ名)を指定する「要素型セレクタ」(type selector)、「.myclass」のようにドット(ピリオド)から始まるものはclass属性の値を指定する「クラスセレクタ」(class selector)、「#myid」のようにシャープ(ナンバーサイン)から始まるものはid属性(またはname属性)の値を指定する「IDセレクタ」(ID selector)で、この3つの組み合わせが基本となる。
他にも、「要素:nth-child(n)」で子要素の特定の順番を指定したり、「要素[属性名="値"]」で特定の属性値を持つ要素のみを取り出したり、「要素:hover」(マウスオーバー時の挙動を指定)など要素が特定の状態にある場合を指し示す書式などが用意されている。
文書内の要素の階層構造(親子関係)に基づいて特定の位置にあるものだけを指定することもできる。例えば、「p>a」のような大なり記号は「子セレクタ」と呼ばれ、親要素直下の子要素(この例ではp要素直下のa要素)を指す。「p a」のように空白で繋ぐ指定方式は「子孫セレクタ」と呼ばれ、孫要素などすべての子孫要素(この例ではp要素内のすべてのa要素)を指す。
歴史
最初の規格(CSS Level 1)は1996年にW3Cによって標準化され、1998年に拡張された「CSS Level 2」標準が勧告された。長年の間これがCSS標準として定着していたが、2011年に大改訂された「CSS Level 3」(CSS3)が策定された。
CSS3からは仕様がモジュール(部品)化されたため、CSS3準拠のモジュール規格はその後何年にも渡り新たに登場し続けている。メディアクエリやセレクタなどで「Level 4」仕様の検討が始まっているが、今後は「CSS4」(あるいは5、6など)のような単一の統合されたバージョン番号は用いられない可能性がある。
XSL 【Extensible Stylesheet Language】
XML文書の構造を表示や印刷に適した状態に整え、また、その見栄えを定義するマークアップ言語。XSL自体もXML言語の一つで、XMLの仕様に準拠した記法や仕様で記述される。
XML文書の構造を変換する「XSLT」(XSL Transformations)と、XML文書内の特定の部分を指し示す書式を定めた「XPath」、文書の組版や文書内の各要素の見栄えを指定する「XSL-FO」(XSL Formatting Objects)の3つの仕様で構成される。XSLTとXPathは独立した規格として定義されており、狭義にはXSL-FOのことをXSLということもある。
XSLによるスタイル指定は、まずXML文書内の要素をXPathで指定し、XSLTで表示や変換に適した形式に整形する。その後、XSL-FOで要素のレイアウトやサイズ、書式、色などの指定を行い、人間にとって見やすい、表示や印刷に適した状態とすることができる。
1999年にWeb関連技術の標準化を行うW3C(World Wide Web Consortium)でXSLTとXPathの標準が策定され、2001年にXSL-FOを含むXSL規格が発行された。2006年にXSL 1.1規格が勧告されたものの、対応ソフトウェアはほとんど現れず、2012年にXSL 2.0の草案(ワーキングドラフト)が発表されたのが最後となっている。
UML 【Unified Modeling Language】
オブジェクト指向のソフトウェア開発において、データ構造や処理の流れなどソフトウェアに関連する様々な設計や仕様を図示するための記法を定めたもの。ソフトウェアのモデリング言語の標準として最も広く普及している。
ソフトウェア開発では、プログラムを作成する前にシステムの設計や構造、振る舞いを定義し、発注者と開発者、あるいは開発チーム内で仕様について共通認識を得る必要がある。その際、説明が文章や箇条書きだけだと分かりにくく、多数の要素の複雑な相互作用などを簡潔に表現することが難しい。
UMLでは、システムをオブジェクトの組み合わせとしてモデル化し、その構造や仕様を図表によって記述するための表記法を定めている。システムの構成要素の定義や、要素間の関連性、要素の振る舞いなどを図示することができる。
図表の描き方が人や組織によってまちまちでは相互理解に支障を来すが、標準化されたUMLという共通の「言語」を用いることで、書き手の意図を正しく読み手に伝えることができる。システムの様々な側面を伝達できるよう、UMLには14種類の図が用意されている。
UMLの仕様は1996年に当時のラショナル・ソフトウェア(Rational Software)社(2003年に米IBM社が買収)が策定した。その後、仕様の策定・改訂は業界団体のOMG(Object Management Group)が行うようになった。UML1.4が2005年にISO/IEC 19501として、UML 2.4が2012年にISO/IEC 19505としてそれぞれ国際標準となっている。
図の種類
UMLで定義される図は大きく分けて、システムの構造を表す「構造図」(structure diagram)と、動作や変化を表す「振る舞い図」(behavior diagram)の2種類に分類される。
構造図には「クラス図」(class diagram)、「オブジェクト図」(object diagram)、「コンポーネント図」(component diagram)、「パッケージ図」(package diagram)、「配置図」(deployment diagram)、「複合構造図」(composite structure diagram)、「プロファイル図」(profile diagram)がある。
振る舞い図には「アクティビティ図」(activity diagram)、「ユースケース図」(use case diagram)、「ステートマシン図」(state machine diagram)、「相互作用図」(interaction diagram)がある。
相互作用図はさらに、「シーケンス図」(sequence diagram)、「コミュニケーション図」(communication diagram、以前はコンポーネント図と呼ばれていた)、「タイミング図」(timing diagram)、「相互作用概要図」(interaction overview diagram)に分かれる。
クラス図
UMLで規定された図の一つで、システムを構成するクラスの構成や、クラス間の関係を表現する図。システム全体の静的な構造を明らかにするために作成される。
UML(Unified Modeling Language)はオブジェクト指向のソフトウェア開発において、データ構造や処理の流れなどソフトウェアに関連する様々な設計や仕様を図示するための記法を定めた標準規格である。クラス図はシステムの構造を図示する構造図の一つで、クラスの構成やクラス間の関係を表現することができる。
オブジェクト指向プログラミングでは互いに関連するデータと操作手順を「クラス」という単位で一体的に定義する。クラス図ではクラスを矩形で示し、クラス間の関係を線で表す。クラスを外部から操作する方法だけを定義した「インターフェース」(interface)も矩形で示し、クラスと対応付ける。
矩形の内部にはクラスが表す対象の性質や状態を表す「属性」(property)や、属性に対する操作である「メソッド」(method)を名前やデータ型と共に列挙する。他のクラスから見えるかどうかを指定したい場合は、項目の先頭に「+」(public:どこからでも見える)、「#」(protected:子クラスからのみ見える)、「-」(private:外部からは見えない)、「~」(package:同じパッケージ内から見える)という記号を付ける。
主な関係の種類
クラス間の関係は、クラスをプログラム中で実際に具象化した「インスタンス」(instance)同士の関係と、複数のクラス同士の関係に分かれる。クラス同士の場合もインスタンス同士の場合もありえる関係として「依存」(dependency)があり、あるクラスが機能するためには別のクラスの存在が必要という関係を表す。
インスタンス同士の関係としては、クラス間に何らかの繋がりがあることを示す「関連」(association)、あるクラスが別のクラスの部分を構成する「集約」(aggregation)や「コンポジション」(composition)がある。集約では部品は複数のクラスに属することができるが、コンポジションは所属先がただ一つに定まっている。
クラス同士の関係としては、あるクラスが別のクラスの子クラス(サブクラス)となる「継承」(inheritance)あるいは「特化」(specialization)、逆に、子クラスにとって親クラス(スーパークラス)であることを示す「汎化」(generalization)、抽象クラスやインターフェースで示された仕様を子クラスで具体化する「実現」(realization)あるいは「実装」(implementation)などがある。
オブジェクト図
ソフトウェアの設計などに用いられるUML(Unified Modeling Language)で規定された図(ダイアグラム)の一つで、実際の場面において登場する具体的なオブジェクトとそれらの間の関係を表したもの。
オブジェクト(object)は設計時にはその雛形であるクラス(class)によって定義されるが、ソフトウェアの実行時など実際の場面では具現化されたインスタンス(instance)として登場する。オブジェクト図は系のある時点におけるインスタンス同士の関係を記述することでシステムの挙動などを詳細に知らせることができる。
オブジェクトは長方形で示され、内部にオブジェクト名が記入される。オブジェクト名には下線が引かれ、クラスに所属している場合には「:」に続けてクラス名を記入する。
オブジェクトが何らかの属性や状態を持つ場合には、長方形を上下に区切り、下側の区画に「属性名=属性値」の形式で列挙する。オブジェクトと別のオブジェクトの間に何らかの関連がある場合は直線(リンクと呼ばれる)で結び、線の脇にそれらの関係を記入する。
オブジェクト図は業務やシステムのある時点における具体的な状況を理解したり説明する助けになり、クラス図を作成するための分析に用いられたり、定義されたクラスなどが適切か否かを検証するために用いられることが多い。
コンポーネント図
ソフトウェアの設計などに用いられるUML(Unified Modeling Language)で規定された図(ダイアグラム)の一つで、システムを構成する要素間の関係を表したもの。
規模の大きなソフトウェアは通常、複数の実行ファイルやライブラリファイル、モジュールといったソフトウェア部品の組み合わせとして実装される。コンポーネント図はシステムがどのようなコンポーネント群から構成され、それらの相互の依存関係はどうなっているかといった内容を記述する。
各コンポーネントは矩形で表し、内部に機能の名前と、コンポーネントであることを示す《component》という表記(ステレオタイプ)を記載する。ステレオタイプに代えてコンポーネントを表す小さなアイコン(矩形の左辺に小さな長方形が縦に並んだもの)を付加する場合もある。
矩形の内部を何段かに区切り、外部に提供するインターフェース《provided interface》や要求するインターフェース《required interface》などの付加情報を記載することもできる。
依存関係は依存先に向けて破線の矢印で表す。複数のコンポーネント間に親子関係がある場合は、親のインターフェースから委譲先の子のインターフェースに向けて矢印を記す。コンポーネントは入れ子構造にすることができ、内部が細かい複数のコンポーネントで構成される場合は矩形の内部にその構造を表すコンポーネント図を描く。
パッケージ図
ソフトウェアの設計などに用いられるUML(Unified Modeling Language)で規定された図(ダイアグラム)の一つで、クラス図などの各モデル要素がどのように分類され、グループ分け(パッケージ)されているかを表現するもの。
システムの構造や構成を表す構造図(structure diagram)の一つで、モデルを膨大な数作成する大規模なシステムの全容を把握する場合などに、機能群を分割し、グループ化して整理することができる。
パッケージ図ではタブ付の長方形で一つのパッケージを表現し、この中にパッケージ名及びそのパッケージに所属する各モデル要素を記述する。パッケージ間の汎化・依存関係は、パッケージ間を破線の矢印で結ぶ。
パッケージはモデル要素に加えて別のパッケージを含むことができ、パッケージ間を関係を入れ子構造として表すことができる。オプションとしてステレオタイプを付記することができ、役割などの修飾情報を表すことができる。
パッケージマージ (package merge)
UML 2.0ではパッケージの再利用をより行いやすくするために、「パッケージマージ」という概念が追加された。複数のパッケージを統合(merge)して一つのパッケージとすることができ、既存のパッケージを再利用して新しいパッケージを作成することが容易になる。
パッケージの再利用にはパッケージマージの他に「パッケージインポート」がある。両者の違いはパッケージ間で同じ名前の要素の衝突があったときの処理にある。パッケージマージの場合は汎化の関係になり、双方の要素の特長を合わせ持つものになるが、パッケージインポートの場合はインポート元の要素は隠され、インポート先の要素のみを持つことになる。
アクティビティ図 【活動図】
ソフトウェアの設計などに用いられるUML(Unified Modeling Language)で規定された図(ダイアグラム)の一つで、業務や処理の実行手順を表したもの。
アクティビティ図ではそれ以上分割できない最小の動作単位を「アクション」(action)と呼び、角丸四角形で図示する。アクションを組み合わせたひとまとまりの動作を「アクティビティ」(activity)と呼ぶ。
活動の開始ノード(黒丸で示される)から終了ノード(丸で囲った黒丸で示される)までの間にアクションやアクティビティを配置し、それぞれの依存関係に従って矢印で結んでいく。
次のアクションへ情報などが受け渡される場合には、中間に四角形で示す。矢印で結ばれた手順の流れを「フロー」(flow)という。異常終了などでフローが途中で終了する場合には、終了地点に丸囲みの×印を記す。
アクティビティ図全体を縦または横(あるいはその両方)に分割して実行主体や段階を示すことができる。アクションやアクティビティが分割されたどの領域に存在するかによって、どの主体による動作かを示したり、どのような段階に行われる動作かを示すことができる。
フローの分岐・合流
特定の条件に従ってフローが分岐する場合には、菱形の「デシジョン」(decision:判断)ノードを置いて2方向に矢印を記し、それぞれの脇に条件を記述する。フローが合流する地点には同じ菱形の「マージ」(merge:合流)ノードを置く。
ある時点から複数のフローを並列に実行する場合には、その開始地点に太い直線で示される「フォーク」(fork:分岐)ノードを置き、複数のフローを出発させる。これらの同期を取って一つのフローに戻したい場合には、同じく太い直線の「ジョイン」(join:結合)ノードを置き、フローを集合させる。
アクティビティ図 【活動図】
ソフトウェアの設計などに用いられるUML(Unified Modeling Language)で規定された図(ダイアグラム)の一つで、業務や処理の実行手順を表したもの。
アクティビティ図ではそれ以上分割できない最小の動作単位を「アクション」(action)と呼び、角丸四角形で図示する。アクションを組み合わせたひとまとまりの動作を「アクティビティ」(activity)と呼ぶ。
活動の開始ノード(黒丸で示される)から終了ノード(丸で囲った黒丸で示される)までの間にアクションやアクティビティを配置し、それぞれの依存関係に従って矢印で結んでいく。
次のアクションへ情報などが受け渡される場合には、中間に四角形で示す。矢印で結ばれた手順の流れを「フロー」(flow)という。異常終了などでフローが途中で終了する場合には、終了地点に丸囲みの×印を記す。
アクティビティ図全体を縦または横(あるいはその両方)に分割して実行主体や段階を示すことができる。アクションやアクティビティが分割されたどの領域に存在するかによって、どの主体による動作かを示したり、どのような段階に行われる動作かを示すことができる。
フローの分岐・合流
特定の条件に従ってフローが分岐する場合には、菱形の「デシジョン」(decision:判断)ノードを置いて2方向に矢印を記し、それぞれの脇に条件を記述する。フローが合流する地点には同じ菱形の「マージ」(merge:合流)ノードを置く。
ある時点から複数のフローを並列に実行する場合には、その開始地点に太い直線で示される「フォーク」(fork:分岐)ノードを置き、複数のフローを出発させる。これらの同期を取って一つのフローに戻したい場合には、同じく太い直線の「ジョイン」(join:結合)ノードを置き、フローを集合させる。
状態遷移図
対象がどのような状態を持ち、どのような条件や出来事(イベント)によりそれらの間を遷移するかを一覧に表した図。
様々な表現形式があるが、一般的な手法では、対象が取りうる状態を円や矩形などで列挙し、どこからどこへ遷移が起きうるかを矢印によって示す。各矢印の脇に、その遷移が起きるための条件やきっかけとなる出来事などを記述する。自らに遷移する場合は自分を指し示す輪っか状の矢印を書き入れる。
対象に開始や終了がある場合は、特殊な記号で示される場合がある。UMLでは開始を塗りつぶした丸印で、終了を内側を塗りつぶした二重丸で記載するよう定められている。
状態遷移表
ステートマシン図の各状態を一行として表の形で書き表したものを状態遷移表という。
一般的な形式では、各行が対象の状態を、各列がイベントを表し、ある状態のときにあるイベントが起きたときにどの状態に遷移するかを書き入れていく。
また、縦軸・横軸ともに状態を並べ、各状態の交差する項目にそのような遷移が起こるイベントを書き入れていく様式もある。
ソフトウェア開発の分野ではテストを行う際にテストケースを漏れなく網羅するために状態遷移表が作成される場合がある。
ステートマシン図 (state machine diagram)
ソフトウェアの設計などに用いられるUML(Unified Modeling Language)では、ステートマシン図に相当する図をステートマシン図(state machine diagram)として定義している。
あるオブジェクトの振る舞いを漏れなく記述するために用いられるもので、開始状態を塗りつぶした丸印(●)、終了を内側を塗りつぶした二重丸で表し、途中の状態を角丸の矩形を並べて図示していく。
状態間は遷移する方向に矢印で繋ぎ、脇に遷移の説明を添える。遷移したときに実行する動作がある場合は矩形を横に区切って下半分に動作の内容を記述する。
シーケンス図 【シーケンスダイアグラム】
ソフトウェアの設計などに用いられるUML(Unified Modeling Language)で規定された図(ダイアグラム)の一つで、要素間の相互作用を時系列で表したもの。相互作用図(interaction diagram)の一種で、図の上から下に向かって時間の流れが表される。
シーケンス図の上方には、図中に登場するオブジェクトなどの構成要素を横に並べて表示する。それぞれの要素からは下に向かって「ライフライン」(lifeline)と呼ばれる破線が引かれ、その要素が有効である期間を示す。要素が消滅・退場する時点は×印で示し、そこでライフラインが途切れる。
要素が何かを実行している最中であることを示すにはライフライン上に縦長の長方形を描く。これを「実行仕様」(execution specification)という。箱の上端がその動作の開始時、下端が終了時をそれぞれ示す。
メッセージ
ある要素から別の要素へ何らかの作用を及ぼす際には、その二要素間を矢印で結び、線上に作用の内容を表記する。これを「メッセージ」(message)と呼ぶが、データの送受信だけでなく、操作の実行やインスタンスの生成などもメッセージに含まれる。
他の要素からのメッセージに答える「応答(reply)メッセージ」は破線の矢印で示される。送り先の応答を待つ「同期」(synchronous)メッセージは先端が黒三角の矢印で、待たずに先に進む「非同期」(asynchronous)メッセージは先端が三叉の矢印で示す。
また、図上に示されない相手からのメッセージは送り手が黒丸(●)で示された「ファウンドメッセージ」(found message)、図上に示されない相手へのメッセージは送り先が黒丸で示された「ロストメッセージ」(lost message)で表す。
JSON 【JavaScript Object Notation】
JavaScriptにおけるオブジェクトの表記法を応用したテキスト(文字)ベースのデータ形式。多数の要素が複雑な構造で組み合わせられたデータを簡潔な表記で書き表すことができる。JavaScriptプログラム上ではコードとして実行するだけで読み込みが完了する。
JavaScriptではオブジェクト定義の構文として、キーと値のペアを列挙したデータ構造を用いる。これは他のプログラミング言語では連想配列、ハッシュ、マップ、辞書(ディクショナリ)などと呼ばれるものに近い。
JSONでは、これと配列を利用して複合的なデータ構造を記述することができる。配列やオブジェクトの値として別の配列やオブジェクトを入れ子の形で記述でき、深い階層構造を持つ複雑なデータを表すことができる。
値として利用できるデータ型はJavaScriptに用意されているプリミティブデータ型で、整数型、浮動小数点数型、文字列型、ブール型(真偽値)、null(値無し)、配列、オブジェクトである。
配列は [“A”,“B”,“C”] のように全体を角括弧で囲み、値をカンマ区切りで列挙していく。オブジェクトは { Key1:“Value1”, Key2:“Value2”} のように全体を中括弧で囲み、キーと値をコロン(:)で区切って表記したペアをカンマ区切りで列挙していく。
JSONはJavaScriptでの扱いが簡単なため、WebサービスやAjaxなどでプログラム間でのデータ交換フォーマットとして多用されている。また、数多くのプログラミング言語でJSONを簡単扱えるようにする追加機能などが公開されており、設定ファイルやデータ交換などでXMLに代わって普及している。
歴史
JSONはもともとJavaScriptの構文規則の一部だが、2001年にダグラス・クロックフォード(Douglas Crockford)氏がこれをデータ形式のように扱うことできることを「発見」し、これをJSONと命名した。
2006年には独立したデータ形式としてIETFがRFC 4627として規格化した。JavaScriptの標準化を行っていたEcma Internationalが2011年にECMAScript 5.1の一部として標準化、2013年にはECMA-404として独立した規格が発行された。両団体間で一部の仕様が異なる問題があったため、2017年にRFC 8259およびECMA-404の改訂版として仕様が統一された。
YAML 【YAML Ain’t Markup Language】
構造的なデータ集合を簡素な文字列として表記することができるデータ形式の一つ。ソフトウェアの設定ファイルの記述や異なるソフトウェア間のデータ交換などでよく用いられる。ファイル拡張子は「.yml」とすることが多いが、公式には「.yaml」が標準とされる。
用途はXMLのような汎用のマークアップ言語に近いが、文法はプログラミング言語に近く、JavaScriptのオブジェクト記法でデータを記述するJSON(JavaScript Object Notation)とよく比較される。プログラムが内部で扱うオブジェクトなどを、保存や送受信などのために文字データ化する「シリアライズ」(serialize/直列化)のための形式として特に有名である。
基本的な仕様
YAMLでは基本的に「シーケンス」(sequence)、「マッピング」(mapping)、「スカラ」(scalar)の3種類の形式の組み合わせとしてデータを記述していく。
シーケンスは多くのプログラミング言語で「配列」(array)「リスト」(list)などと呼ばれる、データを連続に並べた構造である。同様に、マッピングは「ハッシュ」(hash)「連想配列」(associative array)などと呼ばれる、キーと値のペアを列挙する構造で、スカラは単体のデータである。
シーケンスやマッピングの入れ子(ネスト)構造の表現は、1文字以上の半角スペースを行頭に挿入して字下げ(インデント)することによって行なう。スペースの数は任意だが、タブ文字で代用することはできない。
スカラとして記述することのできるデータ型には、文字列、整数(8進数/10進数/16進数)、浮動小数点数、真理値(true/false)、日付、日付と時刻(タイムスタンプ)、空データ(Null値)などがあり、特定のプログラミング言語の特定のデータ型を明示して記述することもできる。
記法
スカラは「10」なら整数、「0.1」なら浮動小数点数、「abc」なら文字列といったように原則として表記によって自動的にデータ型の判定が行われる。数字や真理値の「true」などを文字列として扱いたい場合は引用符(「"」または「'」)で括る。先頭に「!!str 」のように「!!型名 」を付けて型を明示することもできる。
シーケンスは、一行で記述する場合は [ Red, Green, Blue ] のように角括弧で囲って値をカンマ区切りで並べる。一行に一項目を記述する場合は先頭をハイフン(-)とする。マッピングは「key : value」のようにコロン(:)でキーと値を対応付ける。
シーケンスの項目やマッピングの値を別のシーケンスやマッピングにすることができ、何段階も入れ子状に構造化することができる。データ本体として評価されたくない注釈(コメント)を記述したいときは、「#」を記述すればそこから行末までがコメントとなる。コメントは行頭からでも行の途中からでもよい。
歴史
YAMLは2001年にクラーク・エバンス(Clark Evans)氏、インギー・ドット・ネット(Ingy döt Net/2005年にTerry Brian Ingersonから改名)氏、オーレン・ベンキキ(Oren Ben-Kiki)氏らが考案し、最初の正式な仕様は2004年1月に発表された。
「YAML」という名称の由来は、当初はXML等を意識した “Yet Another Markup Language” (さらにもう一つのマークアップ言語)の略とされていたが、現在では正式には “YAML Ain’t Markup Language” (YAMLはマークアップ言語ではない)の略とされる。