高校「情報Ⅰ」単語帳 - 全用語 - アルゴリズムとプログラミング
プログラム ⭐⭐⭐
予定(表)、計画(表)、課程、式次第などの意味を持つ英単語。ITの分野では、コンピュータに行わせる処理を記述したコンピュータプログラムのことを略して単にプログラムということが多い。
コンピュータプログラム (computer program)
コンピュータが行うべき処理を順序立てて記述したもの。広義の「ソフトウェア」の一部であるが、実用上はプログラムとソフトウェアはほとんど同義のように扱われることが多い。
現代のコンピュータではプログラムは一定の形式に従ってデータとして表現され、記憶装置(メインメモリ)に格納される。実行時にはCPU(中央処理装置)がプログラムに記述された命令を順番に読み出して解釈・実行していく。
プログラムを作成する作業や工程を「プログラミング」(programming)、これを行う人や職種のことを「プログラマ」(programmer)という。人間がプログラムを記述する際には、人間が理解しやすい人工言語である「プログラミング言語」(programming language)を使うことが多い。プログラミング言語で記述されたプログラムを「ソースコード」(source code)という。
ソースコードはコンピュータが解釈・実行することができないため、コンパイラなどの変換ソフトによってコンピュータが解釈・実行できる機械語(マシン語)などで構成された「オブジェクトコード」(object code)に変換されてから実行される。スクリプト言語のように、この変換処理を開発時には行わず、実行時にインタプリタなどのソフトウェアによって動的に行う場合もある。
プログラミング ⭐⭐
コンピュータに意図した動作を行わせるために、まとまった処理手順を作成し、与えること。作成された手順のことを「コンピュータプログラム」(computer program)あるいは単にプログラムという。
狭義には、プログラミング言語やそれに相当する仕組みや道具を用いて、人間が読み書きしやすい形式のプログラム(ソースコード)を記述していく「コーディング」(coding)作業を指す。広義には、その前後に行われる、設計や試験(テスト)、修正(デバッグ)、実行形式や配布形式への変換(コンパイルやビルドなど)といった一連の作業を含む。プログラミングを行う人や職種のことを「プログラマ」(programmer)という。
プログラムの作成
プログラミングを行うには、まず何をするプログラムを作るのかを明確に定義し、仕様や要件を自然言語で記述したり、大まかな処理の流れを箇条書きやフローチャートなどの図表を用いて設計する。集団でソフトウェア開発を行う場合はプログラムの記述者とは別の設計者が専門に作業を行い、仕様書や設計書などの形でまとめる場合もあるが、個人が小規模のプログラムを作成する場合はこの工程を頭の中で行い、作業や手順としては省略する場合もある。
どんなプログラムを作りたいか決まったら、これをコンピュータが解釈できるプログラミング言語を用いてソースコードとして記述していく。言語やプログラムの記述法には様々な種類があるが、手続き型の言語(手続き型プログラミング)の場合、実行すべき命令を先頭から順に書き下していく。必要に応じて、複数の命令をひとまとめにして名前をつけて呼び出せるようにしたり(関数やサブルーチンなど)、条件分岐や反復(繰り返し)などで命令の流れの制御を行う。
プログラムの実行
ソースコードそのものはコンピュータ(の処理装置)が解釈・実行できる形式ではないため、これを機械語(マシン語)のプログラムなど実行可能な形式に変換する必要がある。ソースコードを機械語などのコード(オブジェクトコード)に変換する工程をコンパイル(compile)と呼び、プログラムの起動処理やライブラリなど実行に必要なコードを連結する工程をリンク(link)という。これら一連の工程を行って実行可能ファイルやパッケージを作ることをビルド(build)という。
スクリプト言語(軽量言語)などの場合はこうした明示的な変換工程は不要で、ソースコードを機械語に変換しながら同時に実行するインタプリタなどの処理系で直に実行することができる。記述したコードをすぐ実行でき手軽だが、変換しながら実行するため実行可能ファイルを生成する場合より実行速度やメモリ効率では劣る。
プログラムの修正
作成したプログラムが一度で完全に思い描いたとおりに動作する場合もあるが、大抵は何らかの誤りや不具合を抱えているものである。このため、ビルドしたプログラムを実行してみてテスト(動作試験)を行い、仕様通りに動くか調べる。
誤り(バグ)が発見されると原因や解決策を考え、正しく動作するようにプログラムを書き換える(デバッグ)。バグには単純な記述ミスのようなものから、そもそも解くべき問題に対して選択した計算手順(アルゴリズム)が合っていないといった根本的なレベルのものまで様々な種類がある。
デバッグ作業が完了したら再びビルドとテストを行い、誤りが正されていることを確認する。このビルド→テスト→デバッグの繰り返しによって次第にプログラムの完成度や品質が上がっていき、実際に実用可能なプログラムに仕上げることができる。実際のプログラミングにおいては作業時間の多くがこの繰り返しの工程に費やされる。
スクリプト
台本、脚本、原稿、手書き、筆記体などの意味を持つ英単語。ITの分野では簡易なコンピュータプログラムをスクリプトと呼ぶことが多い。
プログラムの種類の一つで、人間が読み書きしやすいプログラミング言語で書かれたプログラム(ソースコード)を即座に実行できるようなものをスクリプトという。そのようなプログラムを記述するための言語を「スクリプト言語」(scripting language)という。
通常、プログラミング言語で書かれたコードはコンピュータが直に解釈して実行することができないため、機械語(マシン語)へのコンパイル(翻訳)や必要な外部プログラムのリンクなどの操作を行ない、実行可能ファイルを作成する作業工程が必要となる。
スクリプトではこの工程を専用のソフトウェア(インタプリタや仮想マシンなど)が自動的に行なってくれるため、プログラムを作成あるいは入手後、即座に実行を始めることができる。面倒で専門的な作業が不要な一方、機能や性能に一定の制約や制限があることが多い。
多くのスクリプトは何らかのソフトウェア上で実行され、そのソフトの持つ機能を呼び出して作業を自動化したり、機能を拡張するために用いられる。言語によっては通常の実行可能プログラムと同じように、オペレーティングシステム(OS)などの上で独立して起動できる実行環境が用意されている場合もある。
著名なスクリプト言語としては、UNIX系OSのシェルで実行されるシェルスクリプト(shell script)、Webブラウザで実行されるJavaScript、Webサーバで実行されるPHPやJSP、ASP、汎用的で多様な実行環境を持つPerlやRuby、Pythonなどがある。
ソースコード 【ソースプログラム】 ⭐⭐
プログラミング言語などの人間が理解・記述しやすい言語やデータ形式を用いて書き記されたコンピュータプログラムのこと。プログラムに限らず、人工言語や一定の規約・形式に基いて記述された複雑なデータ構造の定義・宣言などのこともソースコードと呼ぶ場合がある。
コンピュータへの指示や一連の処理手順などをプログラミング言語によって文字データの羅列として表記したもので、そのままではコンピュータ(のCPU)では実行できないため、CPUが直に解釈できる命令コードの体系である機械語(マシン語)によるプログラムに変換されて実行される。
変換後の機械語による実行可能プログラムを「オブジェクトコード」(object code)、「オブジェクトプログラム」(object program)、「ネイティブコード」(native code)、「ネイティブプログラム」(native program)、「バイナリコード」(binary code)などと呼ぶ。
実行可能形式への変換
ソースコードからオブジェクトコードへの変換はソフトウェアによって自動的に行うのが一般的となっている。アセンブリ言語で記述されたソースコードを変換することを「アセンブル」(assemble)、そのようなソフトウェアを「アセンブラ」(assembler)という。
アセンブリ言語以外の高水準言語で記述されたソースコードを一括して変換することは「コンパイル」(compile)と言い、そのようなソフトウェアを「コンパイラ」(compiler)という。実行時に少しずつ変換しながら並行して実行するソフトウェアもあり、「インタプリタ」(interpreter)と呼ばれる。
開発時にソースコードから直接オブジェクトコードへ変換せずに、特定の機種やオペレーティングシステム(OS)の仕様・実装に依存しない機械語風の独自言語による表現(中間コード)に変換して配布し、実行時に中間コードからCPU固有の機械語に変換するという二段階の変換方式を用いる言語や処理系もある。
ソースコードの作成
ソースコードは多くの場合、人間がキーボードなどを操作して文字を入力して記述する。この作業・工程を「コーディング」(coding)という。ソースコードはテキストデータの一種であるため文書編集ソフトで作成することはできず、テキストエディタや統合開発環境(IDE)に付属する専用のコードエディタなどを用いることが多い。
必ずしも人間が記述するとは限らず、何らかの元になるデータや入力からソフトウェアによって生成したり、別の言語で記述されたソースコードを変換して生成したり、オブジェクトコードを逆変換してソースコードに戻したりといった方法で、ソフトウェアが自動的・機械的に作成する場合もある。
ソースコードの公開・非公開
日本を含む多くの国でソースコードは著作物の一種として著作権で保護されている。販売される商用ソフトウェア製品の多くは、ソースコードを企業秘密として非公開とし、人間に可読でない中間コードやオブジェクトコードによる実行プログラムのみを利用者に提供している。
一方、ソースコードを公開し、誰でも自由に入手、利用、改変、再配布、販売などができるようにしている場合もある。そのようなソフトウェアを、ソースコードがオープンになっているという意味で「オープンソースソフトウェア」(OSS:Open Source Software)という。ボランティアのプログラマが個人あるいは共同で開発しているソフトウェアに多いが、企業がOSSを開発・公開している例も多く見られる。
コーディング
プログラミング言語など何らかのコンピュータ言語の語彙や文法に従って、コンピュータが処理・解釈できる符号の列を記述する作業のこと。
ソフトウェア開発の場合には、プログラムの仕様や構造を定めた仕様書や流れ図などの資料、あるいは頭の中に思い浮かべた処理の流れやアルゴリズム(計算手順)に従って、プログラミング言語を用いてソースコードを入力していく工程を指す。得られたソースコードは機械語(マシン語)のプログラムなどに変換されて実行される。
「プログラミング」(programming)とほぼ同義とされることもあるが、プログラミングはコードの構想や設計、記述したコードのテストや修正(デバッグ)といったコード記述の前後の段階を含む概念とされることが多く、その場合はコーディングはプログラミングの一部となる。
また、コンピュータプログラムの作成だけでなく、人工言語を用いてコンピュータが処理できるコードを記述する作業全般をコーディングと呼ぶことがある。例えば、HTMLやCSSなどの言語を用いてWebページの内容やデザインをコードとして記述していく作業や、ハードウェア記述言語を用いて論理回路の構成を記述する作業などもコーディングという。
インデント ⭐
文章の行頭に空白を挿入して先頭の文字を右に押しやること。また、そのために左端に挿入された空白や、テキストエディタやワープロソフトの持つ字下げ機能のこと。
横書きの日本語は段落の先頭を一文字分字下げすることになっているため、文書作成ソフトなどにはそのための機能が用意されていることが多い。
ソースコードのインデント
プログラミングの分野では、プログラムの構造を見やすくするために制御構文の内側にある行などの先頭に一律に同じ幅の空白を挿入することをインデントという。
どの行が同じブロックに含まれるのか視覚的に分かりやすく表示することができ、プログラムの流れが理解しやすくなる。範囲の取り違えなどに起因するバグなどを減らす効果も期待できる。
あるブロックの中に別のブロックが含まれるという入れ子構造(ネスト)になっている場合、各行のインデントも入れ子の深さに応じて長くなっていく。これにより、プログラムの階層構造をコード中で視覚的に表すことができる。
インデントとして挿入されるのはタブ文字か連続した空白文字(スペース文字)で、タブ文字の場合はインデントの幅は表示する側のソフトウェアの設定により異なる。空白文字で表す場合は2~8文字程度の連続した空白でインデントする。
読む側で好みの幅を調整できるのでタブが好ましいとする人と、書く側で幅を決定して環境によらず同じように表示できるので空白文字が好ましいとする人の間で長年論争があり、また、いずれの場合も一段のインデント幅を何文字分とするかで好みが分かれる。
ほとんどのプログラミング言語ではインデントはソースコードの見た目の問題でありプログラムの意味には影響を及ぼさない(取り除いても同じように動作する)が、Pythonのようにインデントによってプログラムの構造を記述する言語もある。
コメントアウト
プログラムのソースコードなどを編集する際に、特定の箇所をコメント化して一時的に除外すること。あとで復活させるかもしれない内容を消さずにその場で取っておくために行われる。
プログラミング言語やマークアップ言語でコードを記述するとき、すでに記述されたコードを完全に削除するのではなく一時的に無効化して試験などを行いたい場合がある。
そのような場合に当該箇所の前や後にコメント記法を追加してコメント化する(コードとして解釈・実行されなくなる)ことをコメントアウトという。コメント記法を取り除けば再びコードとして復活させることができる。
コメントの開始や終了を指示する記号の組み合わせなどは言語によって異なり、HTMLやXML系マークアップ言語では <-- と --> で囲んだ部分が、CSSやC言語系の記法を採用するプログラミング言語(Java、JavaScriptなど)では /* と */ で囲んだ部分(あるいは//から行末まで)がコメントとなる。
なお、通常はコードの一部をコメントとして外す(out)ことを指すが、注釈を書き入れるなど、本来の意味でコメントを記述することを含めてコメントアウトと呼ぶ人もいる。
バグ ⭐
「虫」という意味の英単語で、コンピュータの分野ではプログラムに含まれる誤り、欠陥を指す。俗に、ソフトウェアが正常に動作しなくなることを「バグる」ということがある。
ソフトウェアの誤作動を引き起こすコンピュータプログラム中の欠陥を指し、人間がプログラムを書き記す際に起きる単純な誤記や勘違いなどによるものから、構想や設計の段階で誤りや矛盾が含まれていたことに起因するものなど、様々な原因によって発生する。プログラム中の誤りを発見し取り除く作業・工程を「デバッグ」(debug:除虫する)という。
バグを含むプログラムを実行することで生じる問題は様々だが、典型的なものとしては、利用者の操作に応答しなくなったり、設計意図と異なる挙動を示したり、誤ったデータを出力したり、記録されたデータを破壊したりといった振る舞いが挙げられる。
ビデオゲームの分野では、キャラクターやフィールドが通常はありえない状態になる現象や、不可能なはずの挙動や展開が可能になるバグが注目されることが多い。製品としては欠陥だが、バグによって可能になる奇妙な挙動や攻略テクニックなどを「裏技」「バグ技」などと呼んで面白がる文化がある。
潜在的なバグ
常に同じ実行箇所に差し掛かると同じ問題を引き起こすバグは発見しやすいが、いつどこで実行しても同じ箇所で必ず不具合を引き起こすとは限らない。特定の入力データや操作、使用環境や設定、あるいはそれらの特定の組み合わせによって発現し、それ以外の状況では誤作動を引き起こさない場合がある。
例えば、1980年代までは日付データの年号部分を西暦の下二桁で記録・管理することは記憶容量の節約や処理速度の向上に寄与するとして推奨されることが多かったが、西暦2000年に到達すると正常に動作しなくなる(西暦2000年問題)。実際、情報システム業界は1990年代末に業務用システムの改修に大きな人手を割くことになった。
バグの発見と修正
コンピュータプログラムの設計・記述の多くは人間が行うため、バグの発生・混入を未然に完全に防ぐ方法はなく、いかに効率よく早期に発見し取り除くかが重要となる。そのためには、ソフトウェア開発の各段階で繰り返し入念にテストを行い、発見された不具合や誤作動についてプログラム上の発生箇所や原因を特定し、対処方法を決定して修正などを行う。
発見されたほとんどのバグは正しい動作を行うプログラムコードに差し替えられる。発売・公開前のプログラムは修正して実行ファイルなどを作りなおすが、利用者の手元に提供した後にバグが発見されることもある。そのような場合には、開発元が「パッチ」「バグフィックス」などと呼ばれる修正プログラムをインターネットなどを通じて配布し、利用者側のソフトウェアを更新する。
オペレーティングシステム(OS)やライブラリ、ミドルウェアなど基盤的なソフトウェアの場合には、修正によってプログラムの振る舞いが変わり、従前の振る舞いを前提に動作していた他のプログラムなどに思わぬ影響を及ぼすことがある。深刻な影響が想定される場合はバグをあえて放置し、別の箇所や方法で悪影響を抑えるというアプローチが取られる場合もある。
歴史
古くは19世紀の記録に機械の設計・製造上の誤りや不良が “bug” と呼ばれていた事例がいくつか知られており、初出がいつに遡るのかは判然としない。現代のコンピュータのソフトウェアにおける用例に近い初期のエピソードとして最も有名なものは、1947年にグレース・ホッパー(Grace Hopper)氏が米ハーバード大学で遭遇した事例である。
初期の電気機械式のコンピュータ「Harvard Mark II」の不具合を調査する過程で、あるスタッフがリレー(スイッチ)に蛾が挟まって接触不良を起こしているのを発見した。彼女は日誌に蛾をテープで留め、“First actual case of bug being found”(実際にバグが見つかった最初の事例) と書き残した。
デバッグ 【デバッギング】 ⭐
コンピュータプログラムが意図した通りに動作しない場合に、その原因となるプログラム中の誤った箇所を探し出し、ソースコードを修正して取り除くこと。
プログラムが仕様や開発者の意図と異なる動作をする場合、そのような動作を引き起こすプログラム上の欠陥、誤りを「バグ」(bug:虫)という。テストなどによって発見された誤作動・不具合について、その原因やソースコード上での位置を探索・特定し、意図した通りに動作するように修正する作業をデバッグという。
バグの探索
デバッグ作業ではまず、バグがプログラムのどこに潜んでいるのかを探し出す。バグはエラーなどで停止したコードに存在するとは限らない。あるコードが誤ったデータを生成し、そのデータを使って処理を行おうとした別のコードが致命的なエラーを起こして停止するということもあるからである。
位置が特定されると、なぜそのような誤りが生じたのか原因を調べる。単純な誤記によるものから、プログラムを構成する論理やアルゴリズムの誤りに原因がある場合、当初の想定では予期していなかった入力値や動作環境など、様々なものが原因になりうる。
バグの修正
原因が特定されると修正が行われるが、様々なシステムの基盤に用いられるような製品では外部のシステムがすでにそのバグが存在する前提で作られてしまっている場合もあるため、修正せずに存在を周知して個別に対策するよう呼びかける場合もある。
また、修正によって新たなバグが発生したり、別の箇所に潜んでいたバグを顕在化させる「デグレード」と呼ばれる事態が生じることもあるため、修正したプログラムは当該箇所以外への影響も含めて入念にテストされることが多い。
デバッガ
デバッグ作業を支援するソフトウェアを「デバッガ」(debugger)あるいは「デバッグツール」(debugging tool)という。“debugger” は英文法的には「デバッグを行う者」という意味だが、プログラムを自動的に修正してくれるわけではなく、バグの位置を特定するためにプログラムの動作状況を解析・可視化する機能などを提供するものを指し、デバッグ作業自体は人間の開発者が行う。
構文エラー 【シンタックスエラー】
プログラミング言語などの人工言語で記述したコードが、定められた構文規則(シンタックス)を満たしていないときに発生するエラー。コードを正しく解釈できないため処理は打ち切られる。
人間が読み書きするコンピュータプログラムであるソースコードはプログラミング言語などの仕様に従って記述される必要がある。言語処理系がこれを解釈してコンピュータが直に理解可能な形式(機械語のプログラムなど)に変換する際、プログラムが構文規則に照らして誤っている場合に構文エラーが生じる。
構文エラーが発生するとそれ以上変換や実行などを続行することはできないため、処理系がエラーメッセージを表示するなどして停止する。誤った記述を修正すれば正しく解釈・変換できるようになるが、あくまでコードが言語仕様に形式的に適合しているか否かの問題であり、エラーが解消されたからといって実行結果が開発者の意図した通りになっているとは限らない。
開発時にコンパイラなどでソースコードを実行形式(ネイティブコードなど)に変換する言語や処理系では構文エラーはコンパイル時エラーだが、実行時にインタプリタなどがソースコードを解釈しながら実行する言語や処理系では構文エラーは実行時エラー(ランタイムエラー)となる。
構文エラー 【シンタックスエラー】
プログラミング言語などの人工言語で記述したコードが、定められた構文規則(シンタックス)を満たしていないときに発生するエラー。コードを正しく解釈できないため処理は打ち切られる。
人間が読み書きするコンピュータプログラムであるソースコードはプログラミング言語などの仕様に従って記述される必要がある。言語処理系がこれを解釈してコンピュータが直に理解可能な形式(機械語のプログラムなど)に変換する際、プログラムが構文規則に照らして誤っている場合に文法エラーが生じる。
文法エラーが発生するとそれ以上変換や実行などを続行することはできないため、処理系がエラーメッセージを表示するなどして停止する。誤った記述を修正すれば正しく解釈・変換できるようになるが、あくまでコードが言語仕様に形式的に適合しているか否かの問題であり、エラーが解消されたからといって実行結果が開発者の意図した通りになっているとは限らない。
開発時にコンパイラなどでソースコードを実行形式(ネイティブコードなど)に変換する言語や処理系では文法エラーはコンパイル時エラーだが、実行時にインタプリタなどがソースコードを解釈しながら実行する言語や処理系では文法エラーは実行時エラー(ランタイムエラー)となる。
ランタイムエラー 【実行時エラー】
コンピュータプログラムの実行時に発生するエラーのこと。実行を継続できないほどの致命的な問題であり、プログラムはその時点で実行を中断して直ちに異常終了させられる。
通常、プログラムは開発時に人間の記述したソースコードからコンピュータの実行可能な形式に変換(コンパイル/アセンブル)されるため、この段階で解釈・変換できないようなコードの形式的な記述の誤りや欠陥については検知・修正される。
実行時エラーはこのような形式上のチェックでは未然に防げない種類のエラーであり、処理の内容や実行時の状況により様々な要因により発生する。実行時の環境や入力データ、外部との入出力などに異状や想定外の状況が生じたり、単体では問題ない複数のコードの組み合わせや論理に致命的な矛盾や欠陥がある場合などに発生することが多い。
例えば、処理可能な範囲を大幅に外れた値や長過ぎるデータの入力が行われたり、起動時に確保できたメモリ容量が最低限必要なサイズを下回っていたり、実行に必要なライブラリなど外部のプログラムが実行環境に存在しないなど、開発時の想定や前提が成立しない状態に陥ると実行時エラーを生じて終了せざるを得なくなる。
また、連続したメモリ領域に先頭から順番にデータを書き込んでいくような処理を記述する際に、終端を検知して終了するコードを記述し忘れると、実行時に領域の終端を超えて書き込みを行おうとしてしまい言語によっては実行時エラーとなる。個々のコードの記述が形式的に正しく、実行可能なプログラムが構成できても、全体としては誤った論理に基づいてプログラムが作成されているためにこのような事態が生じる。
一方、ソースコードから実行形式に変換する際にコード記述の形式的な誤りなどにより生じるエラーを「コンパイルエラー」(complile error)という。コンパイル処理は中断され、実行可能なプログラムは作成されない。また、開発時にコンパイル等の工程がなくソースコードを実行時に動的に実行可能コードに変換するタイプの言語(スクリプト言語)や言語処理系(インタプリタ/仮想マシンなど)の場合には、コードの形式的な誤りも含めすべてのエラーが実行時エラーとなる。
ダイアグラム 【ダイヤグラム】
図表、図式、略図、図形などの意味を持つ英単語。日本語の外来語としては、鉄道などの運行図や運行表を意味する「ダイヤ」が “diagram” (より正確には “service planning diagram”)の略であることでよく知られている。
多数の要素や値などで構成される情報を視覚的に分かりやすく表すため、幾何学的な図形などを組み合わせて作成した抽象的、模式的な図を意味する。
一般的には、多角形や円、線分、矢印などの単純な図形、ラベル(短い表題)、数字、記号などを組み合わせ、対象の構造や構成、特性、要素間の関係性などの質的な側面を一定の作図ルールに基づいて描画したものを指す。フローチャートやPERT図(アローダイアグラム)、樹形図、ネットワーク図、回路図、組織図などが該当する。
グラフ (chart)
広義には、値の推移や分布、変数間の関係など対象の量的な側面を図形の長さや広さに対応付けて描画した図が含まれる。棒グラフや折れ線グラフ、円グラフ、数学の関数グラフ、散布図、ヒストグラム、株価チャートなどである。
これらは日本語(の外来語)では「グラフ」、英語では “chart” (チャート)と総称されるもので、情報を図示する手法の総称を “diagrams and charts” と呼ぶことがあるため、狭義にはグラフ類はダイアグラムに含まれないとする考え方もある。
また、より広義には、要素を碁盤目状に整然と並べた表(テーブル)や数学の行列、模式化された地図(鉄道路線図など)、機械や建物の設計図、組み立て図など、何らかの幾何学的な整理や抽象化が行われた視覚表現はすべてダイアグラムの一種であると考える場合もある。
フローチャート 【流れ図】 ⭐⭐⭐
工程や手順の流れを図示する手法の一つで、個々の段階を箱で表し、それらを順序や論理の推移に従って矢印や線分で結んだもの。
ITの分野では、コンピュータプログラムの設計やアルゴリズム(計算手順)の理解などのために、内部で行われる処理や演算の詳細な流れをフローチャートに表すことが多い。プログラムに限らず、業務手順など様々な過程や手順の図示に応用できる。
一つのフローチャートには開始と終了があり、その間に一つ以上の工程が含まれる。流れは分岐や繰り返しによって複数に枝分かれしたり戻ったりすることがあるが、途中どのような経路を通っても必ず一つの開始から始まって一つの終了で終わる。
フローチャートで用いる部品の種類や図記号の形状はJIS X 0121で規格化されており、一般的にはこれを用いることが多い。主な部品として、開始や終了を表す「端子」(円・楕円・角丸長方形)、「処理」(長方形)、プログラムにおけるサブルーチンや関数などの「定義済み処理」(左右が二重線の長方形)、「入出力」(平行四辺形)、条件分岐などの「判断」(菱形)、繰り返しの範囲を示す「ループ端」(開始は上側、終了は下側の角が欠けた長方形)、他の図との出入り口を示す「結合子」(小さな丸)、処理の流れを示す「線」(右や下へは線分・左や上には矢印)などがある。
ループ
輪(状のもの)、環(状のもの)、仲間内、閉回路、などの意味を持つ英単語。ITの分野では、環状あるいは循環構造になっているものや、繰り返しのことを意味する。
通信経路のループ
ネットワークの分野では、通信ケーブルの配線や転送経路が循環構造になっている状態をループという。ループに迷い込んだ信号やデータは永久にその中をぐるぐる回り続け、回線資源を消費し尽くしてしまうため、障害の原因となる。
プログラムのループ
コンピュータプログラムの中で、プログラム中の特定の箇所を繰り返し実行することや、そのような制御構造やプログラムコードをループという。
多くのプログラミング言語にはループを制御するための命令や構文が用意されており、開発者が指定した繰り返し回数や終了条件などに基づいて処理が繰り返される。利用する制御文の違いにより「forループ」「whileループ」などと呼ばれる。
一回処理を行うごとに、ループ先頭に戻って再度繰り返すかループを終了するか判定するようになっている場合が多く、このような判定を処理の手前で行うことを「前判定ループ」、処理の後に行うことを「後判定ループ」という。このような判定がなく、永久に繰り返すように指定されたループのことを「無限ループ」という。
ループの先頭や終端以外の部分でループの制御ができる命令などが用意されている場合もある。C言語などではbreak文でループを強制終了、continue文でその回のループ終端までの処理をスキップできる。コード中の任意の位置に実行を移すgoto文が用意されている言語では、これを使ってループ中からループ外へ強制的に脱出できる場合もある。
状態遷移図 ⭐⭐
対象がどのような状態を持ち、どのような条件や出来事(イベント)によりそれらの間を遷移するかを一覧に表した図。
様々な表現形式があるが、一般的な手法では、対象が取りうる状態を円や矩形などで列挙し、どこからどこへ遷移が起きうるかを矢印によって示す。各矢印の脇に、その遷移が起きるための条件やきっかけとなる出来事などを記述する。自らに遷移する場合は自分を指し示す輪っか状の矢印を書き入れる。
対象に開始や終了がある場合は、特殊な記号で示される場合がある。UMLでは開始を塗りつぶした丸印で、終了を内側を塗りつぶした二重丸で記載するよう定められている。
状態遷移表
状態遷移図の各状態を一行として表の形で書き表したものを状態遷移表という。
一般的な形式では、各行が対象の状態を、各列がイベントを表し、ある状態のときにあるイベントが起きたときにどの状態に遷移するかを書き入れていく。
また、縦軸・横軸ともに状態を並べ、各状態の交差する項目にそのような遷移が起こるイベントを書き入れていく様式もある。
ソフトウェア開発の分野ではテストを行う際にテストケースを漏れなく網羅するために状態遷移表が作成される場合がある。
ステートマシン図 (state machine diagram)
ソフトウェアの設計などに用いられるUML(Unified Modeling Language)では、状態遷移図に相当する図をステートマシン図(state machine diagram)として定義している。
あるオブジェクトの振る舞いを漏れなく記述するために用いられるもので、開始状態を塗りつぶした丸印(●)、終了を内側を塗りつぶした二重丸で表し、途中の状態を角丸の矩形を並べて図示していく。
状態間は遷移する方向に矢印で繋ぎ、脇に遷移の説明を添える。遷移したときに実行する動作がある場合は矩形を横に区切って下半分に動作の内容を記述する。
状態遷移図
対象がどのような状態を持ち、どのような条件や出来事(イベント)によりそれらの間を遷移するかを一覧に表した図。
様々な表現形式があるが、一般的な手法では、対象が取りうる状態を円や矩形などで列挙し、どこからどこへ遷移が起きうるかを矢印によって示す。各矢印の脇に、その遷移が起きるための条件やきっかけとなる出来事などを記述する。自らに遷移する場合は自分を指し示す輪っか状の矢印を書き入れる。
対象に開始や終了がある場合は、特殊な記号で示される場合がある。UMLでは開始を塗りつぶした丸印で、終了を内側を塗りつぶした二重丸で記載するよう定められている。
状態遷移表
状態遷移表の各状態を一行として表の形で書き表したものを状態遷移表という。
一般的な形式では、各行が対象の状態を、各列がイベントを表し、ある状態のときにあるイベントが起きたときにどの状態に遷移するかを書き入れていく。
また、縦軸・横軸ともに状態を並べ、各状態の交差する項目にそのような遷移が起こるイベントを書き入れていく様式もある。
ソフトウェア開発の分野ではテストを行う際にテストケースを漏れなく網羅するために状態遷移表が作成される場合がある。
ステートマシン図 (state machine diagram)
ソフトウェアの設計などに用いられるUML(Unified Modeling Language)では、状態遷移表に相当する図をステートマシン図(state machine diagram)として定義している。
あるオブジェクトの振る舞いを漏れなく記述するために用いられるもので、開始状態を塗りつぶした丸印(●)、終了を内側を塗りつぶした二重丸で表し、途中の状態を角丸の矩形を並べて図示していく。
状態間は遷移する方向に矢印で繋ぎ、脇に遷移の説明を添える。遷移したときに実行する動作がある場合は矩形を横に区切って下半分に動作の内容を記述する。
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(Unified Modeling Language)で規定された図(ダイアグラム)の一つで、実際の場面において登場する具体的なオブジェクトとそれらの間の関係を表したもの。
オブジェクト(object)は設計時にはその雛形であるクラス(class)によって定義されるが、ソフトウェアの実行時など実際の場面では具現化されたインスタンス(instance)として登場する。オブジェクト図は系のある時点におけるインスタンス同士の関係を記述することでシステムの挙動などを詳細に知らせることができる。
オブジェクトは長方形で示され、内部にオブジェクト名が記入される。オブジェクト名には下線が引かれ、クラスに所属している場合には「:」に続けてクラス名を記入する。
オブジェクトが何らかの属性や状態を持つ場合には、長方形を上下に区切り、下側の区画に「属性名=属性値」の形式で列挙する。オブジェクトと別のオブジェクトの間に何らかの関連がある場合は直線(リンクと呼ばれる)で結び、線の脇にそれらの関係を記入する。
オブジェクト図は業務やシステムのある時点における具体的な状況を理解したり説明する助けになり、クラス図を作成するための分析に用いられたり、定義されたクラスなどが適切か否かを検証するために用いられることが多い。
クラス図
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)で規定された図(ダイアグラム)の一つで、業務や処理の実行手順を表したもの。
アクティビティ図ではそれ以上分割できない最小の動作単位を「アクション」(action)と呼び、角丸四角形で図示する。アクションを組み合わせたひとまとまりの動作を「アクティビティ」(activity)と呼ぶ。
活動の開始ノード(黒丸で示される)から終了ノード(丸で囲った黒丸で示される)までの間にアクションやアクティビティを配置し、それぞれの依存関係に従って矢印で結んでいく。
次のアクションへ情報などが受け渡される場合には、中間に四角形で示す。矢印で結ばれた手順の流れを「フロー」(flow)という。異常終了などでフローが途中で終了する場合には、終了地点に丸囲みの×印を記す。
アクティビティ図全体を縦または横(あるいはその両方)に分割して実行主体や段階を示すことができる。アクションやアクティビティが分割されたどの領域に存在するかによって、どの主体による動作かを示したり、どのような段階に行われる動作かを示すことができる。
フローの分岐・合流
特定の条件に従ってフローが分岐する場合には、菱形の「デシジョン」(decision:判断)ノードを置いて2方向に矢印を記し、それぞれの脇に条件を記述する。フローが合流する地点には同じ菱形の「マージ」(merge:合流)ノードを置く。
ある時点から複数のフローを並列に実行する場合には、その開始地点に太い直線で示される「フォーク」(fork:分岐)ノードを置き、複数のフローを出発させる。これらの同期を取って一つのフローに戻したい場合には、同じく太い直線の「ジョイン」(join:結合)ノードを置き、フローを集合させる。
DFD 【Data Flow Diagram】
情報システムの設計などで作成される図の一つで、要素間のデータの流れを表した図。データがどこで発生し、どこからどこへ運ばれ、どこへ出力・保管されるのかを図示することができる。
システムが扱うデータの流れを整理するための図法で、対象となるシステムと利用者や外部のシステムなどのデータの流れを図示する場合と、システム内の構成要素(データストアやプロセスなど)間の流れを図示する場合がある。
データは発生源から様々な処理(プロセス)を経て出力先へ収まる。一つの図にあまり多くの要素を図示すべきではないとされ、。全体的で抽象的なレベルから作図し、段階的に詳細化した図を描いていくという手法が用いられることが多い。
データフロー図では、データの保管や取り出しを行う「データストア」を平行な上下二本線で、データを処理するソフトウェアなどの「プロセス」を丸で、データの発生源や出力先である「外部実体」(ターミネータ)を長方形あるいは楕円で示す。これらの要素の間をデータの流れ(フロー)を表す矢印で結んでいく。
プロセスには入力と出力を表す「フロー」がそれぞれ一つ以上必要で、データストアや外部実体は入力または出力のいずれか一方のフローが必要となる。また、各フローの一方の端は必ずプロセスでなければならない。
プログラミング言語 ⭐⭐⭐
主に人間がコンピュータプログラムを記述、編集するために用いる人工言語。作成したプログラムは機械語による記述に変換した後、コンピュータで実行できるようになる。
プログラミング言語でプログラムを開発することを「プログラミング」(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)などの分類がある。
プログラミング言語
主に人間がコンピュータプログラムを記述、編集するために用いる人工言語。作成したプログラムは機械語による記述に変換した後、コンピュータで実行できるようになる。
プログラム言語でプログラムを開発することを「プログラミング」(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)などの分類がある。
高水準言語 【高級言語】 ⭐
プログラミング言語の分類の一つで、抽象的な語彙や記法、構文などを用いて処理を記述することができる言語の総称。
「高水準」「高級」とは優れた言語という意味ではなく、機種やOSなどに固有の要素を極力排し、抽象度の高い記述が可能であることを表しており、アプリケーションソフトの開発などに用いられる言語の多くは高水準言語に分類される。
これに対し、コンピュータ(CPU)が直接解釈・実行できる機械語(マシン語)や、機械語と一対一に対応するアセンブリ言語などのことは「低水準言語」(low-level programming language)あるいは「低級言語」と呼ぶ。ここでの「低」はハードウェアに近いという意味である。
高水準言語は英語など自然言語の語彙や構文を利用したり、数式に似た記号や記法などを取り入れることにより、人間が記述・読解しやすい構造となっている。言語仕様はハードウェアやOSの仕様とは切り離された抽象的なものになっており、様々な環境で同じように動作する汎用的なソフトウェアの開発に向いている。
一方、ハードウェアへの直接的なアクセスやハードウェア固有の機能の利用は制限されており、また、CPUの振る舞いを細かく記述して性能を引き出すことも難しい。デバイスドライバのように装置を直接制御するような用途や、複雑で高度な機械の制御ソフトのように応答時間に強い制約があるような環境にはあまり向いていない。
高水準言語を使って人間の記述したプログラム(ソースコード)はそのままではコンピュータが解釈できないものであるため、変換ソフトウェアによって機械語による実行可能なプログラム(オブジェクトコード)に変換されて実行される。開発時にまとめて変換するものを「コンパイラ」(compiler:翻訳者の意)、実行時に逐次変換しながら並行して実行するものを「インタプリタ」(interpreter:通訳者の意)という。
低水準言語 【低級言語】 ⭐
プログラミング言語のうち、コンピュータが直接解釈・実行できる機械語や、機械語に近い言語の総称。
「低水準」「低級」とは劣った言語であることを意味するのではなく、ハードウェアに近いことを意味する。これに対し、人間の理解しやすいように設計された言語を「高水準言語」(高級言語)と呼ぶ。
一般的に低水準言語といった場合、マイクロプロセッサ(CPU/MPU)などが直接解釈・実行できる「機械語」(マシン語)と、機械語と一対一に対応する「アセンブリ言語」(ニーモニック)のことを意味する。
機械語は0と1を並べたビット列として表され、人間が読み取ったり記述したりするのは容易でないため、実際には命令コードなどを英単語などのシンボルに置き換えたアセンブリ言語でプログラムを記述し、変換ソフトウェア(アセンブラ)でマシン語のコードに変換して実行することが多い。
低水準言語は装置を直接制御するコードを記述するため、ハードウェアの機能をフルに利用することができ、機種ごとに固有の機能もすべて利用することができる。反面、仕様はメーカーや機種ごとにまちまちで、仕様が異なると同じプログラムが動作せず、汎用性は低い。
また、CPUの細かい振る舞いを直接記述することができるため、CPUの性能を引き出して高速なプログラムを記述することができ、プログラムサイズもコンパクトに抑えることができるが、制御構文などは単純で貧弱なため、大規模なソフトウェアの開発には向かない。
コンピュータの性能が向上し、様々な種類の高水準言語が普及した現在では低水準言語を利用する機会は減ったが、上記のような特徴から、現在でも周辺機器のドライバソフトや産業機器の組み込みソフトなどの開発によく利用される。
アセンブリ言語
プログラミング言語の類型の一つで、コンピュータのCPU(MPU/マイクロプロセッサ)が直接解釈・実行できる機械語(マシン語)と正確に対応する命令語で構成された言語。
人間が実用的に使用できるプログラミング言語で最も機械に近い低水準(低級)な言語で、具体的な仕様はプロセッサの機種(命令セットアーキテクチャの種類)ごとに異なる。
コンピュータはCPUがプログラムとして与えられた機械語の命令列を順番に実行することで処理を行うが、機械語の命令は「オペコード」(opcode)と呼ばれる識別番号(正確にはビット列)で表されるため、これを直に人間が記述してプログラムを作ることは困難で、無理に書いたとしても後から読み解くのが難しく、書き間違いも起きやすい。
そこで、それぞれのオペコードに対応する「ニーモニック」(mnemonic)と呼ばれる短いアルファベットの命令語を定義し、これを用いてプログラムを記述する手法が考案された。あるプロセッサのオペコードの体系に対応するニーモニックの集合を定義したものを、そのプロセッサに対するアセンブリ言語という。
例えば、米インテル(Intel)社の8086プロセッサにおいて、指定されたレジスタの値を指定されたメモリ番地に書き込む命令は「10001000」というビット列で表され、十進表記では136、16進表記では88となるが、これに「mov」というニーモニックを対応付ければ何をする命令なのか分かりやすい。
オペコードとニーモニックの対応関係
機械語の場合、値を代入するという同じ動作でもオペランド(引数)として指定される対象の組み合わせ(即値→レジスタ、レジスタ→レジスタ、レジスタ→メモリなど)によって異なるオペコードが割り当てられている場合がある。これらは動作に即して同じニーモニックで表されることが多く、オペランドの組み合わせから適切なオペコードに変換される。
このため、オペコードとニーモニックは必ずしも正確に一対一には対応していないが、ある命令セットを完全に実装したアセンブリ言語では、どのオペコードにも必ず対応するニーモニックが用意されている。
アセンブラ/アセンブル
アセンブリ言語で記述されたソースコードはそのままでは実行できないため、アセンブラ(assembler)と呼ばれるソフトウェアで機械語のプログラムに変換されてから実行される。この変換処理をアセンブル(assemble)という。
アセンブラは機械語への置き換えだけでなく、マクロの展開や、シンボル名を実際の値やメモリアドレスに置き換えたりといった処理も行なう。
ニーモニックの体系はアセンブラに実装されるため、同じ命令セットに対応したアセンブラでもアセンブリ言語は異なっていることがある。ただし、通常はプロセッサの開発元が命令セットの仕様を公開・提供する際に標準のニーモニックを公表するため、これに沿った実装が行われる。
機械語 【マシン語】 ⭐⭐
コンピュータのマイクロプロセッサ(CPU/MPU)が直接解釈・実行できる命令コードの体系。0と1を並べたビット列として表され、人間が直に読み書きしやすい形式ではない。
プロセッサは設計段階でどのような命令番号(オペコード)が与えられたらどのように動作するかが決められている。機械語のプログラムは基本的に命令番号を実行順に並べたデータとなっており、個々の命令には必要に応じて処理すべき対象となるデータ(オペランド)などを付記する。
機械語はプロセッサに直接命令を与える言語であるため、プロセッサの持つすべての機能を利用することができる。どのようなプログラミング言語で記述されたプログラムであっても、ソフトウェアによる変換や調整を経て最終的には機械語のプログラムとしてプロセッサに渡され実行される。
ニーモニックとアセンブリ言語
人間が命令番号そのものを暗記して直にプログラムを記述するのは容易ではないため、各番号に意味を類推しやすいアルファベットの並び(ニーモニック)を一対一に対応付け、これを用いてプログラムを記述する手法が用いられる。このようにして作られたプログラミング言語をアセンブリ言語(assembly language)という。
アセンブリ言語によるプログラミングはハードウェアを直に制御でき、短く高速なプログラムを記述することができるが、大規模で複雑なプログラムや大人数での分業などには向いていない。OSやデバイスドライバなどハードウェアを直接的に制御する必要のあるプログラムや、極めてシビアに実行速度が求められる場面などで部分的に用いられることが多い。
命令セットとプログラムの互換性
命令番号と動作の対応関係、および各命令に付随するオペランドの形式などを定めた体系は命令セットアーキテクチャ(ISA:Instruction Set Architecture)あるいは単に命令セットと呼ばれ、同じ命令セットを持つプロセッサ間では互いに同じ機械語プログラムをそのまま実行することができる。
一般に、同じメーカーの同じ製品シリーズのプロセッサ製品間は同じ命令セットを共有し、新しい製品に新たな命令が追加されるようになっており、異なるモデルや世代の製品間でも同じ機械語プログラムを動作させることができる。異なるメーカーが同じ命令セットを実装した製品を開発する場合もあり、互換プロセッサなどと呼ばれる。
命令セットが異なるプロセッサ間では同じ機械語プログラムは動かないため、プログラムのソースコードからコンパイルなどの処理を行ってそのプロセッサの命令セットによって記述された機械語プログラムを生成する必要がある。
手続き型言語 【命令型言語】 ⭐
プログラミング言語の分類の一つで、コンピュータが実行すべき命令や手続きを順に記述していくことでプログラムを構成する言語。
命令は一つずつ記述して並べることもできるが、多くの言語では複数の命令をひとまとまりの手続きに連結し、外部から一つの大きな命令のように呼び出せるようにする機構を備えている。この手続きは言語により「プロシージャ」(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)などを含む。
関数型言語 【関数型プログラミング言語】 ⭐
プログラミング言語の分類の一つで、プログラム中の処理や制御を関数の定義と適用の組み合わせとして記述していくもの。そのようなスタイルでコードを記述することを「関数型プログラミング」(functional programming)という。
プログラミング言語の多くは手続き型(procedural)あるいは命令型(imperative)と呼ばれる形式で、コンピュータに対する動作の指示を一つずつ順番に並べるスタイルでプログラムを記述していく。
これに対し関数型言語ではプログラムを、引数を入力として処理を行い、呼び出し元に返り値を出力する関数(function)の組み合わせとして記述する。手続き型でも関数の仕組みは利用できるが、関数型言語はほとんどありとあらゆるものを関数の定義と関数呼び出しを用いて実現する点で徹底している。
例えば、同じ処理を規定の回数や条件に従って繰り返す反復処理は、手続き型では一般的にfor文やwhile文などの制御構文を用いるが、関数型言語では関数の再帰呼び出しによって実装される。
関数型言語の主な特徴
関数型言語の多くに共通する特徴として、関数を変数と同じようにほとんどの操作が可能な第一級オブジェクト(first-class object)として扱う点があり、関数を引数や返り値とする「高階関数」(higher-order function)を定義することができる。
また、変数や関数の引数、返り値などを記述する際に、明示的にデータ型を宣言しなくても処理系が自動的に推定して適した処理を行ってくれる「型推論」(type inference)の機能もほとんどの言語が持っている。
参照透過性と純粋関数型言語
同じ入力には必ず同じ作用と出力を返す性質を「参照透過性」(referential transparency)と呼び、参照透過な記述のみで構成されたプログラムは、その評価や実行が以降の処理に思わぬ影響を及ぼす「副作用」(side effect)のないプログラムとなる。
関数型言語ではすべてを関数とすることで参照透過性を保ちやすくなっており、手続き型のプログラミングで開発者を悩ませ続ける副作用の問題を解消しやすい。ただし、外部との入出力など参照透過性を維持するのが本質的に難しい場面もあるため、多くの関数型言語は実用性との兼ね合いから参照透過的でない記述ができるようになっていることが多い。
参照透過的な記述しかできないようになっている言語を「純粋関数型言語」と呼び、Haskellがよく知られる。そうでないものは「非純粋関数型言語」と呼ばれ、Lisp、Scheme、ML(Meta-Language)、OCaml、Scala、Clojure、Erlang、F#など、よく知られる関数型言語のほとんどはこちらに分類される。
関数型言語と関数型プログラミング
関数型言語の研究や普及が進むに連れて、手続き型など他の種類のプログラミング言語にもその特徴が取り込まれるようになってきており、無名関数や高階関数、型推論などは多くの言語に実装されている。
「関数型プログラミング」とは関数型言語によるプログラミングだけでなく、手続き型言語などを用いて関数を組みわせてプログラムを構成する手法が含まれる。逆に、形式的には関数型言語を使っていても、代入など手続き型の特徴ばかりを用いてプログラムを構成していれば、それはもはや関数型ではなく手続き型プログラミングであると言える。
オブジェクト指向言語 【オブジェクト指向プログラミング言語】
プログラミング言語のうち、互いに関連するデータの集合とそれらに対する手続き群をひとまとめにした「オブジェクト」(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のように関数型かつオブジェクト指向の言語などもある。
コンパイラ型言語 【コンパイラ方式】 ⭐
かつて用いられた高水準プログラミング言語の分類の一つで、公式あるいは主要な処理系がコンパイラであるような言語のこと。
コンパイラ(compiler)はプログラミング言語で記述されたソースコードを解釈し、実行可能な機械語(マシン語)などのコードに一括して変換するソフトウェアで、変換後のコードを元に実行可能ファイルを作成して実行される。
記述したコードを実行に移すまでに手間や準備時間が必要だが、機械語への変換と実行が分離されるため、プログラムを少ない消費メモリで高速に実行でき、実行時にソースコードが不要(利用者へソースコードを提供しなくてよい)という特徴がある。
コンパイラ型言語は言語の開発元が提供する公式の処理系や、広く普及している主要な処理系がコンパイラであるような言語を指し、機械語コードへ変換しながら同時に実行する「インタプリタ型言語」(インタプリタ言語)と対比される。
このような分類は現代よりもプログラミング言語とその処理系が密接に関連付けられていた1990年代以前によく用いられたが、インタプリタとコンパイラのどちらを用いるかは言語そのものの特性ではなく、実際、今日では一つの言語に両者が標準的に提供されることも少なくないため、このような分類を用いることはほとんどなくなった。
インタプリタ型言語 【インタプリタ方式】 ⭐
かつて用いられた高水準プログラミング言語の分類の一つで、公式あるいは主要な処理系がインタプリタであるような言語のこと。
インタプリタ(interpreter)はプログラミング言語で記述されたソースコードを解釈し、実行可能な機械語(マシン語)のコードに変換しながら同時に実行するソフトウェアで、変換処理の分だけ消費メモリ容量や実行速度は犠牲になるが、ソースコードを与えるだけで即座に実行できるという特徴がある。
インタプリタ型言語は言語の開発元が提供する公式の処理系や、広く普及している主要な処理系がインタプリタであるような言語を指し、機械語コードへの変換を一括して行い、実行可能ファイルを生成してから実行する「コンパイラ型言語」(コンパイラ言語)と対比される。現代では、いわゆるスクリプト言語が該当する。
このような分類は現代よりもプログラミング言語とその処理系が密接に関連付けられていた1990年代以前によく用いられたが、インタプリタとコンパイラのどちらを用いるかは言語そのものの特性ではなく、実際、今日では一つの言語に両者が標準的に提供されることも少なくないため、このような分類を用いることはほとんどなくなった。
マクロ 【マクロ言語】 ⭐
関連する複数の操作や手順、命令などを一つにまとめ、必要に応じて呼び出すことができるようにする機能のこと。アプリケーションソフトの定型的な操作の自動化などに用いられる。
ソフトウェア操作のマクロ
アプリケーションソフトの操作を自動化する機能の一つにマクロ言語がある。利用者が複数の操作手順を一連の手続きとして記録したもので、簡単な操作で繰り返し実行することができる。
利用者はマクロ言語登録開始に操作の後、操作画面上で登録したい一連の操作を行い、記録終了の操作を行う。この間の操作はデータとして記録され、録音した音声を再生するように簡単な操作で何度も繰り返し呼び出すことができる。
業務上何度も繰り返し行わなければならない定型的な作業を自動化することができ、文書内の複数の個所や複数の文書に同じ操作を行わなければならない場合などに利用される。
Microsoft Excelのマクロ機能など、表計算ソフトでよく利用される機能で、記録した操作をスクリプト言語などで表し、後から編集できる機能を持ったソフトもある。キー操作を記録して再生できるようする機能は「キーボードマクロ」と呼ばれる。
プログラミングのマクロ
プログラミングの分野では、ソースコード中に繰り返し登場する特定の記述を、別の(短い)記述に置き換えることができる機能をマクロ言語という。
複数の命令をまとめて一つの命令のように記述したり、複数の箇所で参照される定数の値を後からまとめて変更できるようシンボル名で記述するのに使われる。
関数のようなプログラミング言語の持つ仕様や機能ではなく、アセンブラやコンパイラなどの機能として提供されるもので、コンパイルなどの前処理としてソースコードを単純に文字列置換することにより実現される。C言語などではプリプロセッサと呼ばれる専用のプログラムで処理される。
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++言語が用いられることが多い。
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がよく知られる。
スクリプト言語 【軽量言語】
プログラミング言語の一種で、オペレーティングシステム(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ブラウザに対するマクロ言語のような用途として発明されながら、拡張や移植を重ねて汎用的な言語として様々な機能や実行環境を獲得した例もある。
JavaScript 【JS】 ⭐
主にWebページに組み込まれたプログラムをWebブラウザ上で実行するために用いられるプログラミング言語の一つ。いわゆるスクリプト言語の一つで、近年ではブラウザ以外の実行環境でも利用される。
主な特徴
C言語やJavaに似た記法や文法を採用した手続き型の言語で、簡潔な記述でプログラムを開発することができる。関数を変数のように(第一級のオブジェクトとして)扱ったり、関数を引数に取る高階関数を定義できるなど、関数型プログラミング言語の仕様も取り込んでいる。
オブジェクト指向にも対応しているが、他の多くの言語で一般的な、オブジェクトの雛形を定義したクラスを用いる方式(クラスベース)ではなく、既存のオブジェクトを複製して機能を追加していく「プロトタイプベース」と呼ばれる手法を採用している。
Webブラウザでの利用
WebページのHTMLファイル内に特殊な記法を用いて埋め込まれて記述され、Webブラウザに内蔵された言語処理系によってページの表示時に解釈・実行されることが多い。スクリプトのみを記述したファイル(.jsファイル)を読み込む形で利用されることもある。ページ内の要素に動きや効果を加えたり、閲覧者の操作に即座に反応して何らかの処理を行ったりするのに用いられる。
主要なWebブラウザの多くが標準で対応しているが、ブラウザの種類やバージョンによって仕様や挙動に違いがあり、開発者を悩ませ続けている。他の言語の場合にも見られる言語そのものの仕様・実装の違い(バージョンの違いや各社独自の拡張や仕様・実装の相違)の他に、HTMLやCSSの仕様や解釈の相違や、スクリプトからWebページ上の表示要素を扱う際に必要となるDOM(Document Object Model)と呼ばれるAPIの違いもあるため、複数のブラウザで同じように動作するスクリプトを開発するのは一筋縄ではいかない。
他の実行環境
近年ではWebブラウザに留まらず様々な環境に言語処理系が移植され、様々な用途で使用されている。Node.jsやASP.NETのようにWebサーバ上でプログラムを実行して動的にWebブラウザに応答を返すシステムや、オペレーティングシステム(OS)上で直に実行可能な処理系(Windows Scripting Hostなど)がよく知られる。米アドビ(Adobe)社の「Flash」では標準のスクリプト言語に採用されていた(正確にはActionScriptと呼ばれる方言)。
AltJS
開発効率や保守性、プログラムの読みやすさなどの改善、よく起こりがちな誤りの防止などを目的に、JavaScriptを元に独自の機能や仕様を追加したり、文法や記法の追加・変更を行った言語がいくつか開発されており、「AltJS」(Alternative JavaScript)と総称される。
これらの言語で書かれたプログラムは「トランスパイラ」(transpiler:トランスコンパイラの略)と呼ばれる変換ソフトにより一旦JavaScriptによる表記に変換されるため、JavaScriptの実行環境さえあれば通常のスクリプトと同じように実行できる。著名なものには「TypeScript」や「JSX」、「CoffeeScript」などがあり、Webアプリケーションの開発現場などでよく利用される。
Javaとの違い
名称にプログラミング言語「Java」の語を冠しているが、他の「Java○○」技術とは異なり、Java言語の拡張仕様や関連技術などではなく、記法や予約語などの一部が共通していること以外に直接的な繋がり互換性はない。
実際、型システムや関数、オブジェクト指向の扱いなど言語仕様の根本的な部分のいくつかがJavaとは大きく異なる。かつてはJavaにもWebページ内にプログラムを埋め込んで実行する「Javaアプレット」と呼ばれる仕組みがあったため、主に技術者以外のWebに携わる人々にとって名称が紛らわしく、しばしば混同や取り違えが発生した。
歴史
1995年にネットスケープ・コミュニケーションズ(Netscape Communications)社(当時)のブランダン・アイク(Brendan Eich)氏によって開発され、当時最も人気の高いWebブラウザだった「Netscape Navigator 2.0」に初めて実装された。
当初は「LiveScript」(ライブスクリプト)という名称だったが、同社がJava開発元のサン・マイクロシステムズ(Sun Microsystems)社(当時)と提携していたことから、Javaの名称を冠してJavaScriptに改称された。
1997年にはEcma International(エクマ・インターナショナル)によって「ECMAScript」の名称で仕様が標準化され、ISOやJISなども同様の規格を標準化した。ECMAScriptは20年以上に渡って活発に改版を重ねており、各社の処理系もこれに準拠する形で機能追加が進められている。
Python ⭐⭐
簡潔で読みやすい文法が特徴的な汎用の高水準プログラミング言語の一つ。いわゆるスクリプト言語の草分けの一つで、UNIX系OSを中心に広く普及している。近年では初学者向けの学習用途、統計処理やAI関連のプログラム記述用途として用いられることも多い。
基本的な特徴としては、豊富なデータ型とコンテナ型、ガベージコレクション、Unicodeによる多言語対応、プログラムのモジュール(部品)化による他のプログラムへの容易な組み込み、プログラムの仕様の文書化(ドキュメンテーション)を支援する機能などがある。
ユニークな特徴としては、多くの言語では人間にとってプログラムを読みやすくするために便宜的に行われるインデント(字下げ)を言語仕様上の構文の一つとして採用しており、ブロックの範囲を示すのに用いられる。
言語自体の文法や語彙、記法な最小限のシンプルなものに抑えられているが、対照的に、極めて広範囲の分野に渡り豊富な機能を提供する標準ライブラリが用意されている。当初は手続き型言語とオブジェクト指向言語の特徴を備えた言語として設計されたが、関数型言語の要素の多くを取り入れ、様々なスタイルのプログラミングが可能なマルチパラダイム言語として知られている。
他の言語や環境との連携機能も充実しており、Pythonからアクセスできない低レベルの機能をC言語で記述して拡張モジュールとして組み入れる仕組みが提供されているほか、Javaライブラリを利用できる実行環境の「Jython」や、Microsoft .NET環境で.NET Frameworkの機能を利用できる「IronPython」などの処理系もある。
標準の言語処理系(CPython)にはソースコードを読み込みながら同時に実行するインタプリタが含まれ、コンパイルやビルドなど手間や時間のかかる作業を省略して記述したプログラムを即座に実行してみることができる。この処理系はオープンソースソフトウェアとして公開されており、誰でも自由に入手、利用、改変、再配布などすることができる。
Pythonの最初のバージョンは1991年にオランダのグイド・ヴァン・ロッサム(Guido van Rossum)氏によって発表された。現在ではWebアプリケーションの開発用言語として人気が高いほか、データ処理や統計解析などの分野でよく利用されることで知られる。
Swift
米アップル(Apple)社の開発した手続き型プログラミング言語の一つ。同社のiOSやmacOS(旧Mac OS X)で動作するソフトウェアの開発に用いられる。同社のソフトウェア開発ツール「Xcode」が標準で対応している。初版は2014年に発表され、2015年にApacheライセンスに基づいてオープンソース化された。
C言語系の言語によく見られる記法を採用した言語で、手続き型を基本としながらオブジェクト指向や関数型言語の要素も含まれている。構造体(struct)や演算子のオーバーロードなどC言語/C++言語から引き継いだ機能に加え、ジェネリクスやクロージャ、タプル、辞書型、for-in文、関数のカリー化など、関数型言語やスクリプト言語に由来する現代的な機能が多く取り込まれている。
変数などの静的型付け、変数の初期値の省略禁止、if文の処理が1行だけでも中括弧(ブレース)を省略できない、switch文のフォールスルーは明示的に記述しなければ起こらないなど、あえて制限・制約を設けることで単純な記述ミスなどに起因するバグが発生しにくいよう配慮されている。
値が存在しないことを示す特殊な値として「nil」が用意されているが、これは原則として変数などへの代入が禁止されている。代わりに、これを安全に取り扱うためのデータ型としてオプショナル型(Optional Type)が用意されている。
Swiftの開発ツールはコンパイラ基盤として「LLVM」(Low Level Virtual Machine)を採用しており、LinuxやWindowsなど同社製以外の環境向けのソフトウェアも開発できる。配布パッケージを作成する場合などにはコンパイラで実行可能コードを生成するが、開発時にはスクリプト言語のようにその場ですぐに実行してみて動作を検証することもできる。
従来のiOS/macOS向けのソフトウェア開発ではC言語にオブジェクト指向拡張を行った「Objective-C」が標準的に使われてきたが、Swiftはより簡潔で見通しのよいコードを記述することができる。従来環境からの移行に配慮して、SwiftプログラムではObjective-CのAPIやクラス、メソッドなどを呼び出すことができ、Objective-C向けのライブラリやフレームワークもそのまま使える。
スクラッチ開発 ⭐
製品を開発する際に、すでに存在する何かを土台とせずにゼロから新たに作り上げること。
情報システム開発などでは、パッケージ製品のカスタマイズや機能追加、現在使用中のシステムの改修などによらず、全体を新たに開発する(あるいは、開発し直す)ことを指してScratchということが多い。
ソフトウェア開発やWebサイト制作では、元になるソースコードや雛形(テンプレート)などを使用せず、何も無い状態からコードを記述していくことをScratchという。他から流用する要素が一切無い場合を特に「フルスクラッチ」(totally from scratch)ということがある。
既存製品を流用する場合に比べ費用や期間はかかるが、パッケージの制約や過去のしがらみなどに縛られることが少なく、独自機能を組み込んで他社と差別化するといった施策も行いやすい。流用部分がブラックボックス化することがなく、改良や修正、機能追加の自由度も高い。
DSL 【Domain-Specific Language】
特定の作業の遂行や問題の解決に特化して設計されたコンピュータ言語。特定用途向けのプログラミング言語やマークアップ言語、モデリング言語などが該当する。
特定の領域や対象に関連する処理や定義の記述に特化した語彙や仕様を持つ言語のことを指し、C言語やXMLのように特定の用途や目的を持たない汎用のプログラミング言語やマークアップ言語などと対比される。
ただし、このような機能があればDSLであるとか、このような水準に達していれば汎用言語であるといったような厳密な基準や定義はなく、Webページの動的な生成に特化したDSLとして産まれながら、次第に機能が拡張され汎用的になっていったPHPのような例もある。
DSLには対象や領域ごとに様々な言語がある。各分野で特に著名な例としては、Webページ記述のためのHTML、スタイル記述言語のCSS、組版言語のTeX/LaTeX、ページ記述言語のPostScript、データベースへの問い合わせ言語SQL、電子回路設計のためのハードウェア記述言語(HDL)であるVerilogやVHDL、文字列のパターンを表現する正規表現、文脈自由文法を定義するBN記法(BNF)などがある。
元になる汎用の言語(ホスト言語)が存在し、その語彙や構文を借りながら、複雑な機能を制限、省略するなどして定義されたものを「組み込みDSL」(embedded DSL)あるいは「内部DSL」(internal DSL)と呼び、既存の言語とは無関係に独立に定義されたものを「外部DSL」(external DSL)という。
手続き型言語 【命令型言語】
プログラミング言語の分類の一つで、コンピュータが実行すべき命令や手続きを順に記述していくことでプログラムを構成する言語。
命令は一つずつ記述して並べることもできるが、多くの言語では複数の命令をひとまとまりの手続きに連結し、外部から一つの大きな命令のように呼び出せるようにする機構を備えている。この手続きは言語により「プロシージャ」(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)などを含む。
構造化プログラミング 【構造化手法】
コンピュータプログラムの開発や理解、修正を円滑に行えるよう、プログラムを整理された少数の定型的な構造の組み合わせによって記述すること。
一般的には「順接、反復、分岐の三つの制御構造のみを組み合わせて処理の流れを記述すること」と説明されることが多いが、これは本来の定義とは異なる誤解が広まったものだとも指摘される(後段で詳述)。
今日一般的に言われる構造化プログラミングとは、プログラム中のコードの実行順の制御を、記述した順番に実行する「順接」あるいは「順次」(sequence)、指定された条件が成り立つ間繰り返す「反復」あるいは「繰り返し」(iteration)、指定された条件を満たすか否かによって枝分かれする「分岐」あるいは「選択」(selection)の三つのみを組み合わせて記述することとされる。
特に、実行順の制御をこの三つに限定することにより、かつてのプログラミングで多用されていた、指定した任意の位置に無条件に移動する “goto” 文を排除し、処理の流れがあちこちへ飛んで見通しが悪くなるのを防ぐことが重要であると説明される。
構造化定理とその解釈
この原則は1966年にイタリアのコンピュータ科学者コラド・ベーム(Corrado Böhm)とジュゼッペ・ヤコピーニ(Giuseppe Jacopini)が証明した「構造化定理」(Structure theorem)あるいは「構造化プログラム定理」(Structured program theorem)によって基礎付けられているとされる。
確かにこの定理はすべてのアルゴリズムが順接、反復、分岐の三つの組み合わせで記述できることを示してはいるが、計算科学における理論上の可能性を述べており、これによって見通しの良いプログラムを開発できるといった趣旨の主張は含まれていない。
実際、高名なコンピュータ科学者のドナルド・クヌース(Donald Knuth)は、プログラムからgoto文を除去してこの三つの組み合わせに置き換えることにより却って構造が失われる例を示し、構造化定理のこのような解釈を批判している。
ダイクストラの構造化プログラミング
「構造化プログラミング」(structured programming)の語が最初に提唱されたのは1969年にオランダのコンピュータ科学者エドガー・ダイクストラ(Edsger W. Dijkstra)が発表した論文で、本来はこちらが構造化プログラミングの定義であるとされる。
彼の主要な問題意識は、プログラムの規模が大きくなっても正しさを容易に検証できるような「良く構造化されたプログラム」(well-structured program)を記述する方法論で、そのためのいくつかの考察と原則を構造化プログラミングという概念でまとめた。
これには、現代では関数やサブルーチンなどとして知られる、プログラムの「段階的な抽象化」(step-wise abstraction)、現代のオブジェクト指向プログラミングに近い、「抽象的なデータ構造」(abstract data structures)とこれに関連付けられた「抽象的な構文」(abstract statements)の「共同詳細化」(joint refinement)が含まれる。
これらを適用したプログラムは上下に階層化された交換可能なモジュール(部品)を連結したような構造になると指摘し、これを真珠のネックレスの構造に例えて説明している。この論考には「構造化定理」も「三つの制御構文」も「goto文」も登場せず、構造化プログラミングの本来の概念とこれらとはあまり関係がない。
しかし、ダイクストラが別の機会に発表したgoto文の濫用に疑問を呈する論説(1968年の “Go To Statement Considered Harmful” )や、他の論者とのいわゆる「goto文論争」、また、「構造化定理」と「構造化プログラミング」の名称の類似性などを通じて、次第に「三つの制御構文」式の理解が広まっていったと考えられている。
オブジェクト指向プログラミング 【OOP】 ⭐
コンピュータプログラムの構造、構成法の一つで、関連するデータの集合体と、それを操作する手続きを「オブジェクト」(object)と呼ばれるひとまとまりの単位として一体化し、オブジェクトの組み合わせとしてプログラムを記述する手法。
オブジェクト指向プログラミングではオブジェクトの定義と、オブジェクト間の関係、相互作用を記述することによりプログラムを構築していく。オブジェクトにはそれぞれ固有のデータ(属性/プロパティ)と手続き(メソッド)があり、外部からのメッセージを受けてメソッドを実行し、データを操作する。オブジェクトに付随するデータの操作は原則としてすべてオブジェクト中のメソッドによって行われる。
オブジェクトは外部に公開されたメソッドにより機能を提供する。内部の状態を表す変数なども、外部からの参照・操作が必要なものだけが専用の手続きによってアクセス可能となり、それ以外は外から見えない存在となる。
このように、関連するデータと手続きを一つの単位にまとめることを「カプセル化」(encapsulation)、外部に対して必要な情報や手続きのみを提供することを「情報隠蔽」(information hiding)という。外から直に参照や操作をする必要のない内部の状態や構造は秘匿される。
主流のクラスベースのオブジェクト指向プログラミングでは、オブジェクトの雛形を「クラス」(class)として記述し、これをプログラムの実行時に「インスタンス」(instance)として実体化し、データの保存や操作を行う。
あるクラスを元に一部の振る舞いを改変したり新しい機能を追加した別のクラスを作成する「継承」(inheritance)を活用することで、ライブラリや既存のプログラムから必要な機能を流用し、足りない部分だけ新たに記述するといったスタイルで開発を進めることができる。
派生したクラスでは既存のメソッドの振る舞いを必要に応じて改変することができ、外部から同じメソッドを呼び出した際に各オブジェクトがそれぞれ自らに適したコードを実行してくれる。このような性質を「ポリモーフィズム」(polymorphism/多態性)という。
オブジェクト指向によるソフトウェア開発は、異なるプログラムを組み合わせたり、後で部分的に再利用したりするのが容易になるという特徴があり、現代では多くのプログラミング言語にオブジェクト指向的な記述を可能にする仕様が取り入れられている。オブジェクト指向を主要な言語仕様としているものは特に「オブジェクト指向プログラミング言語」(オブジェクト指向言語)と呼ばれることもある。
IDE 【Integrated Development Environment】
ソフトウェア開発に必要なソフトウェアを一つに組み合わせ、同じ操作画面から統一的な操作法で利用できるようにしたソフトウェアパッケージ。一般的にはコードエディタやコンパイラ、リンカ、デバッガ、テストツール、バージョン管理ソフトなどで構成される。
プログラムのソースコードを記述するためのコードエディタを中心に、ソフトウェアの操作画面の設計や要素の配置、挙動の指定などを支援するGUIデザイン機能、ライブラリや開発中のクラスなどの仕様や内部構造を表示する機能、コンパイラやリンカを呼び出して実行可能ファイルを構築するビルド機能、ステップ実行やインスペクション、エラー箇所のハイライト表示などテストやデバッグを支援する機能などを持っていることが多い。
ソフトウェア開発を支援する補助的な機能として、コードとともにデータやドキュメントなどを一括して管理するプロジェクト管理機能や、ファイルの新旧の版管理や複数人による編集を管理するバージョン管理機能、複数の開発者の連携を補助するチーム開発機能などを持つものもある。
プラグインなどの拡張機構を用いて、後から対応言語や機能を増やすことができるものもある。特定の製品や技術を対象としたプログラムを開発するためのソフトウェア開発キット(SDK:Software Development Kit)が著名な統合開発環境に対するプラグインの形で提供されることも多い。
コードエディタは一般的なテキストエディタとして機能に加え、入力途中の文字列から予約語や関数名、プロパティ名、メソッド名などの候補を推測して自動的に提示してくれるコード補完機能や、予約後や区切り文字などを認識して色分けして見やすくする機能、コンパイルエラーなどが発生した場所をエラーメッセージ等とともに強調表示する機能など、コード記述に特化した便利な機能が盛り込まれていることが多い。
特定の環境や対象、プログラミング言語向けの統合開発環境として、米マイクロソフト(Microsoft)社の「Visual Studio」(Windows向け)や、米アップル(Apple)社の「Xcode」(macOS/iOS向け)、ジェットブレインズ(JetBrains)社の「IntelliJ IDEA」(Java言語向け)などがよく知られる。オープンソースソフトウェアの「Eclipse」(エクリプス)のように様々な言語や環境で汎用的・横断的に利用されるものもある。
エディタ
データの作成や編集(edit)を行うためのソフトウェア。“editor” の原義は「編集者」。
特定の形式のデータを、ストレージ(外部記憶装置)上のファイルやその他の情報源から読み込み、利用者の操作によって編集・加工し、結果をファイルなどに保存することができる。
編集できるデータの種類や主な用途などにより、「テキストエディタ」「コードエディタ」「バイナリエディタ」「グラフィックエディタ」など様々な種類がある。単にエディタといった場合は文字データの編集を行うテキストエディタを指すことが多い。
一方、データの表示や再生のみに対応し、編集機能を持たないソフトウェアのことは「ビューワ」(viewer)「ブラウザ」(browser)「プレーヤー」(player)などという。
テキストエディタ
文字のみで構成されるテキストファイルの作成や編集を行うためのソフトウェア。文字の入力や削除、検索、複製、一括置換などを行うことができる。
テキスト形式は文字のみで構成されるデータで、画像など他の形式のデータや、コンピュータ向けの制御データ、文字の大きさや色などの修飾情報などは含まない。テキストエディタは文字の編集に特化したソフトウェアであり、こうした文字以外の情報を扱うことはできない。
現代では一般的な文書作成はレイアウトや見た目の修飾ができるワープロソフトなどを使うことが一般的なため、テキストエディタは主にソフトウェアの設定ファイルやコンピュータプログラムのソースコード、マークアップ言語による文書ファイルなどの作成・編集に用いられる。プログラムの編集に特化したものは特にコードエディタと呼ばれることもある。
製品によっては、行番号の表示や折返し桁数の設定、正規表現による複雑な条件を用いた検索や置換、操作の取り消し(アンドゥ)、編集作業の記録・再生や自動化(マクロやスクリプト)、特定の記号やキーワードの色分け表示(シンタックスハイライト)など文字データの編集を支援する便利な機能が利用できる。
Windowsの「メモ帳」やmacOSの「テキストエディット」のように多くのOSには付属のテキストエディタが存在するが、フリーソフトウェアやオープンソースソフトウェアとして配布されているエディタや、企業などが製品として開発・販売しているものも数多く存在する。UNIX環境では伝統的にvi/VimやEmacsが標準的に使われている。
コンパイラ ⭐
人間に分かりやすく複雑な機能や構文を持つ高水準プログラミング言語(高級言語)で書かれたコンピュータプログラムを、コンピュータが解釈・実行できる形式に一括して変換するソフトウェア。“compiler” の原義は「翻訳者」。
コンパイラは、プログラミング言語で書かれた「ソースコード」(source code)を読み込んで解析し、コンピュータが直に実行可能な機械語や、それに相当する中間言語などで記述された「オブジェクトコード」(object code)に変換する。この変換工程のことを「コンパイル」(comple)という。
コンパイラが生成したオブジェクトコードはそのままでは実行可能でない場合が多く、リンカなど別のソフトウェアを用いて、起動に必要なコードを追加したり、必要なライブラリなどを結合(リンク)したりして実行可能形式のプログラムとする。コンパイルを含む一連の工程を「ビルド」(build)という。
一方、ソースコードを読み込みながら、逐次的に実行可能コードを生成して実行するソフトウェアを「インタプリタ」(interpreter:「通訳者」の意)という。コンパイルやリンクなどのビルド工程を経ずにソースコードをいきなり実行できるため、スクリプト言語の実行環境としてよく用いられる。
様々なコンパイラ
Javaや.NET言語など、CPUやオペレーティングシステム(OS)の種類に依存しない中間形式でプログラムを配布する言語では、実行時に実行環境固有のコード形式(ネイティブコード)に変換するコンパイラを「JITコンパイラ」(Just-In-Time compiler)あるいは「実行時コンパイラ」という。この方式では、開発時にソースコードから中間形式へ、実行時に中間形式からネイティブコードへ、2段階のコンパイルを行う。
デジタル家電などの組み込みソフトウェアの開発など、開発環境と実行環境が異なる場合、開発環境上で別の環境向けのオブジェクトコードを生成する「クロスコンパイラ」(cross compiler)という。実行プログラムは対象環境に送ってテストや実行を行う。
コンパイラとは逆に、コンパイル済みのオブジェクトコードを解析して元のソースコードに逆変換するソフトウェアを「デコンパイラ」(decompiler)あるいは「逆コンパイラ」という。高水準言語ではソースコードとオブジェクトコードの各要素は一対一に対応しないため、完全な復元は難しい。特に、変数名などのシンボルはコンパイル時に失われるため、オブジェクトコードから取り出すことはできない。
インタプリタ
人間に分かりやすい高水準プログラミング言語(高級言語)で書かれたコンピュータプログラムを、コンピュータが解釈・実行できる形式に変換しながら同時に少しずつ実行していくソフトウェア。英語の原義は「通訳者」。
人間などがプログラミング言語で記述したソースコードを処理の流れの順に少しずつ読み込んでいき、内容を解析して実行可能なプログラムに変換し、即座に実行する。変換と実行を逐次的に繰り返し行い、処理を進めていく。
コンパイラなどで一括して変換してから実行する方式に比べ、ソースコードを即座に実行開始できるため開発や修正をテンポよく進めることができるが、変換にかかるオーバーヘッドの分だけ実行速度やメモリ使用量では劣る。
また、インタプリタによる実行を前提とする場合はプログラムの配布をソースコードで行うことになるが、環境ごとに変換済みのバイナリコードを用意しなくてよく、インタプリタさえ用意されていれば様々な環境で動作させられる反面、利用者にソースコードを必ず開示しなければならない点が嫌がられることもある(商用ソフトウェアなどの場合)。
いわゆるスクリプト言語や軽量言語(LL)と呼ばれる言語は標準の処理系としてインタプリタが用意されており、すぐに実行できるようになっている。
デバッガ 【デバッグツール】
プログラミングの際に用いる開発ツールの一つで、プログラムの欠陥(バグ)を発見・修正するデバッグ(debug)作業を支援するソフトウェア。自動的にデバッグしてくれるソフトウェアではない。
人間がプログラミング言語で書いたソースコードには誤りが含まれることがあり、コンピュータが実行可能な形式(オブジェクトコード)に変換できないような文法上の誤りなどはコンパイラなどが検出して修正を促すが、処理の論理的な誤りなどを自動的に検知するのは難しく、開発者が自力で欠陥を見つけて除去しなければならない。
デバッガはプログラムの実行状態に介入したり、実行中のある瞬間におけるコード中の変数やメモリの特定の番地、CPU内部のレジスタなどの値を表示することができ、どこで誤りが生じているのか探し出すのを手助けしてくれる。
ブレークポイント(breakpoint)機能はプログラマがコード中の任意の箇所を指定し、実行時にその場所に差し掛かったら強制的に実行を一時停止してその時点での変数などの状態を確認することができる。
ステップ実行(step by step execution)あるいはシングルステップ実行(single stepping)は、ブレークポイントなどで一時停止後、プログラムを一ステップ(一行、一命令など)ごとに実行する機能で、各ステップで実際にどのような処理が行われたかを確認しながら実行を進めることができる。
ステップ実行中に関数呼び出しなどに出くわした場合に、その内部へ移動してさらにステップ実行するステップイン、ステップインした関数等の終了までを一気に実行(呼び出し元に戻った時点で一時停止)するステップアウト、関数等の呼び出しなどをスキップするステップオーバーなどの機能が利用できる場合もある。
オブジェクトコードを実行しつつ、対応するソースコード上での実行位置や変数名などを参照できるものをシンボリックデバッガ(symbolic debugger)あるいはソースレベルデバッガ(source-level debugger)と呼び、通常はこちらが使われるが、ソースコードが入手できない場合など特殊な状況で利用される、実行形式コードを直接解析するデバッガ(low-level debugger/machine language debugger)も存在する。
ライブラリ ⭐
図書館、図書室、資料室、書庫、書斎、蔵書、文庫、選書、双書などの意味を持つ英単語。ある分野の資料やデータなどを一定の形式で集めたものを、図書館になぞらえて比喩的にライブラリと呼ぶことがある。
ITの分野では、ある特定の機能を持ったコンピュータプログラムを他のプログラムから呼び出して利用できるように部品化し、そのようなプログラム部品を複数集めて一つのファイルに収納したものをライブラリということが多い。
一般的に、ライブラリにはオブジェクトコード(機械語などで記述された実行可能形式のプログラム)が格納されているが、それ単体で起動して実行することはできず、他の実行可能ファイルに連結されて利用される。言語や処理系によってはソースコードの集合をライブラリという場合もある。
様々なプログラムが共通して利用する汎用性の高い機能などがライブラリとして開発・提供されることが多く、標準的なライブラリはオペレーティングシステム(OS)やプログラミング言語の開発環境、開発ツールなどの一部として付属することが多い。
特定のソフトウェアやハードウェアを利用したプログラムを開発するために必要な機能がライブラリの形でまとめられている場合もあり、当該システムのソフトウェア開発キット(SDK)などの一部として開発者に提供される。
また、部品化されたコンピュータプログラム以外にも、特定の分野や形式のデータなどを検索、取得、再利用しやすい形にまとめたファイルやデータベース、Webサイトなどのことを「フォトライブラリ」「音声ライブラリ」などといったように呼ぶことがある。
API 【Application Programming Interface】 ⭐⭐
あるコンピュータプログラム(ソフトウェア)の機能や管理するデータなどを、外部の他のプログラムから呼び出して利用するための手順やデータ形式などを定めた規約のこと。
個々のソフトウェアの開発者が毎回すべての機能をゼロから開発するのは困難で無駄なため、多くのソフトウェアが共通して利用する機能は、OSやミドルウェアなどの形でまとめて提供されている。
そのような汎用的な機能を呼び出して利用するための手続きを定めたものがAPIで、個々の開発者はAPIに従って機能を呼び出す短いコードを記述するだけで、自分で一から処理内容を記述しなくてもその機能を利用したソフトウェアを作成することができる。
広義には、プログラミング言語の提供する機能や言語処理系に付属する標準ライブラリの持つ機能を呼び出すための規約などを含む場合もある(Java APIなど)。
また、APIを経由して機能を呼び出す形でプログラムを構成することにより、同じAPIが実装されていれば別のソフトウェア上でそのまま動作させることができるのも大きな利点である。実際、多くのOS製品などでは同じ製品の旧版で提供していたAPIを引き継いで新しいAPIを追加するという形で機能を拡張しており、旧バージョン向けに開発されたソフトウェアをそのまま動作させることができる。
APIの形式
APIは人間が記述・理解しやすい形式のプログラムであるソースコード上でどのような記述をすべきかを定めており、原則としてプログラミング言語ごとに定義される。
関数やプロシージャなどの引数や返り値のデータ型やとり得る値の意味や定義、関連する変数や定数、複合的なデータ構造の仕様、オブジェクト指向言語の場合はクラスやプロパティ、メソッドの仕様などを含む。
通信回線を通じて遠隔から呼び出すような構造のものでは、送受信するパケットやメッセージの形式、通信プロトコル(通信規約)などの形で定義される仕様をAPIと呼ぶこともある。
Web API
近年ではネットワークを通じて外部から呼び出すことができるAPIを定めたソフトウェアも増えており、遠隔地にあるコンピュータの提供する機能やデータを取り込んで利用するソフトウェアを開発することができる。
従来は通信を介して呼び出しを行うAPIはRPC(リモートプロシージャコール)の仕様を元に製品や環境ごとに個別に定義されることが多かったが、インターネット上でのAPI呼び出しの場合は通信にHTTPを、データ形式にXMLやJSONを利用するWeb APIが主流となってきている。
2000年代前半まではWeb APIの標準として仕様が巨大で機能が豊富なSOAPの普及が試みられたが、2000年代中頃以降は軽量でシンプルなRESTful APIが一般的となり、狭義のWebアプリケーションだけでなく様々な種類のソフトウェアやネットサービス間の連携・接続に幅広く用いられるようになっている。
APIと実装
API自体は外部からの呼び出し方を規定した決まりごとに過ぎず、呼び出される機能を実装したライブラリやモジュールなどが存在して初めてAPIに挙げられた機能を利用することができる。
あるソフトウェアのAPIが公開されていれば、同じAPIで呼び出すことができる互換ソフトウェアを開発することもできる。ただし、APIを利用する側のプログラムが(スクリプトなどではなく)バイナリコード(ネイティブコード)の場合にはこれをそのまま動作させることはできないのが一般的で、同じソースコードを元に互換環境向けにコンパイルやビルドをやり直す必要がある(ソースレベル互換)。
また、API自体は標準実装における動作の詳細までは定義していないため、APIが同一の互換ソフトウェアだからといって動作や振る舞いがまったく同じであるとは限らない。商用ソフトウェアの場合はAPIが非公開だったり、すべては公開されていなかったりすることが多く、公開情報だけではAPI互換の製品を作ることも難しい。
APIと知的財産権
従来は特許で保護されている場合を除いて、APIそのものには著作権その他の知的財産権は存在しないとする見方が一般的で、実際、元のソフトウェアのコードを複製せずすべて独自に実装するという方法でAPI互換ソフトウェアが数多く開発されてきた。
ところが、米オラクル(Oracle)社が権利を有するJava言語やその処理系に関して、米グーグル(Google)社が同社の許諾を得ずにAndroidスマートフォン向けにJava APIを実装した実行環境(Dalvik VM)を開発・提供しているのは著作権侵害であるとの裁判が起こされ、米裁判所は訴えを認める判決を出した。今後はAPIの権利について従来の状況が変化していく可能性がある。
シングルボードコンピュータ 【SBC】
概ね手のひらサイズ程度までの小さな電子基板に単体のコンピュータとして必要なほぼすべての機能や要素を実装したもの。
基板上にCPU(マイクロプロセッサ/MPU)やメインメモリ(RAM)、ストレージ、チップセット、入出力端子などを実装された小型コンピュータで、画面出力やネットワークインターフェースなどを備えたパソコンなどに近い仕様の製品もある。
Linuxなど汎用のオペレーティングシステム(OS)が動作するよう設計されていることが多く、ネットワーク上でサーバとして動作させたり、Pythonなどのスクリプト言語でハードウェアの入出力制御を行うことができる。
もともとは産業機械の組み込みシステムで制御用コンピュータとして使われていた製品などがこのように呼ばれており、その場合はより簡素な仕様でリアルタイムOSなど特殊なソフトウェア環境を有するものが多い。
近年では「Raspberry Pi」(ラズベリーパイ)などパソコンやスマートフォンなど汎用の小型コンピュータに近い機能や仕様を持った新たな製品カテゴリーが台頭し、組み込み用途に限らず趣味や教育など幅広い用途で利用される。
マイコンボード (ワンボードマイコン)
概ね名刺サイズかそれより小さな電子基板に、電子機器の制御などを行うマイクロコンピュータ(マイコン)としての機能を実装したもの。
CPUとしてパソコン向けなどで用いられる複雑で高性能なマイクロプロセッサではなくマイクロコントローラやSoC(System on Chip)、RISC系プロセッサなど軽量な製品を搭載し、RAMやI/Oインターフェース、プログラム記憶用の不揮発メモリなどコンピュータとしての動作に必要な一通りの機能を内蔵している。
LinuxやWindowsのような汎用のOSを用いず外部からバイナリプログラムを転送して直接実行したり、リアルタイムOSなど組み込みシステム用のソフトウェア環境を用いることが多い。外部との通信もGPIOやSPI、I2Cなどシリアルインターフェースが主体で、画面出力やネットワークインターフェースなどは無いことが多い。
半導体製品の評価ボードとして使用したり、電子機器や機械などの制御用として内蔵する組み込みシステムとして利用されることが多い。組み込み用途の製品ではシングルボードコンピュータ(SBC)との区別は曖昧で、似たような製品でもマイコンボードと呼ばれたりSBCと呼ばれたりする。
1970年代には、まな板くらいの大きさの(現代から見れば大きめな)ワンボード型コンピュータが最初期の個人用小型コンピュータとして人気を博したこともあるが、程無くより複雑な構成のマイコン、パソコンに発展していった。近年では電子工作などの制御用ボードとして「Arduino」(アルデュイーノ)などのオープンな仕様の製品が再び注目を集め、産業用だけでなく趣味や教育などの分野で利用されている。
LED 【Light Emitting Diode】
半導体素子の一種で、電流を流すと発光するダイオードのこと。少ない電力で強い光を発することができ、照明や表示装置に広く応用されている。
電流を特定の一方向にのみ流す性質(整流作用)を持つ電子素子を「ダイオード」(diode)というが、LEDは電流を流すと発光する性質を持つ。1962年に米電気工学者ニック・ホロニアック(Nick Holonyak, Jr.)によって発明された。
構造と原理
p型半導体とn型半導体を接合したpn接合を持ち、p型側の陽極(anode:アノード)を正、n型側の陰極(cathode:カソード)を負とする順方向の電圧をかけると、接合面で正孔と電子が結合して発光する。 このような発光現象を「エレクトロルミネッセンス」(EL:Electro-Luminescence)という。
材料によって発光色が異なり、初期には赤やオレンジ、1972年には緑色LEDが開発されたが、1989年にそれまで困難だった青色LEDが実用化された。これにより赤・青・緑の光の三原色が揃い、これらの組み合わせで白色を含む任意の色を作れるようになったため、一気に用途が拡大した。
特徴と用途
LEDは白熱電球や蛍光灯など他の発光装置・器具に比べ、小型化が容易、衝撃に強い、長寿命、構造が単純、大量生産しやすい、明滅の切り替えが高速、発光効率が高い(同じ電力なら明るい、同じ照度なら発熱や消費電力が少ない)、光に含まれる波長が極めて偏っている、高温の環境に弱いという特徴がある。
当初は電気製品の電源などの状態を点灯によって示すインジケータ(表示灯)としてよく用いられたが、高輝度化や白色光の実現により、近年では電球や蛍光灯に代わる照明用途、大型の電光掲示板、コンピュータのディスプレイ装置や液晶テレビなどのバックライトなどとしても広く普及している。
変数 ⭐⭐⭐
コンピュータプログラムのソースコードなどで、データを一時的に記憶しておくための領域に固有の名前を付けたもの。プログラム上で値を代入したり参照することができる。
変数につけた名前を「変数名」と呼び、記憶されているデータをその変数の値という。データの入れ物のような存在で、プログラム中で複数のデータを扱いたいときや、同じデータを何度も参照したり計算によって変化させたい場合に利用する。
変数をプログラム中で利用するには、これからどんな変数を利用するかを宣言(declaration)し、値を代入(assignment)する必要がある。コード中で明示的に宣言しなくても変数を利用できる言語もある。変数に格納された値を利用したいときは、変数名を記述することにより値を参照(reference)することができる。
変数の型
プログラム中で扱うデータは整数、浮動小数点数、文字列など様々なデータ型に分かれており、変数も特定のデータ型を持つ。多くの言語では宣言時に一つのデータ型を指定しなければならず、後から型は変えられないが、特定の型を指定しなくても処理系が適切な型を適用(型推論)してくれる言語や、代入などによって途中で型を切り替えることができる言語もある。
変数のスコープ
変数は宣言した位置などにより通用する範囲(スコープ)が決まっており、範囲の外から参照や代入を行うことはできない。プログラム全体を通用範囲とするものを「グローバル変数」(大域変数)、特定のサブルーチンや関数、メソッド、コードブロックなどの中でのみ通用するものを「ローカル変数」(局所変数)という。オブジェクト指向言語では「クラス変数」や「インスタンス変数」などに分かれる。
変数名
コンピュータプログラム上で変数に付ける名前。プログラマが変数を区別、指定できるようにするためにソースコード中で定義する。
プログラムは実行時にコンピュータのメインメモリ(RAM)内にデータの保管領域を確保し、データの書き込みや読み出し、書き換えなどを行うことができる。コンピュータ内部では個々のデータの記憶位置を番地(メモリアドレス)で識別・指定するが、人間には分かりにくいため、プログラミング言語で記述するプログラム(ソースコードという)の中では、名前の付いた「変数」(variable)として扱う。
仕様上の命名規則
変数名として使用可能な文字の種類や名付けの規則(禁止事項)は言語仕様によって決まっているが、C言語では半角英数字(0~9、a~z、A~Z)とアンダーバー(_)のみ使うことができ、この仕様を踏襲している言語が多い。数値リテラルと区別する必要から、先頭に数字を使うことはできない。多くの言語は英大文字と小文字を別の文字として区別するが、同一視する言語もある。
先頭や末尾に特定の記号を付けることでデータ型やデータ構造(コレクション)の種類を指定することができる言語もある。例えば、Perlでは「$a」のように先頭が「$」(ドルマーク)の変数はスカラ変数を表しており、Visual BasicやVBAでは「a$」のように末尾が「$」の変数は文字列型となる。
慣習上の命名規則
言語仕様上の変数名の規則とは別に、言語ごとの慣習や、組織・プロジェクトごとに命名規則を定めて一定の規則性に従って命名する場合もある。例えば、先頭にデータの種類を表す接頭辞を付ける命名法を「ハンガリアン記法」という。「jpyPrice」のようにデータの意味を表すものを「アプリケーションハンガリアン」、「bChecked」のようにデータ型などを表すものを「システムハンガリアン」という。
また、複数の単語を連ねて変数名とする場合に、「fooBarBuz」のように単純に連結して各単語の先頭を大文字にする方式を「キャメルケース」、「foo_bar_buz」のようにアンダーバーで区切る方式を「スネークケース」という。キャメルケースのうち、「FooBarBuz」のように変数名自体の先頭を大文字にする方式は「パスカルケース」とも呼ばれる。
代入 ⭐
数学で文字を値や式で置き換えること。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 という場合は、変数名が記述された箇所を実際の値で置き換える操作などを表す。
ローカル変数 【局所変数】 ⭐
コンピュータプログラム中のあるコードブロック(関数やメソッドなど)の内部で宣言され、その範囲内でのみ有効な変数。
プログラミング言語の多くは、サブルーチンや関数、メソッドなどの形で複数のコードを束ねたまとまり(ブロック)を作ることができるが、そのようなブロックの内部でのみ通用する変数のことをローカル変数という。
通常、あるブロック内で変数を宣言すると、自動的にそのブロックを有効範囲(スコープ)とするローカル変数となり、ブロック内のコードからのみ参照や変更ができるようになる。関数内で別の関数を定義するといった入れ子構造の記述が可能な場合、内側のブロックから外側のブロックのローカル変数にアクセスできるかどうかはブロックの種類や言語仕様により異なる。
一般的にローカル変数の寿命はブロックの開始(あるいは変数宣言)から終了までで、関数などの実行が終了して呼び出し元に制御が移ると関数内のローカル変数の内容は破棄されるが、言語によっては内容を維持するよう指定する事ができる場合もある(静的ローカル変数)。
どのような種類のブロックでローカル変数を使用できるかは言語によって異なるが、関数やメソッドなどをスコープとするローカル変数はほとんどの言語に存在する。繰り返しや条件分岐などの制御文で指定される範囲をスコープとするローカル変数を宣言できる言語も存在する。
一方、同じプログラムのどこからでも参照や書換が可能な変数を宣言できる言語もあり、そのような変数をグローバル変数(global variable)という。
グローバル変数 【大域変数】 ⭐
コンピュータプログラムで使用される変数のうち、プログラム中のどこにあるコードからでも同じように値の読み取りや書き換えが可能なもの。
特定の関数やメソッド、サブルーチンなどのコードブロックに所属せず、プログラム全体を有効範囲(スコープ)とする変数である。通常、プログラムの冒頭など、どのブロックにも含まれない最も外側に変数宣言を記述することにより定義することができる。変数の寿命はプログラムの開始から終了までで、プログラムの実行中はずっと同じメモリ領域に置かれ、内容が維持され続ける。
多数の関数などにまたがってプログラム全体で頻繁に参照・更新される変数などを、いちいち引数などの形で明示的に受け渡さなくてもよいといった利点があり、メモリ容量や処理速度に厳しい制約がある場合などには多用されることもある。
一方、プログラム中のどこからでも変更できるため、プログラムの規模が大きくなるとどこでどのように書き換えられているのか把握しにくくなり、予期せぬバグが生まれたり、開発の分業やコードの追加・修正が困難になる。
また、開発者の異なる複数のソースコードを連結して実行ファイルを生成する場合など、グローバル変数の変数名が衝突してバグを生み出すこともある。このような特徴からグローバル変数の使用を好ましくないと考える開発者も多く、グローバル変数を仕様から排除したプログラミング言語もある。
予約語 【予約済みキーワード】 ⭐
プログラミング言語などの人工言語の仕様に定められている、開発者が付ける識別名として利用できない文字列のこと。予約語に挙げられた単語やフレーズは変数名や関数名などに使用することはできない。
例えば、「for」が繰り返し処理を表す制御構文の名前であるような言語で、開発者が「for」という名前の変数を定義してしまうと、コード中の「for」が制御文なのか変数なのか分からなくなってしまう。
このように、言語側であらかじめ特定の意味が与えられている文字の並びについては、コード中で開発者が名付ける変数などの識別名としては利用できないようになっている。これを予約語と呼び、「“for” は予約されている」といったように表現する。
どのような文字列が予約語かは言語仕様によって定義されており言語によって異なるが、言語に直接組み込まれている制御構文(if、else、for、while、begin、end、returnなど)や宣言文(const、function、varなど)、組み込みデータ型(int、float、stringなど)、組み込み関数(print、openなど)、特殊なリテラル(true、false、undefined、nullなど)などの名前が指定されていることが多い。
すべての予約語に何らかの意味や機能が付与されているとは限らず、過去に機能が存在したが廃止され予約語だけが残っている場合や、将来の仕様改訂に備え、まさに「予約」してあるだけの予約語もある。Javaの “goto” のように過去も将来も言語上の機能はないが、過去のプログラミング言語のgoto文相当の機能はJavaには存在しないため、混乱を招かないよう予約してあるという例もある。
データ型
プログラミング言語などが扱うデータをいくつかの種類に分類し、それぞれについて名称や特性、範囲、扱い方、表記法、メモリ上での記録方式などの規約を定めたもの。
あるデータがどのような性質のもので、どのように取り扱うべきかを定めたもので、典型的なものには整数型や文字列型などがある。それぞれの変数や値のデータ型に応じて、それを適切に扱うためのプログラムコードが生成・適用される。
例えば、整数型の値について「1+1」という処理を実行すると、数値計算のコードが適用されて「2」という結果が得られるが、文字列型の値について「"1"+"1"」という処理を実施すると、文字列の連結処理が適用されて「"11"」という結果が得られる。
整数を文字列で除算しようとするなど、型が不整合な処理はエラーとなる。"1"という文字列型の値を1という整数型の値に変換するなど、異なる型へ一定のルールに基づいて変換することを「型変換」あるいは「型キャスト」(type casting)という。
プリミティブ型と複合型
様々なデータ型のうち、それ以上要素に分解できない最小単位のデータを格納する最も基本的なデータ型を「単純データ型」「プリミティブデータ型」などという。
言語によって用意されている単純型の種類は異なるが、文字型や文字列型、整数型、浮動小数点数型(あるいは固定小数点数型や実数型)、論理型(ブーリアン型)、日付・時刻型、バイナリ型などが用意されていることが多い。
ポインタ型や参照型などメモリ上の位置を格納する型や、関数型などプログラムをデータのように扱う型、データが「無い」ことを明示するvoid型など、特殊な型が用意されている言語もある。
浮動小数点数型に単精度や倍精度など異なる精度の型が用意されていたり、整数型がバイト長や符号の有無(負数を表現できるか否か)でいくつかの種類に分かれているなど、データの種類が同じでも仕様が異なる複数の型に分かれている場合もある。
一方、複数のデータ型を組み合わて定義された型や、複数の要素からなるデータ構造を格納するためのデータ型を「複合データ型」(complex type)という。配列や連想配列(ハッシュ、マップ、辞書)、リスト、タプル、集合型(セット)、列挙型などがこれに当たる。
組み込み型とユーザー定義型
言語仕様や標準ライブラリなどにあらかじめ用意されているデータ型を「組み込みデータ型」(ビルトインデータ型)、開発者が独自に定義したものを「ユーザー定義データ型」(user-defined type)という。
組み込み型は言語処理系が標準的に扱うことができ、演算子による演算を行ったり、基本的な操作や処理を行うための関数やメソッドが標準で提供されることが多い。
ユーザー定義型は単に既存の組み込みデータ型に別名を与えられるだけの場合もあるが、様々なデータ型を組み合わせた複合データ型を独自に定義できる機能を指すことが多い。演算子の処理内容を独自に定義(上書き)して、ユーザー定義型の値に対しても演算子を適用できる言語もある。
型宣言と型付け
プログラムの開発者がそれぞれの変数などのデータ型をプログラム上に明示することを「型宣言」(type statement)という。コード中で使用する変数などについて必ず事前に型宣言しなければならない言語と、型宣言しなくても変数などを使ってよい言語がある。
プログラムの実行前、ソースコードの記述やコンパイルの時点で型が決定されることを「静的型付け」(static typing)、実行時に実際の値に基づいて型が決定されることを「動的型付け」(dynamic typing)という。
型宣言が不要な言語の多くは動的型付けを採用しているが、「型推論」(type inference)機能により内部的に静的型付けを自動的に行う仕組みの言語もある。
文字列型 【String型】
多くのプログラミング言語やデータベース管理システム(DBMS)に用意されている基本データ型の一つで、複数の文字の並びを一つの値として格納するもの。
文字を表す文字コードを連ねた文字列データを格納する型で、予め格納できる文字列の長さを指定する固定長文字列型(fixed length string)と、任意の長さの文字列を格納できる可変長文字列型(variable length string)がある。言語や処理系によっては一方しか無い場合もある。
古い言語や処理系ではASCII文字(いわゆる半角英数字・記号)しか格納できない仕様のものもあるが、近年ではUnicodeなどで表現さrた多バイト文字(漢字など)をそのまま格納できるようになっているものが多い。
一文字分の文字コードを格納するためのデータ型として文字型(character type)が用意されているC言語/C++言語などでは、組み込みデータ型としての文字列型が無く、文字型のデータの配列などの形で文字列を格納する。
整数型 【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 となる。
符号ビット
数値をビット列で表したときに正負の符号を表すためのビット。一般的な数値のビット表現仕様の多くでは先頭ビットが符号ビットに割り当てられている。
一般的な符号付き整数型の場合、先頭の1ビットが正負の符号を表し、「0」ならば0あるいは正、「1」ならば負の数を表す。正の数の場合は残りビットがそのまま値となり、例えば8ビットであれば「01111111」が127を表す。
負の数の場合、符号ビット以外をどのように扱うかでいくつかの方式に分かれる。最も単純な方式として正の数と同じように符号ビット以外で絶対値(仮数)を表す手法があり、「10000000」は-0、「11111111」は-127となる。コンピュータ上では加減算の処理が複雑になるためあまり採用されていない。
多く採用されているのは符号ビット以外に絶対値の2の補数(two's complement)を格納する方式である。2進数における2の補数とは、その数に足し合わせるとちょうど桁が一つ増える最小の数で、例えば127「1111111」の2の補数は1(足すと「10000000」になる)である。この方式では「10000000」は-128、「11111111」は-1となる。
浮動小数点数型
プログラミング言語などが扱う基本的なデータ型の一つで、小数点以下の桁数が可変長の実数を格納することができるもの。多くの言語で整数型と共に数値を表す組み込みデータ型の一つとして採用されている。
浮動小数点型では、数値の正負を表す「符号部」、数値を2進数で表したときの各桁の数字の並びである「仮数部」、小数点の位置を表す「指数部」の組み合わせで値を表現する。仮数に基数(通常は2)を指数乗した値を乗じ、符号を付け加えたものが表現する数値となる。
例えば、「-4.375」は2進数では「-100.011」であり、仮数と指数に分離すると「-1.00011×1010」(値はすべて2進表記)となる。符号は正を0、負を1とすることが多いため、符号部の値は「1」、仮数部の値は「100011」、指数部の値は「10」となる。数値が0の場合は符号と指数は不定となるが、便宜上各部をすべて0としたもの(+0.0×100)を0の表現として扱うことが多い。
格納できる値の範囲は整数型とは異なり、表現可能な桁の長さ(有効数字)と、数の大きさそのもの(指数部の大きさ)がそれぞれ独立に決まっている。例えば、一般的な仕様の単精度浮動小数点数型は、十進数に換算して概ね10の38乗程度までの絶対値の数を表すことができるが、このうち各桁の数字を正確に表せるのは上位6桁程度である。
IEEE 754形式
浮動小数点型には全体のデータ長や仮数部と指数部のビット数の配分などで様々な形式が存在するが、広く普及している標準規格としてIEEE 754形式が知られる。
全体で16ビット(符号1+指数5+仮数10)の「半精度浮動小数点数型」、32ビット(符号1+指数8+仮数23)の「単精度浮動小数点数型」、64ビット(符号1+指数11+仮数52)の「倍精度浮動小数点数型」、128ビット(符号1+指数15+仮数112)の「四倍精度浮動小数点数型」の4つの形式が定められており、それぞれ表現できる数値の幅の異なる。
実用上は単精度と倍精度がよく用いられ、プログラミング言語や論理回路などでもこの2つに標準で対応しているものが多い。例えば、C言語系の言語では単精度を「float」、倍精度を「double」という型名で表す。
空文字列 【ヌル文字列】
プログラミングなどで用いられるデータの一つで、何の文字も含まれていない文字列型のデータ。
文字数が0で何も含まれていない文字列のことで、多くの言語では "" や '' のように文字列の開始記号の直後に終端記号を続けたリテラルで表される。
空文字列の文字の数は0だが、内部的にはメモリ上で何らかの表現形式で格納されており、記憶された領域の容量が0なわけではない。また、C言語では文字列を文字型(char型など)の配列として表し、終端に空文字('\0')を置く決まりであるため、空文字列は空文字のみを要素とする配列(要素数は1)で表される。
プログラミングでは文字列以外にも「内容が空である」(null)という概念が用いられ、どこも指し示していないポインタ(ヌルポインタ)や、値が存在しないことを表す特殊な値を「null」「NULL」などのシンボルで表すことがある。これらは空文字列とは異なる概念で適切に区別する必要があるが、便宜のため "" と null の比較が真になるなどの設計になっている言語もある。
演算子 【オペレータ】 ⭐⭐
数学やプログラミングなどで式を記述する際に用いられる、演算内容を表す記号などのこと。演算の対象となる値や変数などのことは「被演算子」(operand:オペランド)という。例えば「x+1」という式では「+」が演算子、「x」「1」が被演算子である。
プログラミング言語では言語仕様などで様々な演算子が定義されており、これを組み合わせて式や命令文を構成することができる。対象となる被演算子の数によって、「a++」のように一つしか取らないものを「単項演算子」(unary operator)、「a+b」のように二つのものを「二項演算子」(binary operator)、「c?x:y」のように三つのものを「三項演算子」(ternary opeator)、任意個の被演算子を列挙できるものを「多項演算子」(n-ary operator)という。
演算子は演算の内容によっても分類でき、「a-b」「x/10」のように四則演算などの算術的な計算を記述する「算術演算子」(arithmetic operator)、「a>b」「x==y」のように二項の比較や関係を表す「比較演算子」(comparison operator)あるいは「関係演算子」(relational operator)、「a&&b」「x||y」のように論理演算を行う「論理演算子」(logic operator)などがある。
多くの言語では演算子は言語仕様で定義されており開発者が任意に追加、削除、変更することはできないが、言語によってはコード中で独自の演算子を定義して利用することができたり、既存の演算子に別の演算内容を割り当てる「多重定義」(オーバーロード)ができる場合もある。
等号 【=】
右辺と左辺が等しいことを表す数学記号「=」のこと。IT分野ではコンピュータプログラム中で代入を表す記号として用いられることもある。
数学では「a=b」と書けば、文字aとbは値が等しいことを表し、「aイコールb」あるいは「aはbに等しい」といったように読む。等しくない場合は「≠」を、ほぼ等しい場合は「≒」「≃」「≈」「~」などの記号を用いる。
恒等式(左辺と右辺は恒等的に等しい)や、定義(左辺を右辺のように定義する)は三本線の「≡」を用いることが多い(定義は「:=」等とする場合もある)。図形は面積や体積が等しいことを「△ABC=△XYZ」のように書き、形も一致する合同は「△ABC≡△XYZ」のように「≡」を用いる。
ASCII文字コードでは61番(16進数で3D)が割り当てられており、標準的な配列のキーボードでは文字領域の最上段右寄りにある「= - ほ」と書かれたキーをShiftキーと共に押すことで入力できる。日本語文字コードでは全角記号としての「=」も定義されており、国際的な文字コード標準のUnicodeではU+FF1D「FULLWIDTH EQUALS SIGN」として収録されている。
プログラミングにおける等号
プログラミングでは、左辺の変数などに右辺の値や式の評価結果などを代入する記法として「a=1」のように記述することがある。数学の等式とは意味が異なり、例えば現在の値に1を加算する操作は「a=a+1」のように数式としては意味が通らない記述となる。
初等教育では「=」記号は等式と教わるため初学者が混乱するといった批判もあるが、この記法を採用するC言語の記法を踏襲するプログラミング言語は現代でも主流となっている。Pascalのように代入を「:=」で表し、「=」は等式に意味的に近い条件文などでの左辺と右辺の比較(等価演算子)として用いる言語もある。
C言語や多くの似た構文の言語では、「=」は代入を表し、比較には if(x==1) のように「==」を用いる。JavaScriptのような動的型付け言語(いわゆるスクリプト言語)では、値の実質的な内容が一致するか比較する演算子に「==」を、値とデータ型の両方が厳密に一致するか比較する演算子に「===」(厳密等価演算子)を用いることがある。
算術演算子
プログラミング言語などで用いられる演算子のうち、四則演算(加減乗除)などの算術的な計算を行うもの。和を表す「+」、差を表す「-」などのこと。
ほとんどの言語では加減算は算術・数学と同じ「+」「-」を用いる。半角文字(ASCII文字)には乗算記号「×」と除算記号「÷」が用意されていないため、それぞれ「*」(アスタリスク)、「/」(スラッシュ)で代用することが多い。
一般の算術にはない記号として、剰余(割り算の余り)を求める演算子(C言語系の「%」など)や、累乗を求める演算子(BASIC系の「^」、PythonやJavaScriptの「**」など)が用意されている言語もある。
整数型の変数の値に1を加算するインクリメント演算子(C言語系の「++」など)や、同じく1を減算するデクリメント演算子(同「--」など)を算術演算子に分類する場合もある。
比較演算子 【関係演算子】 ⭐
プログラミング言語などで用いられる演算子のうち、二つの式や値の比較を行い、結果を真偽値(trueまたはfalse)で返すもの。一致・不一致や大小の比較などいくつかの種類がある。
用意されている比較の種類や記法は言語によって様々だが、数の一致や大小は数学の表記に倣って「=」(等しい)「>」(より大きい)「<」(より小さい)の組み合わせで記述する場合が多い。
その際、「~以上」(≧)は「>=」または「=>」、「~以下」(≦)は「<=」または「=<」とする。不一致(≠)は「!=」や「<>」などで表されることが多い。
「=」は代入の意味で用いられることもあるため、混同や誤用しないよう一致の比較演算子を「==」などとする言語も多い。一致・不一致の演算子は数だけでなく文字や文字列、真偽値など様々なデータ型に用いられる。
異なるデータ型の比較
「1==“1”」のようなデータ型の異なる値同士の比較を許容する(自動的に一方の型に変換して比較する)言語と、これを禁じてエラーとして処理する言語がある。前者の場合、例えば「==」を実質的な内容の一致、「===」を内容とデータ型両方の一致(厳密等価演算子あるいは同値演算子と呼ばれる)として使い分ける言語もある。
複合的なデータ構造の比較
オブジェクト指向言語におけるインスタンスや、配列などの複合的なデータ構造などを比較できる言語もある。
その際、一致・不一致は「両方ともメモリ上の同一の実体を指し示している」(参照が一致している)ことを意味する場合と、「含まれるデータの型や値がすべて同じである」(内容が一致している)ことを意味する場合がある。どちらか一方の比較のみ可能な場合と、それぞれを異なる記法で書き分けるようになっている場合がある。
ドット演算子
プログラミング言語で用いられる演算子の一つで、オブジェクトやコレクションなどの構成要素(メンバー)にアクセスするためのもの。文字列の結合演算を表す言語もある。
例えば、オブジェクト指向言語の多くは「obj.prop」のように記述すると、objオブジェクトのpropプロパティにアクセスすることができる。「p=obj.prop+1;」のように変数として値を読み出したり、「obj.prop=1;」のように値を代入することができる(可能な操作は言語や対象により異なる)。「obj.meth();」のようにメソッドを呼び出すこともできる。
言語によっては「p=Math.PI;」「r=Math.round();」のように、クラスに属するクラス変数やクラスメソッドもドット演算子で呼び出すことができる。C言語などでは構造体や共用体のメンバへのアクセスにも用いられる。
C言語やC++言語では、ポインタからメンバにアクセスする場合は「ptr->member」のようにアロー演算子「->」を用いる。PerlやPHPではオブジェクトのメンバにアクセスするのがアロー演算子で、ドット演算子は「$a=$b.$c;」のように文字列を結合する演算子として用いられる。
代入演算子
プログラミング言語で用いられる演算子の種類の一つで、変数などに値を代入するためのもの。多くの言語では「=」(イコール)が用いられる。
例えば、C言語やJavaなどで「a=1」と記述した場合、数学のように「aは1に等しい」という意味ではなく、「aに1を代入せよ」という命令として作用する。「+」が加算を行う演算子であるように、「代入という操作を行うための演算子」と考えられるため、代入演算子と呼ばれる。
一方、条件式などの中で、両辺の値が等しいか否かを判定する演算子のことは「等価演算子」(equality operator)という。C言語等では「==」がこれに当たり、「a==1」という式は「aの値は1に等しいか否か」を表す真偽値(1ならtrue、1以外ならfalse)となる。
代入演算子に「=」を用いる言語では、例えば「現在の値に1を加える」という操作を「a=a+1;」のように記述するため、初学者が数学の等式との違いで混乱し、つまずきの原因になっているといった批判もある。Pascalのように代入を「:=」、比較を「=」として数学の表記に近づけた言語もある。
言語によっては、算術演算子などと組み合わせ、代入時に同時に演算を行うことができる複合的な演算子も用意されており、「複合代入演算子」(compound assignment operator)という。例えば、「a+=1;」のように記述すると「aの元の値に1を加算した値をaに代入する」という意味になる。
真理値 【論理値】
論理学で、ある命題が「真」(true)であるか「偽」(false)であるかを示す値のこと。英語の頭文字を取って真を「T」、偽「F」の文字で表すこともある。
プログラミング言語などにも命題の真偽を表す仕組みや表記法が用意されていることがあり、真理値あるいはブール値(boolean value)などと呼ぶ。条件式や論理演算(ブール演算)の結果を表すことができ、真理値を表すことができるデータ型を論理型、ブーリアン型(ブール型)などという。
<$Fig:truthtable|right|true>リテラルの表記は言語によって異なるが、真は「true」「True」「TRUE」などと、偽は「false」「False」「FALSE」などと表記することが多い。真理値に相当する値を整数で代用し、0が偽、0以外が真とする言語や処理系もある。
電子回路などの場合には、真理値を1ビットの値の0と1に対応付け、電流のオンとオフ、電圧の高低、電荷の有無などの物理量で表す。デジタル信号の1を真、0を偽に対応付けるのが一般的。
論理演算子 【ブール演算子】 ⭐
プログラミング言語などに用意された、論理演算を表す記号や符号などのこと。真(true)と偽(false)の二値からなる真偽値(真理値/ブール値)に対して演算を行うことができる。
論理否定(NOT)、論理和(OR)、論理積(AND)、排他的論理和(XOR)のそれぞれについて、「&&」といった1~2文字記号の組み合わせや、「and」などの符号を演算子として用いる。具体的な演算子の定義は言語によって異なる。否定論理積(NAND)や否定論理和(NORなどの演算子が用意されている場合もある。
NOTは「!a」(aではない)のように演算対象となる被演算子(オペランド)を一つ記述する単項演算子で、他は「a && b」(aかつb)のように二つを記述する二項演算子である。「a && b && c」(aかつbかつc)のように三つ以上を連結することもでき、複数の論理演算のどれを先に計算するか優先順位が決まっている(ほとんどの場合NOT→AND→ORの順)。
論理演算子とビット演算子
コンピュータでは1ビットの値の1を真に、偽を0に置き換えて論理演算子を行うことが頻繁にあり、二つのビット列のそれぞれ対応する桁にある値同士(NOTではビット列の各桁の値)で論理演算を行うことをビット演算という。
ビット演算のための演算子をビット演算子と呼び、各論理演算子に対応する演算を行うためのビット演算子が別に用意されていることが多い。例えばC言語や多くの派生言語では「&&」が論理演算のAND、「&」がビット演算のAND、「||」が論理演算のOR、「|」がビット演算のORとなっている。
論理積 【AND演算】
論理演算の一つで、二つの命題のいずれも真のときに真となり、それ以外のときは偽となるもの。論理回路や2進数の数値の場合は、二つの入力の両方が1のときのみ出力が1となり、いずれか一方あるいは両方が0の場合は0となる。
論理学では記号「∧」を用いて「P∧Q」のように表記し、電子工学(論理回路)では記号「⋅」を用いて「P⋅Q」のように表す。論理積演算を行う論理回路を「論理積演算回路」「AND演算回路」「ANDゲート」などと呼ぶ。
多くのプログラミング言語でもビットごとの論理積演算を行う演算子が用意されており、キーワード「and」を用いて「P and Q」と書くものや、C言語に倣って「&」(アンパサンド)記号を用いて「P&Q」と表記する言語が多い。また、ビット演算と区別して条件式などで用いる真偽値(真理値)の論理積演算を定義している言語では、「and」キーワードや「&&」などの記号が用いられることが多い。
三入力以上の場合は、まず二つを選んで論理積を取り、その結果と残りの一つを選んで論理積を取り、という手順を繰り返すことで結果を得ることができ、すべての入力が1のときのみ出力が1となり、いずれかの入力が0の場合には0となる。
論理積は論理和(OR演算)と論理否定(NOT演算)を組み合わせて P∧Q ⇔ ¬(¬P∨¬Q) と表すことができる。逆に、論理和は論理積と論理否定を組み合わせて P∨Q ⇔ ¬(¬P∧¬Q) と表すことができる。これをド・モルガンの法則という。
論理和 【OR演算】
論理演算の一つで、二つの命題のいずれか一方あるいは両方が真のときに真となり、いずれも偽のときに偽となるもの。論理回路や2進数の数値の場合は、二つの入力のいずか一方あるいは両方が1のとき出力が1となり、いずれも0の場合に0となる。
論理学では記号「∨」を用いて「P∨Q」のように表記し、電子工学(論理回路)では記号「+」を用いて「P+Q」のように表す。論理和演算を行う論理回路を「論理和演算回路」「OR演算回路」「ORゲート」などと呼ぶ。
多くのプログラミング言語でもビットごとの論理和演算を行う演算子が用意されており、キーワード「or」を用いて「P or Q」と書くものや、C言語に倣って「|」記号を用いて「P|Q」と表記する言語が多い。また、ビット演算と区別して条件式などで用いる真偽値(真理値)の論理和演算を定義している言語では、「or」キーワードや「||」などの記号が用いられることが多い。
三入力以上の場合は、まず二つを選んで論理和を取り、その結果と残りの一つを選んで論理和を取り、という手順を繰り返すことで結果を得ることができ、いずれかの入力が1のときに出力が1となり、すべての入力が0の場合に0となる。
論理和は論理積(AND演算)と論理否定(NOT演算)を組み合わせて P∨Q ⇔ ¬(¬P∧¬Q) と表すことができる。逆に、論理積は論理和と論理否定を組み合わせて P∧Q ⇔ ¬(¬P∨¬Q) と表すことができる。これをド・モルガンの法則という。
論理否定 【NOT演算】
論理演算の一つで、与えられた命題が真のときに偽となり、偽のとき真となるもの。論理回路や2進数の数値の場合は、入力が1のとき0となり、0のとき1となる。
論理学では記号「¬」を用いて「P¬Q」のように表記し、電子工学(論理回路)では記号「¯」(上線)を用いて「P」のように表す。論理否定演算を行う論理回路を「否定演算回路」「NOT演算回路」「NOTゲート」などと呼ぶ。
多くのプログラミング言語でもビットごとの論理否定演算(ビット反転)を行う演算子が用意されており、キーワード「not」を用いて「not p」のように書くものや、C言語などの記法にならって「~」(チルダ)記号を用いて「~p」のように表記する言語が多い。
ビット演算と区別して条件式などで用いる真偽値(真理値)の論理否定演算を定義している言語では、「not」キーワードや「!」などの演算子が用いられることが多い。いずれの場合も、演算の対象となる被演算子(オペランド)が一つの単項演算子である。
XOR 【eXclusive OR】
論理演算の一つで、二つの命題のいずれか一方のみが真のときに真となり、両方真や両方偽のときは偽となるもの。論理回路や2進数の数値の場合は、二つの入力のうち片方のみが1であるときのみ出力が1となり、両方1や両方0の場合は0となる。
論理和(OR演算)に似ているが、論理和では「いずれか一方が真」なら他方が何であれ結果は真となるが、排他的論理和では「いずれか一方のみが真」の場合に真となる。両者共に真の場合は真とならないことを「排他的」と表現している。
三入力以上の場合は、まず二つを選んで排他的論理和を取り、その結果と残りの一つを選んで排他的論理和を取り、という手順を繰り返すことで結果を得ることができる。入力における真の数が奇数個のときに出力が真に、偶数個のとき偽となる。
論理学では記号「⊻」を用いて「P⊻Q」のように表記し、電子工学(論理回路)では記号「⊕」を用いて「P⊕Q」のように表す。排他的論理和演算を行う論理回路を「排他的論理和回路」「XOR回路」「XORゲート」などと呼ぶ。
多くのプログラミング言語でもビットごとの排他的論理和演算を行う演算子が用意されており、キーワード「xor」を用いて「P xor Q」と書くものや、C言語に倣って「^」(ハット、キャレット)記号を用いて「P^Q」と表記する言語が多い。
あるビットが「0」のとき、「1」と排他的論理和を取ると「1」になるが、元の値が「1」なら結果は「0」になる。すなわち、「1と排他的論理和を取る」という演算は「そのビットの値を反転する」という操作になる。これを利用して、反転したい位置を「1」にセットしたビット列を用いて、入力値の特定のビットのみを反転させるという操作がよく用いられる。
制御構造 【制御フロー】
コンピュータプログラムで、命令が実行される流れを定めたもの。また、プログラミング言語の仕様や構文のうち、命令の流れを定義することができるもの。
命令の出現順、記述順の通りに順番に命令を実行する「順次構造」(sequence)、条件によって実行する命令の流れがいくつかに分岐する「選択構造」(selection)あるいは「分岐構造」、同じ命令の流れを繰り返し実行する「反復構造」(iteration)あるいは「繰り返し構造」(repetition)の3つを基本とする考え方が多い。
また、方法論や言語の違いにより、これらに加えて、プログラム中の任意の別の箇所に実行の流れを移す「無条件分岐」(ジャンプ命令、goto文)や、別の命令群に流れを移し、終わると元の場所に流れを戻す「サブルーチン」(呼び出し、コール)、プログラム終端以外の箇所で実行を終わらせる「停止」(終了)などを加える場合もある。
プログラミング言語における制御構造
機械語やアセンブリ言語(ニーモニック)のようなCPUの構造に忠実な低水準言語では、命令実行の流れを制御する命令として無条件ジャンプ命令と条件ジャンプ命令しか用意されていないことが多く、他の制御構造はこれらと他の命令を組み合わせて実装する。
人間に分かりやすく抽象的なプログラム構造を記述できる高水準言語では、選択や反復を記述するための制御文が用意されていることが多い。言語によって名称や仕様は異なるが、選択構造は「if文」(二分岐)や「switch文」(多分岐)などで、反復構造は「for文」「while文」「do-while文」などで記述することができる。
順次構造 ⭐⭐⭐
コンピュータプログラムの命令実行の流れの一つで、プログラムに記述された順番通りに命令を実行していくもの。
コンピュータのCPUがプログラムを実行する際、特に指定がなければプログラムを先頭から読み込んで命令を並んでいる順に従って一つずつ実行していく。この最も基本的な命令実行の制御構造を、(他の構造と対比するため便宜的に)順次構造と呼ぶ。
一方、命令の中には命令実行の流れを変更するものもある。これを用いて、条件に従って別の実行位置に流れを分岐させる制御構造を「選択構造」あるいは「分岐構造」、条件が満たされる間だけ同じ個所を繰り返し実行する制御構造を「反復構造」あるいは「繰り返し構造」という。
選択構造 【分岐構造】 ⭐⭐⭐
コンピュータプログラムの命令実行の流れの一つで、実行時に評価する条件によって、次の命令を実行するか、指定されたメモリ上の位置に移行するか分岐するもの。
コンピュータのCPUがプログラムを実行する際、特に指定がなければ命令を先頭から順に実行するが、分岐命令が存在する場合、特定の条件が満たされたらメモリの指定番地に実行位置を変更(ジャンプ)し、以降はそこから順に命令を実行していく。
このような実行制御を「条件分岐」と呼び、プログラムに複雑な処理をさせたい場合は必須の機能となる。一方、条件が満たされる間だけ同じ個所を繰り返し実行する制御構造もあり、「反復構造」あるいは「繰り返し構造」という。
反復構造 【繰り返し構造】 ⭐⭐⭐
コンピュータプログラムの命令実行の流れの一つで、指定の条件が満たされている間、特定の個所を何度も繰り返し実行するもの。
コンピュータのCPUがプログラムを実行する際、特に指定がなければ命令を先頭から順に実行するが、反復構造になっている場合、指定の条件が満たされている間、指定範囲の末尾の命令を実行したら範囲の先頭に戻り、その範囲を繰り返し実行する。
同じ処理を様々な対象に次々に適用したい場合などに用いられ、プログラムに複雑な処理をさせたい場合には必須の機能となる。一方、特定の条件が満たされたらメモリの指定番地に実行位置を変更(ジャンプ)する制御構造もあり、「選択構造」あるいは「分岐構造」という。
ネスト 【入れ子】 ⭐
あるものの中に、それと同じ形や種類の(一回り小さい)ものが入っている状態や構造のこと。IT分野では、コンピュータプログラムやデータ構造において、ある構造の内部に同じ構造が含まれている状態のことを指す。
よく知られるのはプログラムの制御構造の入れ子構造で、if( 条件A ){ ... if( 条件B ){ ... } ... } といったように、条件分岐やループの内部に、別の条件分岐やループなどが含まれた制御構造を指す。複雑な条件による分岐や多重ループを記述するための基本的なテクニックとして多くのプログラミング言語で利用できる。
for文の中にfor文を記述するなど、同じ構文を入れ子状に繰り返すことを指す場合が多いが、while文の中にif文など、異なる制御構文を内部に記述することも含む場合がある。内側の構文の内部にさらに構文を重ねて、マトリョーシカのように何重も入れ子にすることができ、階層の多さを「入れ子構造の深さ」と表現することがある。
サブルーチンなどの入れ子構造
プログラミング言語の中には、サブルーチンやプロシージャ、関数、クラスなどのコードのまとまりを入れ子構造させ、内部に同種のまとまりを定義することができるものもある。例えば、関数の内部に定義された別の関数を「関数内関数」「ローカル関数」などと呼び、クラスの内部に定義された別のクラスを「クラス内クラス」「インナークラス」「内部クラス」などという。
データ構造の入れ子構造
あるデータ構造の要素として、そのデータ構造自身を埋め込むことができる場合があり、データ構造の入れ子構造を形成する。例えば、配列を構成する個々の要素が配列になっている多次元配列は配列の入れ子構造である。
配列の配列など、内部が再帰的に同じ構造になっているものを指すことが多いが、連想配列の要素が配列になっているものなど、制御構文の場合と同じように異なる構造が入れ子状になっている場合も含むことがある。
ネスト 【入れ子】
あるものの中に、それと同じ形や種類の(一回り小さい)ものが入っている状態や構造のこと。IT分野では、コンピュータプログラムやデータ構造において、ある構造の内部に同じ構造が含まれている状態のことを指す。
よく知られるのはプログラムの制御構造のネストで、if( 条件A ){ ... if( 条件B ){ ... } ... } といったように、条件分岐やループの内部に、別の条件分岐やループなどが含まれた制御構造を指す。複雑な条件による分岐や多重ループを記述するための基本的なテクニックとして多くのプログラミング言語で利用できる。
for文の中にfor文を記述するなど、同じ構文を入れ子状に繰り返すことを指す場合が多いが、while文の中にif文など、異なる制御構文を内部に記述することも含む場合がある。内側の構文の内部にさらに構文を重ねて、マトリョーシカのように何重も入れ子にすることができ、階層の多さを「ネストの深さ」と表現することがある。
サブルーチンなどのネスト
プログラミング言語の中には、サブルーチンやプロシージャ、関数、クラスなどのコードのまとまりをネストさせ、内部に同種のまとまりを定義することができるものもある。例えば、関数の内部に定義された別の関数を「関数内関数」「ローカル関数」などと呼び、クラスの内部に定義された別のクラスを「クラス内クラス」「インナークラス」「内部クラス」などという。
データ構造のネスト
あるデータ構造の要素として、そのデータ構造自身を埋め込むことができる場合があり、データ構造のネストを形成する。例えば、配列を構成する個々の要素が配列になっている多次元配列は配列のネストである。
配列の配列など、内部が再帰的に同じ構造になっているものを指すことが多いが、連想配列の要素が配列になっているものなど、制御構文の場合と同じように異なる構造が入れ子状になっている場合も含むことがある。
条件式
プログラミング言語などで用いられる式の種類の一つで、値や式の比較や論理演算を組み合わせたもの。計算結果は真(true)または偽(false)となり、プログラムの分岐条件の記述などに用いられる。
二つの項が満たすべき関係を関係演算子(比較演算子)によって記述し、複数の関係を論理演算子によって組み合わせることができる。項は値(リテラル)や変数のほか、算術式や関数などを置いて計算結果を評価させることもできる。
関係演算子は二項を比較してどのような関係にあるかを表す演算子で、「等しい」(C言語では“==”)、「等しくない」(同“!=”)、「より大きい」(同“>”)「以上」(同“>=”)「より小さい」(同“<”)「以下」(同“<=”)などがある。論理演算子は命題の関係を記述する演算子で、「ではない」(NOT演算/C言語では“!”)、「または」(OR演算/同“||”)、「かつ」(AND演算/同“&&”)などがある。
条件式はこれらを組み合わせて記述する。例えば「a > 0 && a < b」という式は「aが0より大きく、かつ、aがbより小さい」という意味で、計算時のaやbの値によって、この条件が満たされる場合は式の値は真(true)に、満たされない場合は偽(false)になる。
条件式は「if( a > b )[ … }」といったようにif文やwhile文などの制御構文の条件として記述するほか、言語によっては「t = a > b;」のように演算結果をブール型の変数などに代入できる場合もある。
サブルーチン 【サブルーティン】
コンピュータプログラムの中で特定の機能や処理をひとまとまりの集合として定義し、他の箇所から呼び出して実行できるようにしたもの。単に「ルーチン」とも呼ばれる。
プログラム中の様々な状況や箇所で繰り返し必要となるような処理をサブルーチンとして名前をつけて一つの塊として定義することで、その処理を何度も繰り返し記述・複製する必要がなくなり、コード量の削減や開発効率の向上、記述ミスなどによる誤り(バグ)の減少などが期待できる。
サブルーチン内部の処理に反映させるため、呼び出し側から値を指定できるようになっている場合が多く、この値を「引数」(ひきすう/argument)という。また、処理結果として呼び出し元に値を返すことができる場合があり、この値は「返り値」あるいは「戻り値」という。返り値を持つサブルーチンは「関数」(function)と呼ぶのが一般的である。
かつてはプログラムが起動したとき最初に実行される主系統のコード集合を「メインルーチン」(main routine)、そこから呼び出される形で実行される副系統のコード群をサブルーチンと呼んで区別していたが、現在ではそのような構造に当てはまらない例も増えており、サブルーチンのことを単にルーチンと呼ぶことも多い。
サブルーチンに相当するコード集合は、プログラミング言語によっては「プロシージャ」(procedure)のように異なる名称で呼ばれることもある。オブジェクト指向プログラミングでは一般的に「メソッド」(method)という。返り値を持つか否かで名称が異なる言語(Pascalのプロシージャと関数など)や、C言語のようにすべてを関数と呼ぶ場合もある。
プロシージャ
「手続き」という意味の英単語で、コンピュータプログラム内で複数の命令や処理などを一つにまとめ、外部から呼び出し可能にしたものをこのように呼ぶことがある。
全体として何らかの特定の処理や機能を実現するために作成されるもので、繰り返し必要になるコードをまとめておくことで何度も似たようなコードを記述しなくて済むようになり、プログラムの保守性や再利用性も高まる。
このようなコードのかたまりを作成する仕組みを何と呼ぶかはプログラミング言語によって異なり、ルーチン(routine)、関数(function/ファンクション)、メソッド(method)なども似たような仕組みを指す(言語により意味や仕様はそれぞれ異なる)。PascalやVisual Basicのように呼び出し元に値を返さないものをプロシージャ、返すものを関数と呼んで区別する場合もある。
関数 【ファンクション】 ⭐⭐⭐
コンピュータプログラム上で定義されるサブルーチンの一種で、数学の関数のように与えられた値(引数)を元に何らかの計算や処理を行い、結果を呼び出し元に返すもののこと。
プログラム上で関連する一連の命令群を一つのかたまりとしてまとめ、外部から呼び出せるようにしたサブルーチンやプロシージャ(手続き)の一種である。呼び出し時に引数(ひきすう/argument)と呼ばれる値を指定することができ、この値をもとに内部で処理を行って、結果を返り値(かえりち/return value)あるいは戻り値(もどりち)として呼び出し元に通知する。
プログラミング言語によって、返り値を持つものを関数(ファンクション)、処理を行うだけのものをサブルーチンやプロシージャとして区別する場合もある(Pascalなど)が、C言語やJavaScriptのようにすべてが関数で引数や返り値が省略可能になっている言語もある。
多くのプログラミング言語は開発者が自由に関数を定義してプログラム中で呼び出せる構文や記法を定めているほか、算術関数や文字列処理などよく使われる基本的な関数言語仕様や標準ライブラリなどの中であらかじめ実装済みとなっている(組み込み関数)。
関数といっても数学のように計算を行うものには限られず、「利用者に入力を促して入力値を返す」関数といったものもあり得る。途中で画面に何かを表示するなど、引数や返り値と直接関係ない処理を行ってもよい。
プログラムは内部に変数の値など実行状態を持つため、これを反映して同じ引数から異なる返り値が得られる場合もある。また、関数が行う処理によって状態が変化することもあり、これを関数の持つ「副作用」という。多くの算術関数のように副作用のない関数もある。
組み込み関数 【ビルトイン関数】 ⭐
プログラミング言語などの仕様にあらかじめ用意されている標準関数のうち、コンパイラやインタプリタなどの言語処理系自体に実装が組み込まれている関数のこと。
多くのプログラミング言語は、関数やサブルーチン、クラスなど部品化された機能単位を組み合わせて複雑なプログラムを作成する仕組みを持っている。ある言語で利用できる関数のうち、言語仕様に規定されており、処理系が直接解釈できるものを組み込み関数という。
言語によって何が用意されているかは異なるが、基本的・汎用的な文字列操作や算術演算、入出力などの関数が提供されていることが多い。オブジェクト指向言語の場合は、組み込みクラスや組み込みオブジェクト、およびそれらに付随する組み込みメソッドが同様の役割を果たす。
言語仕様に規定され、標準的に利用できる関数全体を「標準関数」という。言語によっては、組み込み関数以外にも、部品化されたプログラム集であるライブラリによって提供される標準関数が規定されている場合がある。そのような関数は「標準ライブラリ関数」という。
これに対し、開発者が自らのプログラム上で独自に定義・実装した関数を「ユーザー定義関数」(user-defined function)という。SDKなど特定の用途や環境でのみ利用可能な関数などもユーザー定義関数として実装されて提供される。
引数 ⭐⭐
プログラム中で関数やメソッド、サブルーチンなどを呼び出すときに渡す値のこと。渡された側はその値に従って処理を行い、結果を返す。オペレーティングシステム(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)があり、どちらもサポートしている言語と片方のみサポートしている言語がある。
値渡しは変数の内容をコピーして渡す方法で、渡された関数などが変数の内容を変更しても、元の変数には影響がない。参照渡しは変数の所在を表す情報を渡す方法で、渡した側と渡された側が同じ変数を共有するため、呼び出された側で変更を加えると呼び出し側にも変更が反映される。
実引数
プログラム中で関数やメソッドを呼び出す際に、呼び出し手続きの中に記述される、引き渡される値や変数のこと。
関数などを呼び出す際に外部から与える値を「引数」というが、呼び出し側のコードの中に記述される値のことを実引数という。呼び出し側で利用している変数名の他に、定数やリテラル、式、他の関数呼び出し(の結果)などを指定できる。
例えば、与えられた二値の和を求める sum という関数があり、function sum(a, b){ return a + b; }のように定義されているとき、これを呼び出す y = sum(x, 1); というコードの1やxが実引数である。関数側でこれを受け取るaやbは「仮引数」(formal argument)という。この例ではxの値がaに、1がbに代入され、a+bという処理が実行される。
仮引数
プログラム中で関数やメソッドを呼び出して実行する際、関数側で値を受け取るために宣言された変数のこと。
関数などを呼び出す際に外部から与える値を「引数」というが、呼び出し側が指定する値を「実引数」(actual argument)、呼び出される側でこれを受け取る変数などを仮引数という。
多くの言語では関数定義の先頭などで変数名を列挙して宣言され、実引数とは記述した順番に従って対応付けられるようになっていることが多い。言語によってはデータ型の宣言を伴う場合もあり、対応する仮引数と実引数でデータ型が整合している必要がある。
例えば、与えられた二値の和を求める sum という関数があり、int sum(int a, int b){ return a + b; } のように定義されている場合、aとbが仮引数となる。これを呼び出し側で y = sum(x, 1); と記述すれば、aにxの値が、bに1が代入され、関数内の処理が実行される。
仮引数と実引数の数が常に一致している必要がある言語と、後ろ側の要素の一部を省略することができる言語がある。また、引数の数をあらかじめ固定せず、呼び出し毎に変更することができる「可変長引数」(可変個引数)に対応している言語もある。
値渡し 【値呼び出し】
コンピュータプログラム中で関数やプロシージャなどに渡す引数として変数などを指定する際、その値のみを引き渡す方式。渡された引数の値を変更しても呼び出し元の変数の値は更新されない。
プログラム中で関数などを呼び出す際に、処理に反映させるパラメータなどを呼び出し元が指定することができる。呼び出し元が呼び出し文中で指定するものを実引数、呼び出された側が実引数を受け取るために用いる変数などを仮引数という。
実引数として定数やリテラルを渡す場合には、仮引数にその値が代入されて処理に用いられるだけだが、実引数に呼び出し側が使用している変数やオブジェクトなどを指定する場合、実引数の変数名で表される実体と仮引数の変数名で表される実体との関係をどのように扱うかという問題がある。
値渡しはリテラルなどを渡すのと同じように値が仮引数に複製されて処理に用いられる方法で、仮引数の変数の内容を変更しても、呼び出し元の実引数の変数には何の影響も及ぼさない。
一方、実引数と仮引数が完全に同じ実体を表すように引数を受け渡すことを「参照渡し」(call by reference)という。参照渡しされた仮引数へ加えられた変更はすべて呼び出し元の実引数にも反映されている。
参照渡し 【参照呼び出し】
コンピュータプログラム中で関数やプロシージャなどに渡す引数として変数などを指定する際、呼び出し先でも同じ実体を参照するように渡す方式。渡された引数に変更を加えると呼び出し元にも同じように反映される。
プログラム中で関数などを呼び出す際に、処理に反映させるパラメータなどを呼び出し元が指定することができる。呼び出し元が呼び出し文中で指定するものを実引数、呼び出された側が実引数を受け取るために用いる変数などを仮引数という。
実引数として定数やリテラルを渡す場合には、仮引数にその値が代入されて処理に用いられるだけだが、実引数に呼び出し側が使用している変数やオブジェクトなどを指定する場合、実引数の変数名で表される実体と仮引数の変数名で表される実体との関係をどのように扱うかという問題がある。
参照渡しは仮引数と実引数が完全に同じ実体を表すように引数を受け渡す方式で、呼び出し先が仮引数に新しい値を代入するなどの変更を行うと、呼び出し元の実引数に指定された変数などにも変更が反映される。
一方、実引数から仮引数へ値のみを複製して渡し、両者が異なる実体として扱われる引き渡し方法を「値渡し」(call by value)という。値渡しか参照渡しかはプログラミング言語によって決まっているが、参照渡しが可能な言語では値渡しも選択できるようになっていることが多い。
ポインタ渡しとの違い
C言語やJavaなどでは、変数などへの参照を表す値(Cにおけるポインタの値など)を複製して引き渡す「ポインタ渡し」が参照渡しにほぼ相当する機能として提供される。
(本来の)参照渡しは呼び出し先で参照先を変更するような操作(新しいオブジェクトを生成して代入するなど)を行うと呼び出し元にもその変更が反映されるが、ポインタ渡しは参照を表す値を渡しているだけなので、参照先を変更しても呼び出し元の参照先は呼び出し前と変わらない。
これは参照渡しが「参照の参照」を渡して参照に対する変更を反映しているように動作する(実際そのように実装している言語もある)ためで、ポインタ渡しを「参照の値渡し」、参照渡しを「参照の参照渡し」のように呼ぶ場合もある。
戻り値 【返り値】 ⭐⭐
プログラム中で呼び出された関数やメソッド、サブルーチンなどが処理を終了する際に、呼び出し元に対して渡す値。計算結果の報告などのために用いられる。
関数などが処理を行った結果として呼び出し元に報告される値のこと。反対に、呼び出し元から関数などに対してパラメータとして渡す値のことは「引数」(ひきすう、argument)という。
戻り値は計算結果の数値や処理結果のデータなどが代表的だが、処理が正しく終了したかどうかを表す真偽値やコード番号、メッセージなどを返す場合もある。多くの言語では「return x+y;」(変数xとyの和を返却する)のようにreturn文(リターン文)と呼ばれる記法で返す値を指定する。
ほとんどのプログラミング言語では戻り値は一つしか返すことができないが、変数への参照やメモリアドレス(ポインタ)を返したり、配列などの複合的なデータ構造、データ型に値を格納して返すことで、複数のデータの集合を返すことができるようになっていることが多い。C言語のvoid型関数のように、明示的に何も返さないよう指定できる言語もある。
関数などを定義する際に戻り値のデータ型もあらかじめ宣言するようになっていることが多く、呼び出し側で受け取る変数の型も揃える必要がある。言語によっては、同じ名前だが引数と戻り値のデータ型が異なる複数の関数やメソッドなどを同時に定義し、引数の型によって自動的に使い分ける機能(オーバーロード)が利用できる場合もある。
再帰呼び出し 【リカーシブコール】
コンピュータプログラム中で外部から呼び出し可能な関数やプロシージャ(手続き)などが、その内部で自身を呼び出すこと。そのような処理を実装した関数を「再帰関数」(recursive function)という。
関数などの内部の処理を記述したプログラムの中で、自らを呼び出すコードが含まれる構造を指す。例えば、階乗の計算 n!=n×(n-1)! やフィボナッチ数列 Fn=Fn-1+Fn-2 のように、定義や計算法にある種の再帰的な構造が含まれている場合、これをシンプルなコードに書き表すことができる。
現代的なプログラミング言語のほとんどは再帰呼び出しが可能な仕様となっているが、再帰的に自身を呼び出す関数などを記述する際には、何重に呼び出されても内部の状態が壊れないよう配慮された「リエントラント」(再入可能)な状態管理が行われている必要がある。
また、関数の中で自らを呼び出す箇所の手前に、脱出条件を満たしたら関数を終了する条件分岐などを記述しなければならない。脱出コードが無かったり条件が誤っていると、無限に自身を呼び出し続けて終了しないプログラムとなってしまう。その場合、実際に実行すると関数呼び出しに用いるメモリ上のスタック領域を使い果たして異常終了することになる。
モジュール
機能単位、交換可能な構成部分などを意味する英単語。機器やシステムの一部を構成するひとまとまりの機能を持った部品で、システム中核部や他の部品への接合部(インターフェース)の仕様が明確に定義され、容易に追加や交換ができるようなもののことを指す。
人工物の構成要素や部品のうち、内部がより単純な複数の要素で構成され、それ自体がある程度まとまった何らかの意味のある機能を有するようなものを指す。他の構成要素と繋いだり、組み合わせて使用するための規約や仕様が、要素自体の仕様とは別に独立して定義されている点も重要である。
このような構成単位を組み合わせて全体を構成する手法を「モジュラー型」設計という。モジュール単位で容易に交換でき、モジュール内部の設計や実装の詳細を他のモジュールや全体の設計者が知る必要がない(ブラックボックス化)ため、要素ごとの分業や専門化が可能となる。
高度にモジュール化が進んだ工業製品の代表としてはパソコンがあり、CPUやメインメモリ(RAM)、マザーボード、ストレージ、入出力装置といった機能単位ごとに専門のメーカーがいくつもあり、購入時に好きな部品を選んで組み合わせたり、後から最新の部品に交換して機能や性能を向上させることができる。
ソフトウェアのモジュール
ソフトウェアの分野でも重要な概念で、モジュール化されたソフトウェア部品のことを「ソフトウェアモジュール」あるいは「プログラムモジュール」という。分野や製品によっては「コンポーネント」「パッケージ」などと呼ぶこともある。
大規模なソフトウェアの中には機能ごとにモジュールを組み合わせた設計になっているものがあり、利用者が必要な機能だけを組み合わせて導入したり、別の開発者や利用者が追加機能を開発して組み込んだり、全体を入れ替えることなく一部を修正・改良できるようになっている。
ソフトウェア開発およびプログラミングでも、特定のプログラミング言語で利用できるプログラム部品をモジュールという。近年の多くの言語では公式のモジュール配布サイトが用意されており、プログラマは必要な機能を実装したモジュールを組み込むことにより、自ら開発することなくその機能を利用することができる。
データ構造
データの集まりをコンピュータプログラムで扱いやすいように、一定の形式で格納したもの。特定の問題を解く手順(アルゴリズム)には、それぞれに適したデータ構造がある。
複数のデータの配置や関係性、データの参照や出し入れなどの操作のルールを定義したもので、様々な種類がある。それぞれに特徴や適した処理があるため、同じ処理の記述でも、目的に対して適切なデータ構造を選択できるかどうかでプログラムの複雑さや処理性能に大きな差がつくことがある。
データ構造の種類
最も基本的なデータ構造には、要素を一列に並べた「配列」(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次元配列」と呼ぶことがある。
添字 【添え字】 ⭐⭐
文字の周囲に小さく添えられた文字。ITの分野では、プログラミングにおいて配列などに格納された個々の要素を指し示す値などをこのように呼ぶ。
配列変数は一つの変数に複数の値を並べて格納できるデータ構造で、多くのプログラミング言語に標準で用意されている。配列内の各要素を識別・指定するために通し番号が与えられており、これをコード上で変数名の隣などに記述したものを添字という。
例えば、C言語やその記法を受け継ぐ多くの言語では角括弧で囲んだ数字が配列の添字を表し、“a[0]” は配列aの先頭の要素を、“a[9]” は先頭から10番目の要素をそれぞれ指し示す。
スクリプト言語などでは配列の添字として0から始まる整数の通し番号以外に、任意のプリミティブ型(実数や文字列など)の値を指定できるデータ構造が用意されていることがあり、言語によって連想配列、ハッシュ、マップ、辞書(ディクショナリ)など様々な名称で呼ばれる。
IT以外の分野では、論文などの文章中で参照すべき注釈の位置を記した番号や記号、数学のべき乗の指数や対数の底、化学式の原子の数などのように、文字の斜め上や下などに小さく添えられた数字や文字、記号、数式などが添字の一種である。
1次元配列 【一次元配列】 ⭐
プログラミング言語などが扱うデータ構造の一つで、各要素に値が直に格納されている、単純な構造の配列のこと。多次元配列と対比する文脈で用いる用語。
配列(array)は多くのプログラミング言語に用意されている基本的なデータ構造の一つで、単純に複数のデータを一列に並べたものである。コード中で配列は配列名で参照され、配列内の各要素は添字(インデックス)によって識別される。
配列の要素に配列が格納されており、配列が入れ子状になったデータ構造を扱うことができる言語もあり、これを「多次元配列」という。例えば、配列の要素が配列になっており、その要素は値であるような2段階の入れ子構造を「2次元配列」と呼ぶ。
「1次元配列」という呼称はこのような入れ子状の配列と対比して、単に値が並んでいるだけの単純な配列のことを指す。注釈なく単に「配列」という場合は通常は1次元配列のことを意味することが多い。
2次元配列 【二次元配列】 ⭐
配列の各要素が配列になっており、その中の各要素に値が格納されているような配列のこと。データ群を縦横に項目の並んだ表や、数学の行列のような構造に格納して整理することができる。
配列(array)は多くのプログラミング言語に用意されている基本的なデータ構造の一つで、単純に複数のデータを一列に並べたものである。コード中で配列は配列名で参照され、配列内の各要素は添字(インデックス)と呼ばれる番号で識別される。
配列の要素が配列に、さらにその要素が配列に…という具合に入れ子構造になっている「配列の配列」を「多次元配列」(multidimensional array)という。2次元配列はその最も基本的な構造で、配列の要素が配列になっており、その要素に個々の値が格納されている。
例えば、C言語やその記法を受け継ぐ言語で整数型の配列aを int a=[2][3]; のように宣言すると、a[0]やa[1]は通常の配列とは異なりそれ自体が配列となっている。その配列の要素が値であるため、値にアクセスするには「a[0][0]」(1番目の配列の1番目の要素)、「a[1][2]」(2番目の配列の3番目の要素)のように添字を2つ指定する。
連想配列
プログラミング言語などに用意されたデータ構造の一種で、文字列など非負整数以外のデータを添字に使用することができる配列のこと。
配列(array)は多くのプログラミング言語に用意されている基本的なデータ構造の一つで、単純に複数のデータを一列に並べたものである。コード中で配列は配列名で参照され、配列内の各要素は添字(インデックス)によって識別される。
通常の配列は添字に0または1から始まる整数(非負整数)の通し番号を用いるが、連想配列では添字に文字列など非負整数に限らず任意のデータを設定することができる。連想配列における添字のことは「キー」(key)と呼ぶことが多い。
キーと値は一対一に対応付けられて格納され、値はキーを指定することで取り出すことができる。格納する値として単独の値(スカラ値)だけでなく配列などのデータ構造を格納したり、別の連想配列を入れ子状に格納することができる言語もある。
例えば、通常の配列では x[0]="日曜" のように記述していたものを、連想配列では x["Sunday"]="日曜" のように記述することができ、要素を番号で管理する場合に比べコードの見通しが良くなることがある。ただし、単純な配列に比べ要素の追加や取り出しが遅く、処理効率や性能では劣るため、用途に応じて通常の配列と使い分ける必要がある。
言語によっては同様のデータ構造を「辞書」あるいは「ディクショナリ」(dictionary)、「ハッシュ」(hash)、「マップ」(map)、「連想リスト」(associative list)などと呼ぶこともある。また、PHPのように添字が整数の配列も連想配列の一種として扱われる言語や、JavaScriptのようにオブジェクトが連想配列の一種として定義される言語もある。
なお、文字列のキーと任意の値を一対一に対応付けて格納するという構造はデータベースの一種である「KVS」(Key-Value Store:キーバリューストア)と同様であり、連想配列が実装された言語はデータの永続的な保存手段としてKVSとの相性が良い。
リスト ⭐⭐
一覧(表)、目録、羅列、一覧に載せる、一覧にする、などの意味を持つ英単語。一般的の外来語としては同じ種類の情報を羅列した一覧のことを指すことが多く、ITの分野でもこの用法が多い。
プログラミングの分野では、ソースコードのことを「プログラムリスト」「ソースリスト」などと呼び、これを略してリストということがある。
データ構造のリスト
基本的なデータ構造の一つで、複数のデータを順序を付けて格納することができる複合データ型(コンテナ/コレクション)をリストという。
中でも、各データが次のデータの所在を表す参照情報(リンク/ポインタ)を持っているものを「連結リスト」(linked list:リンクリスト/リンクトリスト)と呼び、これを略してリストという場合も多い。リストは他に動的配列などを用いても実装することができる。
連結リストの各要素はデータの他に自分の隣の要素を指し示す所在情報を持っている。これを辿ることで、各要素に順番にアクセスすることができる。各要素が自分の次(後)の要素への参照のみを持つ構造を「片方向リスト」「単方向リスト」と呼び、これに加えて自分の前の要素への参照をもつものを「双方向リスト」という。
また、先頭から末尾へ直線上に要素が連結されているものを「線形リスト」、先頭も末尾もなく要素が円環状に連結されているものを「循環リスト」という。
キュー 【待ち行列】
最も基本的なデータ構造の一つで、要素を入ってきた順に一列に並べ、先に入れた要素から順に取り出すという規則で出し入れを行うもの。窓口などの順番を待つ人の行列をモデル化したものとも言える。
キューは先頭が常に最も古い要素になるデータ構造で、新しい要素は必ず末尾に追加される。取り出すときは常に先頭の最も古い要素から取り出される。このように先に入れたものほど先に取り出される管理方式を「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)という。
例えば、コンピュータからプリンタにデータを伝送する速度とプリンタがデータを紙に印刷する速度では、後者のほうが圧倒的に遅い。伝送と印刷を同時に行おうとするとコンピュータ側はほとんどの時間待たされることになり無駄であるため、印刷データを一旦キューに保管し、プリンタの処理の進み具合に応じて専用の制御プログラムが少しずつデータを伝送する手法が用いられる。
スタック
最も基本的なデータ構造の一つで、要素が入ってきた順に一列に並べ、後に入れた要素から順に取り出すという規則で出し入れを行うもの。本や書類、箱などを積み上げて置くことになぞらえてこのように呼ばれる。
スタックは要素が入ってきた順に並べ、先頭が最も古く、末尾が最も新しい要素となる。取り出すときは末尾にある最も新しいものから順に取り出す。このように後に入れたものほど先に取り出される管理方式を「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コーディング、サーバ側(バックエンド)プログラミング、クライアント側(フロントエンド)プログラミング、テスト、機材や回線の調達・導入、ネットワーク設定、サーバ管理、システム運用、プロモーション、利用者サポートなどを一人でできる人材のことをフルスタックであるという。
クラス
級、階級、等級、格、類、分類、種類、学級、科目、授業などの意味を持つ英単語。ITの分野では、オブジェクト指向プログラミングにおけるオブジェクトの雛形や、何らかの階級や分類を表す名称の一部としてよく用いられる。一般の外来語としては学校などの学級の意味でよく使われるほか、商品やサービスの等級や格を表すこともある。
オブジェクト指向プログラミングのクラス
オブジェクト指向では、互いに関連するデータと、データに対する操作(メソッド)を一つの「オブジェクト」(object)と呼ばれる単位に一体化(カプセル化)して取り扱う。あるオブジェクトがどのようなデータとメソッドから作られるのかを定義した雛形をクラスという。
プログラムの実行時にはクラスを元にメモリ空間上に具体的なオブジェクトが生成される。この実体化されたオブジェクトのことを「インスタンス」(instance)という。同じクラスから複数のインスタンスを生成することができ、それぞれ異なる内部状態を持つことができる。
クラスには、オブジェクト内部で取り扱うデータ(フィールド/メンバ変数)の名称やデータ型、アクセス可能な範囲(クラス外から参照・操作可能か否かなど)を宣言する。同様にメソッド(メンバ関数)の名称や引数、処理内容の詳細、アクセス範囲も記述する。
データや手続きは通常はインスタンスに属するが、クラスそのものに属するものを宣言することができる。クラス自体に属するデータを「クラス変数」(静的フィールド/静的メンバ変数)、クラス自体に属する手続きを「クラスメソッド」(静的メソッド)という。
クラスの継承
クラスベースのプログラミング言語では、あるクラスを元に一部を改変して別のクラスを定義することができ、これをクラスの「継承」(inheritance)という。このとき、元になったクラスを「親クラス」(parent class)「スーパークラス」(superclass)「基底クラス」(base class)などと呼び、新たに定義されたクラスは「子クラス」(child class)「サブクラス」(subclass)「派生クラス」(derived class)などという。
抽象的・汎用的なクラスを元に具体的な機能を付け足したクラスを派生させていくことで、大規模なソフトウェアを効率的に開発することができる。言語によっては親クラスのメソッドを子クラスが同じ名前で別の内容に差し替えることができる。このように、同じ名前がクラスによって異なる内容を指すことを「ポリモーフィズム」(polymorphism:多態性)という。
プロトタイプベース
オブジェクト指向プログラミング言語のうち、元になるオブジェクトを複製し、要素や動作の追加や変更を行うことで新しいオブジェクトを定義する方式。オブジェクトの雛形にあたる「クラス」(class)を定義するクラスベース(class-based)のオブジェクト指向と対比される。
クラスベースでいう「インスタンス」(instance)に当たる具体的なオブジェクトしか存在しない仕様で、新しいクラスの定義や既存クラスからの派生・継承に当たる動作はオブジェクトのクローン(複製)を作って内容を追加・変更するという手順で行う。
SelfやLuaなどの言語がプロトタイプベースの仕様を持ち、class構文導入前のJavaScriptもよく例として挙げられる。JavaScriptは確かにクラス定義に相当する仕様を持たなかったが、new構文やprototypeオブジェクトなど、クラスベースとの折衷のような変則的な仕様とも言われる。
プロパティ 【属性】 ⭐
財産、資産、物件、所有物、特性、属性、性質、効能などの意味を持つ英単語。ITの分野では、ソフトウェアが取り扱う対象(オブジェクト)の持つ設定や状態、属性などの情報をプロパティということが多い。一般の外来語としてはあまり定着しておらず、不動産や資産といった意味で企業名の一部などに用いられることがある。
様々な分野や場面で用いられる一般的な用語で、それぞれの対象が持つ固有の属性値やその集合体のことを指す。例えば、「ファイルのプロパティ」と言った場合には、ファイル名やファイルの種類、ストレージ上での所在、アクセス権の設定、作成日時、最終更新日時、データサイズ、読み取り属性などが含まれる。
Windowsなどでは、対象のプロパティの表示や変更を行う設定画面や設定ソフトなどのことを「○○のプロパティ」のように表示するため、文脈によっては「プロパティを開く」といったようにこの設定画面のことを指してプロパティという場合もある。
オブジェクト指向プログラミングにおけるプロパティ
オブジェクト指向プログラミングでは、オブジェクトのフィールド(メンバ変数)を外部から直に操作するように記述できるが、実際には内部的にメソッド呼び出しを利用するよう自動的に変換してくれる機能をプロパティということがある。
通常、フィールドへ外部からアクセスするには「アクセサメソッド」(setterメソッド/getterメソッド)を定義する必要があるが、プロパティ機能のある言語ではこれを簡易化し、少ないコード量で安全にフィールドへアクセスできるようにしてくれる。
例えば、objオブジェクトのPropフィールドを外部から参照するには、クラス内でgetPropメソッドを定義し、外部から x=obj.getProp() のように記述するのが一般的だが、プロパティとして宣言することにより x=obj.Prop のように記述するだけで内部的にアクセサメソッドを呼び出して値を取り出してくれる。
メソッド
方法、方式、手法、やり方、などの意味を持つ英単語。ITの分野では、オブジェクト指向プログラミングにおけるオブジェクトに対する手続きのことや、通信プロトコルにおける要求の種類などのことをメソッドということが多い。一般の外来語としては、一定の形式として確立した奏法、教授法、指導法、その他様々な技法のことを「○○メソッド」のように言う。
オブジェクト指向プログラミングのメソッド (メンバ関数)
オブジェクト指向プログラミング(OOP)では、データと手続きを「オブジェクト」(object)として一体化(カプセル化)して定義、利用する。この、オブジェクトに内包された手続き(データに対する処理内容を記述したプログラム)のことをメソッドという。言語によっては「メンバ関数」などということもあるが、ほぼ同じものを指す。
メソッドはそのオブジェクトに対する操作内容の詳細が実装されており、外部からメソッドを呼び出して起動することにより、その内容が実行される。操作の詳細をオブジェクト内部に隠蔽することができ、プログラムの再利用性や生産性を高めやすくなると言われている。
インスタンスメソッドとクラスメソッド
一般的なメソッドは実行時に展開されるクラスのインスタンス(instance)に付属する「インスタンスメソッド」(instance method)で、所属するインスタンスのプロパティに対する操作などを行うことができる。「メンバメソッド」(member method)と呼ばれることもある。
一方、言語によってはクラス自体に付属する「クラスメソッド」(class method)を定義できる場合があり、クラス変数(静的変数/スタティック変数)の操作や参照、あるいは特に内部状態を必要としない基本的・汎用的な機能の提供などのために用いられる。「静的メソッド」(static method/スタティックメソッド)と呼ばれることもある。
メソッドのオーバーライド
一般的なクラスベースの言語ではメソッドはクラスの一部として定義される。あるクラスの内容を引き継いで一部を変更して別のクラス(サブクラス/派生クラス)を定義する際、元のクラスにあるメソッドと同名のメソッドを定義して別の内容に置き換える場合がある。
この操作をメソッドの「オーバーライド」(overriding)と言い、同名のメソッドがクラスによって異なる振る舞いをすることを「多態性」(polymorphism:ポリモーフィズム)という。サブクラスで機能を追加・変更する必要がある場合などに利用する。引数の型や数を派生元クラスのメソッドに揃えなければならないなどの制約を課している言語もある。
HTTPリクエストメソッド
通信プロトコルのHTTPでは、クライアントからサーバへ要求(リクエスト)を行う際、その種類を示すデータのことをメソッドと呼んでいる。主なメソッドとして、資源の送信を要求する「GETメソッド」、資源の受信(クライアント側から送信)を要求する「POSTメソッド」、資源本体ではなく資源についての情報(メタデータ)を要求する「HEADメソッド」などがある。
オブジェクト
物、物体、目標物、対象、目的語、客体、などの意味を持つ英単語。
コンピュータ上で操作や処理の対象となる何らかの実体のことをオブジェクトという。例えば、操作画面上でアイコンなどの形で表示されるデータ集合や操作要素、図形描画ソフトで画面上に配置した個々の図形、3次元コンピュータグラフィックス(3DCG)で空間に配置した立体などが該当する。
オブジェクトコード
コンピュータプログラムの形式の一つで、コンピュータ(のCPU)が直に解釈・実行できる記述形式(機械語/マシン語)によって構成されているものをオブジェクトコード(object code)という。
一般的に、人間が理解しやすいプログラミング言語で書かれたソースコード(source code)を、専用のソフトウェアによって自動的に翻訳(変換)した結果得られるコードであり、ここでいう “object” は「モノ」ではなく「目的」という意味である。また、オブジェクトコードを格納したファイルをオブジェクトファイルという。
オブジェクト指向
コンピュータプログラムの設計や実装についての考え方の一つで、互いに密接に関連するデータと手続き(処理手順)をオブジェクトと呼ばれる一つのまとまりとして定義し、様々なオブジェクトを組み合わせて関連性や相互作用を記述していくことによりシステム全体を構築していく手法をオブジェクト指向(object oriented)という。
オブジェクトにはそれぞれ固有のデータ(属性/プロパティ)と手続き(メソッド)があり、外部からのメッセージを受けてメソッドを実行し、データを操作する。オブジェクトに付随するデータの操作は原則としてすべてオブジェクト中のメソッドによって行われる。オブジェクトを定義する雛形をクラス(class)、クラスに基づいてプログラム実行時にコンピュータのメモリ上に展開されたオブジェクトのことをインスタンス(instance)と言うが、実際上はインスタンスのことを指してオブジェクトと呼ぶことも多い。
オブジェクト指向の考え方をプログラミングに応用した手法をオブジェクト指向プログラミング(OOP)、プログラミング言語の仕様や機能に反映したものをオブジェクト指向プログラミング言語(オブジェクト指向言語)などという。
インスタンス化
オブジェクト指向プログラミングで、クラスなどの定義に基づいて実行時にメモリ上に領域を確保し、実際にデータの集合体を生成すること。生成されたオブジェクトの実体を「インスタンス」(instance)という。
クラスはオブジェクトがどのような変数(プロパティ)や手続き(メソッド)を持つかを定義した雛形であり、プログラム中で実際にオブジェクトとして扱うにはメインメモリ上に領域を確保して実体化する必要がある。
同じクラスからインスタンス化したオブジェクトは同じプロパティとメソッドを持つが、各プロパティに代入されるデータ(値)はそれぞれのインスタンスごとに固有(インスタンス変数の場合)となり、あるインスタンスのプロパティを変更しても、同じクラスの他のインスタンスの同名プロパティは影響を受けない。
インスタンスメソッド 【メンバメソッド】
オブジェクト指向プログラミングにおけるメソッドの種類の一つで、個々のインスタンスに付随するもの。
オブジェクト指向のプログラミング言語では、互いに関連するデータの集合と、それらデータに対する処理内容を記述した手続きを「オブジェクト」(object)として一体的に定義する。オブジェクトの持つデータを「プロパティ」(property)、手続きを「メソッド」(method)などと呼ぶ。
インスタンスメソッドはプログラムの実行時にインスタンス化されたオブジェクトの一部として機能するメソッドで、そのインスタンスに含まれるプロパティに対する操作などを行うことができる。特に指定などをせず普通にメソッドを定義すればインスタンスメソッドとなる言語が多く、単にメソッドといった場合は一般的にはインスタンスメソッドのことを指すことが多い。
一方、クラス自体に付随する「クラスメソッド」(静的メソッド/スタティックメソッド)など、特殊なメソッドを定義できる言語もあり、「インスタンスメソッド」とあえて呼ぶ場合はこうした特殊なメソッドと対比する文脈が多い。
クラスメソッド 【静的メソッド】
オブジェクト指向プログラミングで定義されるメソッドの種類の一つで、個々のインスタンスではなくクラスそのものに付随するもの。
オブジェクト指向のプログラミング言語では、互いに関連するデータの集合と、それらデータに対する処理内容を記述した手続きを「オブジェクト」(object)として一体的に定義する。オブジェクトの持つデータを「プロパティ」(property)、手続きを「メソッド」(method)などと呼ぶ。
多くの言語では通常のメソッドは個々のインスタンスに付随する「インスタンスメソッド」(instance method/メンバメソッドとも呼ばれる)とみなされ、そのインスタンスのプロパティの操作などを行うために定義され、外部から呼び出される。
一方、静的メソッドはクラスに付随するものとみなされ、インスタンスからではなくクラスから直接呼び出して実行される。クラス変数(静的変数/スタティック変数)への参照や操作を行うための機能や、様々なプログラムから共通して利用される汎用的な機能の実装などに用いられることが多い。
なお、「クラスメソッド」(class method)と「静的メソッド」(スタティックメソッド、staticメソッド)は多くの場合同じ意味だが、言語によっては両者を異なるものとして使い分ける場合もある。また、インスタンス変数へアクセス可能かどうかや、継承時のクラス変数の値などは言語ごとに仕様が異なる。
クラスメソッド 【静的メソッド】
オブジェクト指向プログラミングで定義されるメソッドの種類の一つで、個々のインスタンスではなくクラスそのものに付随するもの。
オブジェクト指向のプログラミング言語では、互いに関連するデータの集合と、それらデータに対する処理内容を記述した手続きを「オブジェクト」(object)として一体的に定義する。オブジェクトの持つデータを「プロパティ」(property)、手続きを「メソッド」(method)などと呼ぶ。
多くの言語では通常のメソッドは個々のインスタンスに付随する「インスタンスメソッド」(instance method/メンバメソッドとも呼ばれる)とみなされ、そのインスタンスのプロパティの操作などを行うために定義され、外部から呼び出される。
一方、クラスメソッドはクラスに付随するものとみなされ、インスタンスからではなくクラスから直接呼び出して実行される。クラス変数(静的変数/スタティック変数)への参照や操作を行うための機能や、様々なプログラムから共通して利用される汎用的な機能の実装などに用いられることが多い。
なお、「クラスメソッド」(class method)と「静的メソッド」(スタティックメソッド、staticメソッド)は多くの場合同じ意味だが、言語によっては両者を異なるものとして使い分ける場合もある。また、インスタンス変数へアクセス可能かどうかや、継承時のクラス変数の値などは言語ごとに仕様が異なる。
カプセル化
オブジェクト指向プログラミングにおいて、互いに関連するデータの集合とそれらに対する操作をオブジェクトとして一つの単位にまとめ、外部に対して必要な情報や手続きのみを提供すること。外から直に参照や操作をする必要のない内部の状態や構造は秘匿される。
オブジェクトは外部に公開された手続き(メソッド)により機能を提供する。内部の状態を表す変数なども、外部からの参照・操作が必要なものだけが専用の手続きによってアクセス可能となり、それ以外は外から見えない存在となる。
十分にカプセル化されたオブジェクトを組み合わせてプログラムを構築していくことにより、オブジェクトの内部の仕様の変更が外部に予期せぬ影響を及ぼしたり、外部からの予期せぬ干渉でオブジェクトの状態が壊されることを防ぐことができるようになる。
通信におけるカプセル化
データ通信においてカプセル化といった場合には、ある通信手順(プロトコル)によるデータ表現の内部に、別のプロトコルによるデータ表現を埋め込んで伝送することを指す。
通信プロトコルの多くは、送受信するデータの基礎単位(パケットやフレームなど)の構造を定義しており、先頭に制御情報などを含むヘッダ領域、その後に運びたいデータの本体(ペイロードやボディ)が続いている(末尾にも制御情報などが付加される場合もある)。このデータ本体部分に、より上位のプロトコルの送受信単位を埋め込むことをカプセル化という。
カプセル化は多段階に行われることが多く、各階層のプロトコルは自らの機能に専念し、上位あるいは下位のプロトコルの詳細を気にしなくても良くなる。また、インターネットのように様々な伝送媒体や異なる管理主体のネットワークをまたいで通信するのも容易となる。
例えば、LAN上をWebデータが流れる場合、EthernetフレームのペイロードにIPパケットがカプセル化され、IPパケットのペイロードにTCPパケットがカプセル化され、TCPパケットのペイロードにHTTPメッセージがカプセル化されて伝送される。
コンストラクタ 【構築子】
オブジェクト指向プログラミング言語において、クラスをインスタンス化する際に実行される特別なメソッド。インスタンスの初期化処理などを記述する。
言語により仕様や定義の仕方は異なるが、C++言語やJavaではクラス定義の内部でクラス名と同名のメソッドを定義すると、それがコンストラクタとして呼び出される。厳密にはコンストラクタにメソッド名はなく内部的には無名のメソッドとして取り扱われる。コンストラクタのための予約語が決められていて、これを名前とするメソッドを定義する言語もある。
コンストラクタ内では他のインスタンスメソッドと同じように任意の処理を記述することができるが、プロパティ(メンバ変数)の初期値の設定などを行うのが一般的である。インスタンスの初期化を超えてあまり複雑な機能を持たせるべきではないとされる。
コンストラクタの呼び出しは、そのクラス外のコード上でnew演算子などを用いて、「クラス名 変数名=new クラス名(引数);」のように変数宣言と同時に行うことが多い。生成されたインスタンスは宣言された変数に代入され、以降のコードで操作可能になる。
多くの言語では他のメソッドと同じように引数を指定することができ、インスタンス化する側のコードからパラメータを渡すことができる。一方、通常は生成したインスタンスへの参照が返り値として呼び出し側に渡されるため、他のメソッドのようにreturn文などで返り値を指定することはできない。
コンストラクタとは逆に、不要になったインスタンスを破棄する直前に実行する特殊なメソッドを定義できる言語もあり、「デストラクタ」(destructor)と呼ばれる。インスタンスが消滅する際に必要な後処理などを記述し、実行後はインスタンスが消滅してメモリが解放される。
getterメソッド 【ゲッターメソッド】
オブジェクト指向プログラミングで、オブジェクト内部のメンバ変数(属性、プロパティ)を外部から読み取るために用意されたメソッド。メンバ変数をオブジェクト内部に隠蔽し、外部から直接参照させないようにする。
オブジェクト指向においてインスタンス内の変数などは内部の状態を表すものであり、外部から直に参照したり操作したりすべきでないという考え方がある。外部から必要とされる変数についてはアクセス用のメソッドを用意して呼び出してもらうことで、変数自体は公開せずにアクセスできるようになる。
そのようなメンバ変数アクセス用のメソッド群のことを「アクセサ」(accessor)と呼ぶ。このうち、外部から変数の内容を取得(読み取る)するために用意されたものをゲッタメソッドという。慣例として「get変数名」と命名されることが多く、実行するとその変数の現在の値を返す。機能や名称が定型的であるため、言語や開発ツールによってはゲッタメソッドを自動生成してくれる機能が用意されていることもある。
一方、アクセサのうちメンバ変数に値を代入(書き込み)するために用意されたものは「setterメソッド」あるいは「setアクセサ」「ライター」(writer)などと呼ぶ。「set変数名」などのメソッド名で引数として値を受け取り、名前で示されるメンバ変数に代入する。
setterメソッド 【セッターメソッド】
オブジェクト指向プログラミングで、オブジェクト内部のメンバ変数(属性、プロパティ)に外部から書き込むために用意されたメソッド。メンバ変数をオブジェクト内部に隠蔽し、外部から直接参照させないようにする。
オブジェクト指向においてインスタンス内の変数などは内部の状態を表すものであり、外部から直に参照したり操作したりすべきでないという考え方がある。外部から必要とされる変数についてはアクセス用のメソッドを用意して呼び出してもらうことで、変数自体は公開せずにアクセスできるようになる。
そのようなメンバ変数アクセス用のメソッド群のことを「アクセサ」(accessor)と呼ぶ。このうち、外部からメンバ変数に値を代入(書き込み)するために用意されたものをセッタメソッドという。慣例として「set変数名」と命名されることが多く、実行すると引数に指定された値を名前が示す変数に代入する。機能や名称が定型的であるため、言語や開発ツールによってはセッタメソッドを自動生成してくれる機能が用意されていることもある。
一方、アクセサのうちメンバ変数の値を取得(読み取り)するために用意されたものは「getterメソッド」あるいは「getアクセサ」「リーダー」(reader)などと呼ぶ。「get変数名」などのメソッド名で、実行すると名前で示されるメンバ変数の値を返す。
アルゴリズム ⭐⭐⭐
ある特定の問題を解く手順を、単純な計算や操作の組み合わせとして明確に定義したもの。数学の解法や計算手順なども含まれるが、ITの分野ではコンピュータにプログラムの形で与えて実行させることができるよう定式化された、処理手順の集合のことを指すことが多い。
曖昧さのない単純で明確な手順の組み合わせとして記述された一連の手続きで、必ず有限回の操作で終了し、解を求めるか、解が得られないことが示される。コンピュータで実行する場合は、基礎的な演算、値の比較、条件分岐、手順の繰り返しなどを指示する命令を組み合わせたプログラムとして実装される。
数値などの列を大きい順または小さい順に並べ替える「整列アルゴリズム」、たくさんのデータの中から目的のものを探し出す「探索アルゴリズム」、データが表す情報を損なわずにより短いデータに変換する「圧縮アルゴリズム」といった基本的なものから、画像の中に含まれる人間の顔を検出する、といった複雑なものまで様々な種類のアルゴリズムがある。
同じ問題を解くアルゴリズムが複数存在することもあり、必要な計算回数や記憶領域の大きさ、手順のシンプルさ、解の精度などがそれぞれに異なり、目的に応じて使い分けられる。例えば、ある同じ問題に対して、原理が単純で簡単にプログラムを記述できるが性能は低いアルゴリズム、計算手順が少なく高速に実行できるが膨大な記憶領域を必要とするアルゴリズム、厳密な解を求めるものより何桁も高速に近似解を求めることができるアルゴリズムなどがある。
探索 ⭐
未知の物事を探し求めること。情報科学では、データ集合などの中から指定の条件に合致する要素を見つけ出す操作を指すことが多い。
データの探索
何らかのデータ形式やデータ構造として集められたデータの集合に対して、一定の手順に基づいて指定の条件を満たすデータを探し出し、一致したデータやその位置を明らかにする(あるいは対象の中には存在しないことを確定させる)操作のことを「探索」(search)という。
探索アルゴリズム
コンピュータなどで実行できるよう定式化された探索手順のことを「探索アルゴリズム」(search algorithm)という。例えば、最も単純な方法として、一列に並べたデータ列に対して端から順に指定の条件に一致するか照合する方法がある。これを「線形探索」(linear search)という。
また、順位や大小が比較できるデータ群であれば、大きい順または小さい順に整列(並べ替え)して、目的のデータと半分の位置にあるデータを比較すれば、含まれる方の半分に絞り込むことができる。残ったデータ群の半分の位置と比較すれば、もう半分に絞り込める。これを繰り返して残りが一つになれば探索完了となる。この方法は「二分探索」(binary search)と呼ばれる。
線形探索では一回の比較で一つしか候補が減らないため、平均してデータの個数に比例した回数の比較が必要となる(これを と表記する)が、二分探索ならば一回の比較で候補を半分に減らせるため、平均してデータの個数の2を底とした対数で済む(これを と表記する)。
このように、探索する対象の特性に適したアルゴリズムを選択することで効率的に探索を行うことができる。文字列内の特定のパターンを探索するためのアルゴリズムや、木構造やグラフなどのデータ構造に格納された要素を探索するためのアルゴリズムなどがよく知られている。
検索との違い
ITの分野では「検索エンジン」「全文検索」のようにデータ群から条件に一致するものを探し出す操作を「検索」と呼ぶこともある。いずれも英語では “search” であり、意味や用法に明確な違いはないが、慣例として情報科学などの学問分野では「探索」の語が、探索法を応用した具体的なシステムやサービスなどでは「検索」の語が好まれる。
探索アルゴリズム
コンピュータプログラムなどに実装される計算手順(アルゴリズム)の一種で、データ集合などの中から指定の条件に合致する要素を見つけ出すもの。
何かを探し出す手順を定式化したもので、探す対象は単体の数値であったり、特定のパターンに一致する文字列であったり、目的地までの最短経路であったり、将棋の最も有利な一手であったりする。データ構造や問題の種類によって様々なアルゴリズムが考案されている。
リスト探索
最も基本的な探索問題はリスト探索で、配列などに一列に並べられた要素の中から指定されたものを探し出す手順を考えるというものである。最も単純な探索法は「線形探索」(linear search)で、端から順に要素を照合していく方法である。効率は最も悪いがどんなリストでも探索することができる。
大きい順または小さい順に要素が並んだリストであれば「二分探索」(binary search)を用いることができる。全体の半分の位置にある要素を探している値と比較し、値が含まれる側の半分に絞り込む。次に絞り込んだ半分のリストの中央の値と比較し、四分の一に絞り込む。この手順を候補が一つになるまで繰り返せばよい。
二分探索と同じ原理だが、常にリストの真ん中の要素と比較するのではなく、大きさとリスト内の位置がほぼ比例していると仮定して探索値に近い値が出現しそうな位置を予想する手法を「内装探索」という。他にも、リストからハッシュテーブルや平衡二分探索木などのデータ構造を作り出して探索を効率化する手法などが知られている。
他の探索
文字列の中から別の文字列や指定の条件を満たす文字列パターンを探索することを「文字列探索」という。人間にとって意味のある文字列は様々な出現頻度で単語が並んだ構造になっているなどの特徴があり、KMP法やBM法など様々なアルゴリズムが提唱されている。
データ群をリストではなく木構造やグラフなどデータ同士の繋がりを表現することができる構造で表現し、一定の条件に基づいて探索を行うアルゴリズムもよく用いられる。現実の問題を定式化してコンピュータに解かせようとすると木探索、グラフ探索の問題に帰着することがよくある。
例えば、地図上の最短経路を求める問題はグラフ探索であり、ダイクストラ法やベルマンフォード法などの探索法が用いられる。将棋やチェスの指し手を考える問題は各手番の選択肢を木構造で表現した「ゲーム木」を探索する問題であり、ミニマックス法やアルファベータ法などのアルゴリズムがよく知られている。
線形探索 【リニアサーチ】 ⭐⭐
データ探索アルゴリズムの一つで、配列などに格納されたデータ列の先頭から末尾まで順番に、探しているデータと一致するか比較していく手法。
最も単純なアルゴリズムで、配列などに格納されたデータ列の中から、まず先頭の要素を探しているデータと比較する。一致しなければ2番目の要素と比較する。これを末尾の要素まで繰り返し、途中でデータを発見したらそこで探索を終了する。
N個のデータ列の中から線形探索する場合、最良のケースは先頭の要素と一致する場合で比較回数は1回、最悪のケースは末尾まで探してもデータが見つからなかった場合で比較はN回、平均の比較回数はN/2回となる。比較回数の平均値は要素数に正比例して増大する。
仕組みが単純なため短いプログラムコードで記述でき、コードを読んだ人が処理を理解しやすく、探索対象のデータ列以外に余分な記憶領域を消費せず、事前にデータ列のソート(大きい/小さい順に並べ直す処理)などの前処理を行う必要がないという利点がある。より高度なアルゴリズムに比べると平均の比較回数は多く、性能の高いアルゴリズムとは言えない。
線形探索 【リニアサーチ】
データ探索アルゴリズムの一つで、配列などに格納されたデータ列の先頭から末尾まで順番に、探しているデータと一致するか比較していく手法。
最も単純なアルゴリズムで、配列などに格納されたデータ列の中から、まず先頭の要素を探しているデータと比較する。一致しなければ2番目の要素と比較する。これを末尾の要素まで繰り返し、途中でデータを発見したらそこで探索を終了する。
N個のデータ列の中から単純前方探索する場合、最良のケースは先頭の要素と一致する場合で比較回数は1回、最悪のケースは末尾まで探してもデータが見つからなかった場合で比較はN回、平均の比較回数はN/2回となる。比較回数の平均値は要素数に正比例して増大する。
仕組みが単純なため短いプログラムコードで記述でき、コードを読んだ人が処理を理解しやすく、探索対象のデータ列以外に余分な記憶領域を消費せず、事前にデータ列のソート(大きい/小さい順に並べ直す処理)などの前処理を行う必要がないという利点がある。より高度なアルゴリズムに比べると平均の比較回数は多く、性能の高いアルゴリズムとは言えない。
二分探索 【2分探索】 ⭐⭐
データ検索アルゴリズムの一つで、一定の順序にソート(整列)済みのデータ群の探索範囲を半分に絞り込むを操作を繰り返すことで高速に探索を行う手法。
まず、データを降順(大きい順)あるいは昇順(小さい順)に並べ替え、探索したいデータが中央の要素より大きいか小さいかを調べる。これにより、データが全体の前半分にあるか後ろ半分にあるかを判定することができるため、存在しない側の半分は探索範囲から外すことができる。
半分になったデータ群の中央の要素と再び比較し、前半と後半のどちらにあるかを調べる。この操作を繰り返し行うことで、一回の操作ごとに探索範囲の大きさが半分になっていき、中央の要素が求めるデータに一致するか、探索範囲の要素数が一つになる(求めるデータは見つからなかったことが確定する)と探索は終了する。
値の大小は文字の索引順の前後関係などに適宜置き換えることにより、順序と比較手段を定義できればどのようなデータにも適用することができる。
n個のデータ群から平均でlog2n回の比較で探索を終えることができ、例えば1000個のデータを10回の比較で探索できる。原理は単純ながら高速なアルゴリズムである。ただし、要素があらかじめ整列済みである必要があるため、未整列のデータに適用するにはソートの分の計算時間も必要となる。
ソート 【整列】 ⭐
複数のデータが並んだ列を、何らかの順序に基いて順番通りになるよう並べ替えること。数値を大きい順または小さい順に並べたり、文字をアルファベット順や五十音順に並べたり、日時を古い順または新しい順に並べ替えることが該当する。
複数の同じ種類の要素が一列に並んでいる場合に、すべての要素に一律に適用可能な順序の規則を用いて並べ替える操作を意味する。数値と日付のように異なる種類の要素が混在していたり、要素間にじゃんけんの出し手のような循環的な関係性がある場合には正しく整列することができない。
数を小さい方から大きい方へ並べる順序を「昇順」(ascending order)、その逆を「降順」(descending order)という。数以外の場合、アルファベットを「A」から「Z」へ、読み仮名を「あ」から「ん」へ、日付や時刻を古い方(過去)から新しい方(未来)へといったように、本来の並び順や自然な順序を昇順、逆を降順という。
ソートアルゴリズム
コンピュータによるデータ処理でもソートは頻繁に用いられる操作で、整列手順を定式化したものを「ソートアルゴリズム」(sorting algorithm)という。古くから活発に研究され様々な手法が考案されており、計算回数の少なさ(高速さ)や必要な記憶装置の容量、手順のシンプルさ(プログラムの短さ)などが異なる。
平均的に効率が良く、広く用いられるのは「クイックソート」(quick sort)と呼ばれる手法で、要素数がn倍になると平均の計算時間が n×log2n 倍になる。プログラミング言語に標準で組み込まれた配列を整列する関数などによく採用されている。
データ列に同じ値が含まれる場合、その出現順がソート前後で変わらない手法を「安定ソート」(stable sorting)、保存されるとは限らない(順序が入れ替わることがある)手法を「不安定ソート」(unstable sorting)という。
また、元のデータ列の格納領域のみを用いて操作が完結する手法を「内部ソート」(in-place sorting)、外部に別の領域を確保する必要がある手法を「外部ソート」(external sorting)という。組み込みシステムなど利用できるメモリ領域が限られる場合には、高速性よりも内部ソートであることが重視されることもある。
ソート 【整列】
複数のデータが並んだ列を、何らかの順序に基いて順番通りになるよう並べ替えること。数値を大きい順または小さい順に並べたり、文字をアルファベット順や五十音順に並べたり、日時を古い順または新しい順に並べ替えることが該当する。
複数の同じ種類の要素が一列に並んでいる場合に、すべての要素に一律に適用可能な順序の規則を用いて並べ替える操作を意味する。数値と日付のように異なる種類の要素が混在していたり、要素間にじゃんけんの出し手のような循環的な関係性がある場合には正しく整列することができない。
数を小さい方から大きい方へ並べる順序を「昇順」(ascending order)、その逆を「降順」(descending order)という。数以外の場合、アルファベットを「A」から「Z」へ、読み仮名を「あ」から「ん」へ、日付や時刻を古い方(過去)から新しい方(未来)へといったように、本来の並び順や自然な順序を昇順、逆を降順という。
ソートアルゴリズム
コンピュータによるデータ処理でも整列アルゴリズムは頻繁に用いられる操作で、整列手順を定式化したものを「ソートアルゴリズム」(sorting algorithm)という。古くから活発に研究され様々な手法が考案されており、計算回数の少なさ(高速さ)や必要な記憶装置の容量、手順のシンプルさ(プログラムの短さ)などが異なる。
平均的に効率が良く、広く用いられるのは「クイックソート」(quick sort)と呼ばれる手法で、要素数がn倍になると平均の計算時間が n×log2n 倍になる。プログラミング言語に標準で組み込まれた配列を整列する関数などによく採用されている。
データ列に同じ値が含まれる場合、その出現順がソート前後で変わらない手法を「安定ソート」(stable sorting)、保存されるとは限らない(順序が入れ替わることがある)手法を「不安定ソート」(unstable sorting)という。
また、元のデータ列の格納領域のみを用いて操作が完結する手法を「内部ソート」(in-place sorting)、外部に別の領域を確保する必要がある手法を「外部ソート」(external sorting)という。組み込みシステムなど利用できるメモリ領域が限られる場合には、高速性よりも内部ソートであることが重視されることもある。
昇順 【小さい順】 ⭐
数字やアルファベット、ひらがな・カタカナ、日付、時刻、曜日など順序や方向が決まっている要素の列について、本来定められた順序のこと。英語の “ascending order” を略した “ASC” “asc” などの略号で示されることもある。
データの並べ替え(ソート)における順序の指定などに用いられる概念で、小さい方から大きい方へ、あるいは本来の並び順における先頭側から末尾側へ「昇(のぼ)っていく」順序のことを意味する。
数字であれば1、2、3…と小さい値から大きい値へ、アルファベットであれば「A」から「Z」に向けて、カナであれば「ア」から「ン」に向けて、日付や時刻であれば過去側・古い側から未来側・新しい側に向けて並べる順序である。
一方、大きい方から小さい方へ、あるいは本来の並び順とは逆に並べる順序は「降順」(descending order)という。「9、8、7」「Z、Y、X」「ん、を、わ」といった本来とは逆の並び順のことである。
降順 【大きい順】 ⭐
数字やアルファベット、ひらがな・カタカナ、日付、時刻、曜日など順序や方向が決まっている要素の列について、本来とは逆の順序のこと。英語の “descending order” を略した “DESC” “desc” などの略号で示されることもある。
データの並べ替え(ソート)における順序の指定などに用いられる概念で、大きい方から小さい方へ、あるいは本来の並び順における末尾側から先頭側へ「降(お)りていく」順序のことを意味する。
数字であれば9、8、7…と大きい値から小さい値へ、アルファベットであれば「Z」から「A」に向けて、カナであれば「ン」から「ア」に向けて、日付や時刻であれば未来側・新しい側から過去側・古い側に向けて並べる順序である。
一方、小さい方から大きい方へ、あるいは本来の並び順の通りに並べる順序は「昇順」(ascending order)という。「1、2、3」「A、B、C」「あ、い、う」といった本来定められた並び順のことである。
バブルソート 【単純交換法】 ⭐⭐
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの最も基本的な手法の一つで、端から順番に隣接する要素同士を比較・交換していくもの。
すべての要素について隣接する要素と大きさを比較し、並べたい順番と逆転していたら両者を入れ替える。この手順を最高で要素数-1回繰り返すと並べ替えが完了する。要素の入れ替えが発生しなくなった時点で処理を打ち切ってもよい。
一般的な実装では、この処理を列の一方の端から反対の端まで順番に行うことが多く、繰り返しの度に未整列の要素の中で最も大きな(あるいは小さな)要素が列の端に移動していく様子を泡(バブル)が浮き上がっていく様に例えてこのような名称となった。
最良の場合の計算時間は O(n) と高速だが、最悪の場合の計算時間は O(n2) と整列法の中でも最も遅い部類に入り、平均して高速な手法とは言えない。ただし、要素の比較・交換は順序を問わず並列化しやすいという特徴があり、並列分散処理が可能な環境では高速化することができる。
整列したいデータ列以外の記憶領域を用意しなくてよいインプレースソート(内部ソート)で、同じ大きさの要素の順序が入れ替わらない安定ソートである。アルゴリズムの理解や実装が容易で、コードの記述量が少ない。実用上はあまり使われないが、整列法の学習ではほぼ必ず取り上げられ、効率化した派生アルゴリズムも多く考案されている。
選択ソート 【基本選択法】
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの最も基本的な手法の一つで、未整列の要素の中から最大あるいは最小のものを選択し、整列済みの列の末尾に追加していくもの。
数値の列を先頭から小さい順(昇順)に並べる場合を考える。まず、先頭から末尾までの間で最も小さい値を見つけ、先頭の値と交換する。次に2番目から末尾までの間で最も小さい値を見つけ、2番目の値と交換する。
以降も同様に、「n番目から末尾までで最も小さい値を見つけ、n番目と入れ替える」という操作を繰り返す。これを末尾の一つ前の値まで繰り返せば、先頭が最も小さく末尾が最も大きい数値の列が得られる。
列の元の状態によらず O(n2) の計算量がかかるため処理時間の予測はしやすいが、ソートアルゴリズムの中では最も遅いものの一つに分類される。木構造の一種である二分ヒープ木を用いて改良した手法を「ヒープソート」(heap sort)という。
整列したいデータ列以外の記憶領域を用意しなくてよいインプレースソート(内部ソート)で、同じ大きさの要素の順序の維持は保証されない不安定ソートである。挿入ソートなどと同じように、アルゴリズムの理解や実装が容易なため、対象データ列が短いことが分かっている場合などに利用されることがある。
挿入ソート 【基本挿入法】
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの最も基本的な手法の一つで、未整列の要素を一つずつ、整列済みの列の適切な位置に挿入していくもの。
数値の列を先頭から小さい順(昇順)に並べる場合を考える。まず、先頭から2つの値を比較して小さい方を先頭に、大きい方を2番目に置く。次に3番目の値を取り出し、先頭・2番目と順に比較し、適切な位置に挿入する。
4番目以降も同様にして、n番目の値を取り出して先頭からn-1番目までと順番に比較し、適切な位置に挿入する操作を繰り返す。これを末尾の値まで繰り返せば、先頭が最も小さく末尾が最も大きい数値の列が得られる。
n番目の値を挿入する際、それが整列済みの列の中で最も小さければ先頭の値との1回の比較で挿入位置が決定できるが、最も大きければ整列済みの値の数(n-1回)だけ比較を繰り返さなければならない。
すなわち、要素が整列済みに近い状態ならば高速に整列を完了でき、最良計算時間はO(n)となるが、逆順に並んでいる場合は比較回数が爆発的に増大し、最悪計算時間は O(n2) となってしまう。この欠点をある程度緩和したアルゴリズムとして「シェルソート」(Shell sort)がある。
整列したいデータ列以外の記憶領域を用意しなくてよいインプレースソート(内部ソート)で、同じ大きさの要素の順序が維持される安定ソートである。アルゴリズムの理解や実装が容易なため、対象データ列が短いことが分かっている場合などに利用されることがある。人間に並べ替えを行わせると、多くの人がまっさきに自然に思いつく方法であるとも言われる。
クイックソート
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの一つで、分割統治法を応用したもの。最も高速な手法の一つで、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になったところで整列終了となる。このとき、端から順に小さい順に値が並んでいることが分かる。
マージソート 【併合ソート】
与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの一つで、データ列を細かく分割し、整列しながら次第に併合(merge)していくもの。
最初にデータ列を半分、そのまた半分と分割していき、一つ一つのデータがバラバラになるまで分割する。その後、最初は単体のデータ同士を、続いて要素数が同じ列同士を順に併合していく。
併合する際は二つの列の先頭のデータを比較し、小さい(あるいは大きい)方を取り除いて併合列に追加する。二つの列の内部はすでに整列済みであるため、両方の列のデータが無くなるまでこの手順を繰り返すことで、整列済みの併合列を得ることができる。列が一つの併合されたら整列完了となる。
平均計算時間も最悪計算時間もO(nlogn)となる極めて高速なソートアルゴリズムだが、元のデータ列の他に作業用の記憶領域を必要とする。実装上の配慮により、同じ大きさの要素の順序が入れ替わらない安定ソートとすることができる。
エラトステネスの篩 【sieve of Eratosthenes】
与えられた整数以下の素数をすべて発見する計算手順(アルゴリズム)の一つ。素数判定法の一種で、古代ギリシャの学者であるエラトステネス(Eratosthenes)が紀元前3世紀頃に考案したとされるため、このように呼ばれる。
まず、2から目的の数までの整数のリストを用意する。このリストの中から最初の素数である2の倍数を消していく。リストに残った整数のうち、先頭にある3が次の素数である。次に、リストの中から3の倍数を消してゆき、残った整数のうち先頭にある5が次の素数である。
このように、先頭に残った数の倍数をリストから消してゆき、その都度先頭に残った数を集めると、素数のリストが得られる。このアルゴリズムが「篩」(ふるい)と呼ばれるのは、この一連の操作が、粉状のものを何段階もふるいにかけてより分ける作業に似ていることに由来する。
この操作は目的の数まで繰り返す必要はなく、先頭に残った素数の2乗が与えられた数を超えるまで(先頭の素数が目的の数の2乗根を超えるまで)でよい。これ以降にリストに消されずに残っている数はすべて素数である。整数においては が成り立つため、これ以降に存在する合成数はそれ以前の操作によりすべて消されているためである。
フラグ
「旗」という意味の英単語で、ITの分野では、コンピュータプログラムが条件判定などの命令を実行する際に結果を保存しておく領域などのことをこのように呼ぶ。一般の外来語としては「フラッグ」と表記するが、コンピュータ用語としては「フラグ」と詰めて表記・発音する慣習が定着している。
プログラミングの分野でフラグという場合は、何らかの処理を実行した際に、結果を表す短いデータを格納しておく領域を指す。変数やメモリ上の特定の番地、CPU内部のレジスタ(の特定のビット)などが使われる。機械語のプログラムなどがフラグ用に用いる専用のレジスタが用意されていることがあり、「フラグレジスタ」という。
フラグは一般的に1ビットの真偽値(ブール値)や二進数の数値で表現され、処理を実行した結果、条件が満たされた場合には「true」(真)や「1」、満たされない場合には「false」(偽)や「0」などの値を取る。条件が満たされてフラグが真になることを「フラグが立つ」という。多値で複雑な条件を表現できるようにしている場合もある。
処理結果をフラグに格納することで、後続の命令が結果を知ることができ、その後の処理に反映させることができる。条件判定を行う命令と実行の流れを分岐させる命令を別々に記述しなければならないアセンブリ言語および機械語(マシン語)のプログラムで多様される。
高水準プログラミング言語の場合、単純な条件分岐などではフラグは実行コード中で内部的に用いられるだけで開発者が意識することはないが、何らかの状態の変化と、変化を反映した処理の間がプログラム中で遠く離れているような場合などにはフラグによる状態変化の伝達が用いられることがある。
ゲームや物語のフラグ
フラグ自体は様々なプログラムで汎用的に用いられる手法だが、ビデオゲームのプログラムではシナリオの分岐条件やステージのクリア条件などの記録のために用いられるため、これらの内部的な判定条件やその現在の状態のことを指してフラグというようになった。
例えば、アクションゲームでステージクリアのために必要なアイテムを取得したときに、「クリアフラグが立った」と表現することがある。
この意味から派生して、俗に、小説や映画、マンガ、アニメなどのストーリーで、お決まりのパターン通りの展開を予期させる「前振り」となる事象をフラグということがある。
例えば、兵士のキャラクターが「俺、この戦争が終わったら田舎に帰って彼女と結婚するんだ」と発言すると、その後の戦いのシーンで悲運にも死を遂げることが多い。このような、読者・視聴者にその後の展開を予期させるような紋切り型のセリフや表現などをフラグ(この例では「死亡フラグ」)という。
乱数 【ランダム値】 ⭐⭐
サイコロの出目のように規則性がなく予測不能な数値のこと。何度も生成した時に、すでに分かっている値の列から次に現れる値を予測できないような数値の列を乱数列と呼び、その中の個々の値を乱数という。
多くのプログラミング言語には乱数を生成する組み込みの関数やメソッドなどが用意されており、呼び出すたびに規則性のないランダムな数値を返す。多くの言語では0以上1未満の浮動小数点数が得られるようになっており、用途に応じて必要な形式に計算・加工して利用する。
コンピュータはその性質上、ソフトウェアによって完全な乱数を生成することはできないため、統計的に乱数と同じ性質を持つような「擬似乱数」(pseudorandom numbers)を計算によって生成している。
これは計算方法と初期値が分かれば全く同一の数値列を再現できるため、暗号化などの用途では不都合となる場合がある。このため、センサーを内蔵して外界の物理現象を測定して数値として反映させるなどの手法により、擬似的でない真の乱数を生成する半導体チップが利用される場合もある。