高校「情報Ⅰ」単語帳 - 実教出版「最新情報Ⅰ」 - アルゴリズムとプログラミング

プログラム ⭐⭐⭐

予定(表)、計画(表)、課程、式次第などの意味を持つ英単語。ITの分野では、コンピュータに行わせる処理を記述したコンピュータプログラムのことを略して単にプログラムということが多い。

コンピュータプログラム (computer program)

コンピュータが行うべき処理を順序立てて記述したもの。広義の「ソフトウェア」の一部であるが、実用上はプログラムとソフトウェアはほとんど同義のように扱われることが多い。

現代のコンピュータではプログラムは一定の形式に従ってデータとして表現され、記憶装置(メインメモリ)に格納される。実行時にはCPU(中央処理装置)がプログラムに記述された命令を順番に読み出して解釈・実行していく。

プログラムを作成する作業や工程を「プログラミング」(programming)、これを行う人や職種のことを「プログラマ」(programmer)という。人間がプログラムを記述する際には、人間が理解しやすい人工言語である「プログラミング言語」(programming language)を使うことが多い。プログラミング言語で記述されたプログラムを「ソースコード」(source code)という。

ソースコードはコンピュータが解釈・実行することができないため、コンパイラなどの変換ソフトによってコンピュータが解釈・実行できる機械語(マシン語)などで構成された「オブジェクトコード」(object code)に変換されてから実行される。スクリプト言語のように、この変換処理を開発時には行わず、実行時にインタプリタなどのソフトウェアによって動的に行う場合もある。

ソースコード 【ソースプログラム】 ⭐⭐

プログラミング言語などの人間が理解・記述しやすい言語やデータ形式を用いて書き記されたコンピュータプログラムのこと。プログラムに限らず、人工言語や一定の規約・形式に基いて記述された複雑なデータ構造の定義・宣言などのこともソースコードと呼ぶ場合がある。

コンピュータへの指示や一連の処理手順などをプログラミング言語によって文字データの羅列として表記したもので、そのままではコンピュータ(の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のようにインデントによってプログラムの構造を記述する言語もある。

バグ

「虫」という意味の英単語で、コンピュータの分野ではプログラムに含まれる誤り、欠陥を指す。俗に、ソフトウェアが正常に動作しなくなることを「バグる」ということがある。

ソフトウェアの誤作動を引き起こすコンピュータプログラム中の欠陥を指し、人間がプログラムを書き記す際に起きる単純な誤記や勘違いなどによるものから、構想や設計の段階で誤りや矛盾が含まれていたことに起因するものなど、様々な原因によって発生する。プログラム中の誤りを発見し取り除く作業・工程を「デバッグ」(debug:除虫する)という。

バグを含むプログラムを実行することで生じる問題は様々だが、典型的なものとしては、利用者の操作に応答しなくなったり、設計意図と異なる挙動を示したり、誤ったデータを出力したり、記録されたデータを破壊したりといった振る舞いが挙げられる。

ビデオゲームの分野では、キャラクターやフィールドが通常はありえない状態になる現象や、不可能なはずの挙動や展開が可能になるバグが注目されることが多い。製品としては欠陥だが、バグによって可能になる奇妙な挙動や攻略テクニックなどを「裏技」「バグ技」などと呼んで面白がる文化がある。

潜在的なバグ

常に同じ実行箇所に差し掛かると同じ問題を引き起こすバグは発見しやすいが、いつどこで実行しても同じ箇所で必ず不具合を引き起こすとは限らない。特定の入力データや操作、使用環境や設定、あるいはそれらの特定の組み合わせによって発現し、それ以外の状況では誤作動を引き起こさない場合がある。

例えば、1980年代までは日付データの年号部分を西暦の下二桁で記録・管理することは記憶容量の節約や処理速度の向上に寄与するとして推奨されることが多かったが、西暦2000年に到達すると正常に動作しなくなる(西暦2000年問題)。実際、情報システム業界は1990年代末に業務用システムの改修に大きな人手を割くことになった。

バグの発見と修正

コンピュータプログラムの設計・記述の多くは人間が行うため、バグの発生・混入を未然に完全に防ぐ方法はなく、いかに効率よく早期に発見し取り除くかが重要となる。そのためには、ソフトウェア開発の各段階で繰り返し入念にテストを行い、発見された不具合や誤作動についてプログラム上の発生箇所や原因を特定し、対処方法を決定して修正などを行う。

発見されたほとんどのバグは正しい動作を行うプログラムコードに差し替えられる。発売・公開前のプログラムは修正して実行ファイルなどを作りなおすが、利用者の手元に提供した後にバグが発見されることもある。そのような場合には、開発元が「パッチ」「バグフィックス」などと呼ばれる修正プログラムをインターネットなどを通じて配布し、利用者側のソフトウェアを更新する。

オペレーティングシステム(OS)やライブラリ、ミドルウェアなど基盤的なソフトウェアの場合には、修正によってプログラムの振る舞いが変わり、従前の振る舞いを前提に動作していた他のプログラムなどに思わぬ影響を及ぼすことがある。深刻な影響が想定される場合はバグをあえて放置し、別の箇所や方法で悪影響を抑えるというアプローチが取られる場合もある。

歴史

古くは19世紀の記録に機械の設計・製造上の誤りや不良が “bug” と呼ばれていた事例がいくつか知られており、初出がいつに遡るのかは判然としない。現代のコンピュータのソフトウェアにおける用例に近い初期のエピソードとして最も有名なものは、1947年にグレース・ホッパー(Grace Hopper)氏が米ハーバード大学で遭遇した事例である。

初期の電気機械式のコンピュータ「Harvard Mark II」の不具合を調査する過程で、あるスタッフがリレー(スイッチ)に蛾が挟まって接触不良を起こしているのを発見した。彼女は日誌に蛾をテープで留め、“First actual case of bug being found”(実際にバグが見つかった最初の事例) と書き残した。

構文エラー 【シンタックスエラー】

プログラミング言語などの人工言語で記述したコードが、定められた構文規則(シンタックス)を満たしていないときに発生するエラー。コードを正しく解釈できないため処理は打ち切られる。

人間が読み書きするコンピュータプログラムであるソースコードはプログラミング言語などの仕様に従って記述される必要がある。言語処理系がこれを解釈してコンピュータが直に理解可能な形式(機械語のプログラムなど)に変換する際、プログラムが構文規則に照らして誤っている場合に文法エラーが生じる。

文法エラーが発生するとそれ以上変換や実行などを続行することはできないため、処理系がエラーメッセージを表示するなどして停止する。誤った記述を修正すれば正しく解釈・変換できるようになるが、あくまでコードが言語仕様に形式的に適合しているか否かの問題であり、エラーが解消されたからといって実行結果が開発者の意図した通りになっているとは限らない。

開発時にコンパイラなどでソースコードを実行形式(ネイティブコードなど)に変換する言語や処理系では文法エラーはコンパイル時エラーだが、実行時にインタプリタなどがソースコードを解釈しながら実行する言語や処理系では文法エラーは実行時エラー(ランタイムエラー)となる。

フローチャート 【流れ図】 ⭐⭐⭐

工程や手順の流れを図示する手法の一つで、個々の段階を箱で表し、それらを順序や論理の推移に従って矢印や線分で結んだもの。

ITの分野では、コンピュータプログラムの設計やアルゴリズム(計算手順)の理解などのために、内部で行われる処理や演算の詳細な流れをフローチャートに表すことが多い。プログラムに限らず、業務手順など様々な過程や手順の図示に応用できる。

一つのフローチャートには開始と終了があり、その間に一つ以上の工程が含まれる。流れは分岐や繰り返しによって複数に枝分かれしたり戻ったりすることがあるが、途中どのような経路を通っても必ず一つの開始から始まって一つの終了で終わる。

フローチャートで用いる部品の種類や図記号の形状はJIS X 0121で規格化されており、一般的にはこれを用いることが多い。主な部品として、開始や終了を表す「端子」(円・楕円・角丸長方形)、「処理」(長方形)、プログラムにおけるサブルーチンや関数などの「定義済み処理」(左右が二重線の長方形)、「入出力」(平行四辺形)、条件分岐などの「判断」(菱形)、繰り返しの範囲を示す「ループ端」(開始は上側、終了は下側の角が欠けた長方形)、他の図との出入り口を示す「結合子」(小さな丸)、処理の流れを示す「線」(右や下へは線分・左や上には矢印)などがある。

状態遷移図 ⭐⭐

対象がどのような状態を持ち、どのような条件や出来事(イベント)によりそれらの間を遷移するかを一覧に表した図。

様々な表現形式があるが、一般的な手法では、対象が取りうる状態を円や矩形などで列挙し、どこからどこへ遷移が起きうるかを矢印によって示す。各矢印の脇に、その遷移が起きるための条件やきっかけとなる出来事などを記述する。自らに遷移する場合は自分を指し示す輪っか状の矢印を書き入れる。

対象に開始や終了がある場合は、特殊な記号で示される場合がある。UMLでは開始を塗りつぶした丸印で、終了を内側を塗りつぶした二重丸で記載するよう定められている。

状態遷移表

状態遷移図の各状態を一行として表の形で書き表したものを状態遷移表という。

一般的な形式では、各行が対象の状態を、各列がイベントを表し、ある状態のときにあるイベントが起きたときにどの状態に遷移するかを書き入れていく。

また、縦軸・横軸ともに状態を並べ、各状態の交差する項目にそのような遷移が起こるイベントを書き入れていく様式もある。

ソフトウェア開発の分野ではテストを行う際にテストケースを漏れなく網羅するために状態遷移表が作成される場合がある。

ステートマシン図 (state machine diagram)

ソフトウェアの設計などに用いられるUML(Unified Modeling Language)では、状態遷移図に相当する図をステートマシン図(state machine diagram)として定義している。

あるオブジェクトの振る舞いを漏れなく記述するために用いられるもので、開始状態を塗りつぶした丸印(●)、終了を内側を塗りつぶした二重丸で表し、途中の状態を角丸の矩形を並べて図示していく。

状態間は遷移する方向に矢印で繋ぎ、脇に遷移の説明を添える。遷移したときに実行する動作がある場合は矩形を横に区切って下半分に動作の内容を記述する。

アクティビティ図 【活動図】 ⭐⭐⭐

ソフトウェアの設計などに用いられるUML(Unified Modeling Language)で規定された図(ダイアグラム)の一つで、業務や処理の実行手順を表したもの。

アクティビティ図ではそれ以上分割できない最小の動作単位を「アクション」(action)と呼び、角丸四角形で図示する。アクションを組み合わせたひとまとまりの動作を「アクティビティ」(activity)と呼ぶ。

活動の開始ノード(黒丸で示される)から終了ノード(丸で囲った黒丸で示される)までの間にアクションやアクティビティを配置し、それぞれの依存関係に従って矢印で結んでいく。

次のアクションへ情報などが受け渡される場合には、中間に四角形で示す。矢印で結ばれた手順の流れを「フロー」(flow)という。異常終了などでフローが途中で終了する場合には、終了地点に丸囲みの×印を記す。

アクティビティ図全体を縦または横(あるいはその両方)に分割して実行主体や段階を示すことができる。アクションやアクティビティが分割されたどの領域に存在するかによって、どの主体による動作かを示したり、どのような段階に行われる動作かを示すことができる。

フローの分岐・合流

特定の条件に従ってフローが分岐する場合には、菱形の「デシジョン」(decision:判断)ノードを置いて2方向に矢印を記し、それぞれの脇に条件を記述する。フローが合流する地点には同じ菱形の「マージ」(merge:合流)ノードを置く。

ある時点から複数のフローを並列に実行する場合には、その開始地点に太い直線で示される「フォーク」(fork:分岐)ノードを置き、複数のフローを出発させる。これらの同期を取って一つのフローに戻したい場合には、同じく太い直線の「ジョイン」(join:結合)ノードを置き、フローを集合させる。

高水準言語 【高級言語】

プログラミング言語の分類の一つで、抽象的な語彙や記法、構文などを用いて処理を記述することができる言語の総称。

「高水準」「高級」とは優れた言語という意味ではなく、機種や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#など、よく知られる関数型言語のほとんどはこちらに分類される。

関数型言語と関数型プログラミング

関数型言語の研究や普及が進むに連れて、手続き型など他の種類のプログラミング言語にもその特徴が取り込まれるようになってきており、無名関数や高階関数、型推論などは多くの言語に実装されている。

「関数型プログラミング」とは関数型言語によるプログラミングだけでなく、手続き型言語などを用いて関数を組みわせてプログラムを構成する手法が含まれる。逆に、形式的には関数型言語を使っていても、代入など手続き型の特徴ばかりを用いてプログラムを構成していれば、それはもはや関数型ではなく手続き型プログラミングであると言える。

コンパイラ型言語 【コンパイラ方式】

かつて用いられた高水準プログラミング言語の分類の一つで、公式あるいは主要な処理系がコンパイラであるような言語のこと。

コンパイラ(compiler)はプログラミング言語で記述されたソースコードを解釈し、実行可能な機械語(マシン語)などのコードに一括して変換するソフトウェアで、変換後のコードを元に実行可能ファイルを作成して実行される。

記述したコードを実行に移すまでに手間や準備時間が必要だが、機械語への変換と実行が分離されるため、プログラムを少ない消費メモリで高速に実行でき、実行時にソースコードが不要(利用者へソースコードを提供しなくてよい)という特徴がある。

コンパイラ型言語は言語の開発元が提供する公式の処理系や、広く普及している主要な処理系がコンパイラであるような言語を指し、機械語コードへ変換しながら同時に実行する「インタプリタ型言語」(インタプリタ言語)と対比される。

このような分類は現代よりもプログラミング言語とその処理系が密接に関連付けられていた1990年代以前によく用いられたが、インタプリタとコンパイラのどちらを用いるかは言語そのものの特性ではなく、実際、今日では一つの言語に両者が標準的に提供されることも少なくないため、このような分類を用いることはほとんどなくなった。

インタプリタ型言語 【インタプリタ方式】

かつて用いられた高水準プログラミング言語の分類の一つで、公式あるいは主要な処理系がインタプリタであるような言語のこと。

インタプリタ(interpreter)はプログラミング言語で記述されたソースコードを解釈し、実行可能な機械語(マシン語)のコードに変換しながら同時に実行するソフトウェアで、変換処理の分だけ消費メモリ容量や実行速度は犠牲になるが、ソースコードを与えるだけで即座に実行できるという特徴がある。

インタプリタ型言語は言語の開発元が提供する公式の処理系や、広く普及している主要な処理系がインタプリタであるような言語を指し、機械語コードへの変換を一括して行い、実行可能ファイルを生成してから実行する「コンパイラ型言語」(コンパイラ言語)と対比される。現代では、いわゆるスクリプト言語が該当する。

このような分類は現代よりもプログラミング言語とその処理系が密接に関連付けられていた1990年代以前によく用いられたが、インタプリタとコンパイラのどちらを用いるかは言語そのものの特性ではなく、実際、今日では一つの言語に両者が標準的に提供されることも少なくないため、このような分類を用いることはほとんどなくなった。

マクロ 【マクロ言語】

関連する複数の操作や手順、命令などを一つにまとめ、必要に応じて呼び出すことができるようにする機能のこと。アプリケーションソフトの定型的な操作の自動化などに用いられる。

ソフトウェア操作のマクロ

アプリケーションソフトの操作を自動化する機能の一つにマクロ言語がある。利用者が複数の操作手順を一連の手続きとして記録したもので、簡単な操作で繰り返し実行することができる。

利用者はマクロ言語登録開始に操作の後、操作画面上で登録したい一連の操作を行い、記録終了の操作を行う。この間の操作はデータとして記録され、録音した音声を再生するように簡単な操作で何度も繰り返し呼び出すことができる。

業務上何度も繰り返し行わなければならない定型的な作業を自動化することができ、文書内の複数の個所や複数の文書に同じ操作を行わなければならない場合などに利用される。

Microsoft Excelのマクロ機能など、表計算ソフトでよく利用される機能で、記録した操作をスクリプト言語などで表し、後から編集できる機能を持ったソフトもある。キー操作を記録して再生できるようする機能は「キーボードマクロ」と呼ばれる。

プログラミングのマクロ

プログラミングの分野では、ソースコード中に繰り返し登場する特定の記述を、別の(短い)記述に置き換えることができる機能をマクロ言語という。

複数の命令をまとめて一つの命令のように記述したり、複数の箇所で参照される定数の値を後からまとめて変更できるようシンボル名で記述するのに使われる。

関数のようなプログラミング言語の持つ仕様や機能ではなく、アセンブラやコンパイラなどの機能として提供されるもので、コンパイルなどの前処理としてソースコードを単純に文字列置換することにより実現される。C言語などではプリプロセッサと呼ばれる専用のプログラムで処理される。

スクリプト言語 【軽量言語】

プログラミング言語の一種で、オペレーティングシステム(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ブラウザに対するマクロ言語のような用途として発明されながら、拡張や移植を重ねて汎用的な言語として様々な機能や実行環境を獲得した例もある。

コンパイラ

人間に分かりやすく複雑な機能や構文を持つ高水準プログラミング言語(高級言語)で書かれたコンピュータプログラムを、コンピュータが解釈・実行できる形式に一括して変換するソフトウェア。“compiler” の原義は「翻訳者」。

コンパイラは、プログラミング言語で書かれた「ソースコード」(source code)を読み込んで解析し、コンピュータが直に実行可能な機械語や、それに相当する中間言語などで記述された「オブジェクトコード」(object code)に変換する。この変換工程のことを「コンパイル」(comple)という。

コンパイラが生成したオブジェクトコードはそのままでは実行可能でない場合が多く、リンカなど別のソフトウェアを用いて、起動に必要なコードを追加したり、必要なライブラリなどを結合(リンク)したりして実行可能形式のプログラムとする。コンパイルを含む一連の工程を「ビルド」(build)という。

一方、ソースコードを読み込みながら、逐次的に実行可能コードを生成して実行するソフトウェアを「インタプリタ」(interpreter:「通訳者」の意)という。コンパイルやリンクなどのビルド工程を経ずにソースコードをいきなり実行できるため、スクリプト言語の実行環境としてよく用いられる。

様々なコンパイラ

Javaや.NET言語など、CPUやオペレーティングシステム(OS)の種類に依存しない中間形式でプログラムを配布する言語では、実行時に実行環境固有のコード形式(ネイティブコード)に変換するコンパイラを「JITコンパイラ」(Just-In-Time compiler)あるいは「実行時コンパイラ」という。この方式では、開発時にソースコードから中間形式へ、実行時に中間形式からネイティブコードへ、2段階のコンパイルを行う。

デジタル家電などの組み込みソフトウェアの開発など、開発環境と実行環境が異なる場合、開発環境上で別の環境向けのオブジェクトコードを生成する「クロスコンパイラ」(cross compiler)という。実行プログラムは対象環境に送ってテストや実行を行う。

コンパイラとは逆に、コンパイル済みのオブジェクトコードを解析して元のソースコードに逆変換するソフトウェアを「デコンパイラ」(decompiler)あるいは「逆コンパイラ」という。高水準言語ではソースコードとオブジェクトコードの各要素は一対一に対応しないため、完全な復元は難しい。特に、変数名などのシンボルはコンパイル時に失われるため、オブジェクトコードから取り出すことはできない。

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の権利について従来の状況が変化していく可能性がある。

変数 ⭐⭐⭐

コンピュータプログラムのソースコードなどで、データを一時的に記憶しておくための領域に固有の名前を付けたもの。プログラム上で値を代入したり参照することができる。

変数につけた名前を「変数名」と呼び、記憶されているデータをその変数の値という。データの入れ物のような存在で、プログラム中で複数のデータを扱いたいときや、同じデータを何度も参照したり計算によって変化させたい場合に利用する。

変数をプログラム中で利用するには、これからどんな変数を利用するかを宣言(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」のように変数名自体の先頭を大文字にする方式は「パスカルケース」とも呼ばれる。

ローカル変数 【局所変数】

コンピュータプログラム中のあるコードブロック(関数やメソッドなど)の内部で宣言され、その範囲内でのみ有効な変数。

プログラミング言語の多くは、サブルーチンや関数、メソッドなどの形で複数のコードを束ねたまとまり(ブロック)を作ることができるが、そのようなブロックの内部でのみ通用する変数のことをローカル変数という。

通常、あるブロック内で変数を宣言すると、自動的にそのブロックを有効範囲(スコープ)とするローカル変数となり、ブロック内のコードからのみ参照や変更ができるようになる。関数内で別の関数を定義するといった入れ子構造の記述が可能な場合、内側のブロックから外側のブロックのローカル変数にアクセスできるかどうかはブロックの種類や言語仕様により異なる。

一般的にローカル変数の寿命はブロックの開始(あるいは変数宣言)から終了までで、関数などの実行が終了して呼び出し元に制御が移ると関数内のローカル変数の内容は破棄されるが、言語によっては内容を維持するよう指定する事ができる場合もある(静的ローカル変数)。

どのような種類のブロックでローカル変数を使用できるかは言語によって異なるが、関数やメソッドなどをスコープとするローカル変数はほとんどの言語に存在する。繰り返しや条件分岐などの制御文で指定される範囲をスコープとするローカル変数を宣言できる言語も存在する。

一方、同じプログラムのどこからでも参照や書換が可能な変数を宣言できる言語もあり、そのような変数をグローバル変数(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には存在しないため、混乱を招かないよう予約してあるという例もある。

演算子 【オペレータ】 ⭐⭐

数学やプログラミングなどで式を記述する際に用いられる、演算内容を表す記号などのこと。演算の対象となる値や変数などのことは「被演算子」(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)などがある。

多くの言語では演算子は言語仕様で定義されており開発者が任意に追加、削除、変更することはできないが、言語によってはコード中で独自の演算子を定義して利用することができたり、既存の演算子に別の演算内容を割り当てる「多重定義」(オーバーロード)ができる場合もある。

比較演算子 【関係演算子】

プログラミング言語などで用いられる演算子のうち、二つの式や値の比較を行い、結果を真偽値(trueまたはfalse)で返すもの。一致・不一致や大小の比較などいくつかの種類がある。

用意されている比較の種類や記法は言語によって様々だが、数の一致や大小は数学の表記に倣って「=」(等しい)「>」(より大きい)「<」(より小さい)の組み合わせで記述する場合が多い。

その際、「~以上」(≧)は「>=」または「=>」、「~以下」(≦)は「<=」または「=<」とする。不一致(≠)は「!=」や「<>」などで表されることが多い。

「=」は代入の意味で用いられることもあるため、混同や誤用しないよう一致の比較演算子を「==」などとする言語も多い。一致・不一致の演算子は数だけでなく文字や文字列、真偽値など様々なデータ型に用いられる。

異なるデータ型の比較

「1==“1”」のようなデータ型の異なる値同士の比較を許容する(自動的に一方の型に変換して比較する)言語と、これを禁じてエラーとして処理する言語がある。前者の場合、例えば「==」を実質的な内容の一致、「===」を内容とデータ型両方の一致(厳密等価演算子あるいは同値演算子と呼ばれる)として使い分ける言語もある。

複合的なデータ構造の比較

オブジェクト指向言語におけるインスタンスや、配列などの複合的なデータ構造などを比較できる言語もある。

その際、一致・不一致は「両方ともメモリ上の同一の実体を指し示している」(参照が一致している)ことを意味する場合と、「含まれるデータの型や値がすべて同じである」(内容が一致している)ことを意味する場合がある。どちらか一方の比較のみ可能な場合と、それぞれを異なる記法で書き分けるようになっている場合がある。

論理積 【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」にセットしたビット列を用いて、入力値の特定のビットのみを反転させるという操作がよく用いられる。

順次構造 ⭐⭐⭐

コンピュータプログラムの命令実行の流れの一つで、プログラムに記述された順番通りに命令を実行していくもの。

コンピュータのCPUがプログラムを実行する際、特に指定がなければプログラムを先頭から読み込んで命令を並んでいる順に従って一つずつ実行していく。この最も基本的な命令実行の制御構造を、(他の構造と対比するため便宜的に)順次構造と呼ぶ。

一方、命令の中には命令実行の流れを変更するものもある。これを用いて、条件に従って別の実行位置に流れを分岐させる制御構造を「選択構造」あるいは「分岐構造」、条件が満たされる間だけ同じ個所を繰り返し実行する制御構造を「反復構造」あるいは「繰り返し構造」という。

選択構造 【分岐構造】 ⭐⭐⭐

コンピュータプログラムの命令実行の流れの一つで、実行時に評価する条件によって、次の命令を実行するか、指定されたメモリ上の位置に移行するか分岐するもの。

コンピュータのCPUがプログラムを実行する際、特に指定がなければ命令を先頭から順に実行するが、分岐命令が存在する場合、特定の条件が満たされたらメモリの指定番地に実行位置を変更(ジャンプ)し、以降はそこから順に命令を実行していく。

このような実行制御を「条件分岐」と呼び、プログラムに複雑な処理をさせたい場合は必須の機能となる。一方、条件が満たされる間だけ同じ個所を繰り返し実行する制御構造もあり、「反復構造」あるいは「繰り返し構造」という。

反復構造 【繰り返し構造】 ⭐⭐⭐

コンピュータプログラムの命令実行の流れの一つで、指定の条件が満たされている間、特定の個所を何度も繰り返し実行するもの。

コンピュータのCPUがプログラムを実行する際、特に指定がなければ命令を先頭から順に実行するが、反復構造になっている場合、指定の条件が満たされている間、指定範囲の末尾の命令を実行したら範囲の先頭に戻り、その範囲を繰り返し実行する。

同じ処理を様々な対象に次々に適用したい場合などに用いられ、プログラムに複雑な処理をさせたい場合には必須の機能となる。一方、特定の条件が満たされたらメモリの指定番地に実行位置を変更(ジャンプ)する制御構造もあり、「選択構造」あるいは「分岐構造」という。

ネスト 【入れ子】

あるものの中に、それと同じ形や種類の(一回り小さい)ものが入っている状態や構造のこと。IT分野では、コンピュータプログラムやデータ構造において、ある構造の内部に同じ構造が含まれている状態のことを指す。

よく知られるのはプログラムの制御構造のネストで、if( 条件A ){ ... if( 条件B ){ ... } ... } といったように、条件分岐やループの内部に、別の条件分岐やループなどが含まれた制御構造を指す。複雑な条件による分岐や多重ループを記述するための基本的なテクニックとして多くのプログラミング言語で利用できる。

for文の中にfor文を記述するなど、同じ構文を入れ子状に繰り返すことを指す場合が多いが、while文の中にif文など、異なる制御構文を内部に記述することも含む場合がある。内側の構文の内部にさらに構文を重ねて、マトリョーシカのように何重も入れ子にすることができ、階層の多さを「ネストの深さ」と表現することがある。

サブルーチンなどのネスト

プログラミング言語の中には、サブルーチンやプロシージャ、関数、クラスなどのコードのまとまりをネストさせ、内部に同種のまとまりを定義することができるものもある。例えば、関数の内部に定義された別の関数を「関数内関数」「ローカル関数」などと呼び、クラスの内部に定義された別のクラスを「クラス内クラス」「インナークラス」「内部クラス」などという。

データ構造のネスト

あるデータ構造の要素として、そのデータ構造自身を埋め込むことができる場合があり、データ構造のネストを形成する。例えば、配列を構成する個々の要素が配列になっている多次元配列は配列のネストである。

配列の配列など、内部が再帰的に同じ構造になっているものを指すことが多いが、連想配列の要素が配列になっているものなど、制御構文の場合と同じように異なる構造が入れ子状になっている場合も含むことがある。

サブルーチン 【サブルーティン】

コンピュータプログラムの中で特定の機能や処理をひとまとまりの集合として定義し、他の箇所から呼び出して実行できるようにしたもの。単に「ルーチン」とも呼ばれる。

プログラム中の様々な状況や箇所で繰り返し必要となるような処理をサブルーチンとして名前をつけて一つの塊として定義することで、その処理を何度も繰り返し記述・複製する必要がなくなり、コード量の削減や開発効率の向上、記述ミスなどによる誤り(バグ)の減少などが期待できる。

サブルーチン内部の処理に反映させるため、呼び出し側から値を指定できるようになっている場合が多く、この値を「引数」(ひきすう/argument)という。また、処理結果として呼び出し元に値を返すことができる場合があり、この値は「返り値」あるいは「戻り値」という。返り値を持つサブルーチンは「関数」(function)と呼ぶのが一般的である。

かつてはプログラムが起動したとき最初に実行される主系統のコード集合を「メインルーチン」(main routine)、そこから呼び出される形で実行される副系統のコード群をサブルーチンと呼んで区別していたが、現在ではそのような構造に当てはまらない例も増えており、サブルーチンのことを単にルーチンと呼ぶことも多い。

サブルーチンに相当するコード集合は、プログラミング言語によっては「プロシージャ」(procedure)のように異なる名称で呼ばれることもある。オブジェクト指向プログラミングでは一般的に「メソッド」(method)という。返り値を持つか否かで名称が異なる言語(Pascalのプロシージャと関数など)や、C言語のようにすべてを関数と呼ぶ場合もある。

プロシージャ

「手続き」という意味の英単語で、コンピュータプログラム内で複数の命令や処理などを一つにまとめ、外部から呼び出し可能にしたものをこのように呼ぶことがある。

全体として何らかの特定の処理や機能を実現するために作成されるもので、繰り返し必要になるコードをまとめておくことで何度も似たようなコードを記述しなくて済むようになり、プログラムの保守性や再利用性も高まる。

このようなコードのかたまりを作成する仕組みを何と呼ぶかはプログラミング言語によって異なり、ルーチン(routine)、関数(function/ファンクション)、メソッド(method)なども似たような仕組みを指す(言語により意味や仕様はそれぞれ異なる)。PascalやVisual Basicのように呼び出し元に値を返さないものをプロシージャ、返すものを関数と呼んで区別する場合もある。

関数 【ファンクション】 ⭐⭐⭐

コンピュータプログラム上で定義されるサブルーチンの一種で、数学の関数のように与えられた値(引数)を元に何らかの計算や処理を行い、結果を呼び出し元に返すもののこと。

プログラム上で関連する一連の命令群を一つのかたまりとしてまとめ、外部から呼び出せるようにしたサブルーチンやプロシージャ(手続き)の一種である。呼び出し時に引数(ひきすう/argument)と呼ばれる値を指定することができ、この値をもとに内部で処理を行って、結果を返り値(かえりち/return value)あるいは戻り値(もどりち)として呼び出し元に通知する。

プログラミング言語によって、返り値を持つものを関数(ファンクション)、処理を行うだけのものをサブルーチンやプロシージャとして区別する場合もある(Pascalなど)が、C言語やJavaScriptのようにすべてが関数で引数や返り値が省略可能になっている言語もある。

多くのプログラミング言語は開発者が自由に関数を定義してプログラム中で呼び出せる構文や記法を定めているほか、算術関数や文字列処理などよく使われる基本的な関数言語仕様や標準ライブラリなどの中であらかじめ実装済みとなっている(組み込み関数)。

関数といっても数学のように計算を行うものには限られず、「利用者に入力を促して入力値を返す」関数といったものもあり得る。途中で画面に何かを表示するなど、引数や返り値と直接関係ない処理を行ってもよい。

プログラムは内部に変数の値など実行状態を持つため、これを反映して同じ引数から異なる返り値が得られる場合もある。また、関数が行う処理によって状態が変化することもあり、これを関数の持つ「副作用」という。多くの算術関数のように副作用のない関数もある。

引数 ⭐⭐

プログラム中で関数やメソッド、サブルーチンなどを呼び出すときに渡す値のこと。渡された側はその値に従って処理を行い、結果を返す。オペレーティングシステム(OS)の操作などで利用者がコマンドを実行する際に指定するパラメータ(コマンドライン引数)などを指すこともある。

仮引数と実引数

関数などを定義する際に外部から受け取った値を表す変数などを「仮引数かりひきすう」(formal argument)、関数を呼び出す側が実際に指定した値を「実引数じつひきすう」(actual argument)という。

例えば、2つの数を受け取って和を返す関数 function sum(a, b){ return a + b; } があるとき、aやbを仮引数という。一方、この関数を呼び出すコード s=sum(1,2); における1や2が実引数となる。1はaに、2はbに代入されて関数内の処理が実行される。

値渡しと参照渡し

プログラミング言語の引数には「値渡しあたいわたし」(call by value)と「参照渡しさんしょうわたし」(call by reference)があり、どちらもサポートしている言語と片方のみサポートしている言語がある。

値渡しは変数の内容をコピーして渡す方法で、渡された関数などが変数の内容を変更しても、元の変数には影響がない。参照渡しは変数の所在を表す情報を渡す方法で、渡した側と渡された側が同じ変数を共有するため、呼び出された側で変更を加えると呼び出し側にも変更が反映される。

戻り値 【返り値】 ⭐⭐

プログラム中で呼び出された関数やメソッド、サブルーチンなどが処理を終了する際に、呼び出し元に対して渡す値。計算結果の報告などのために用いられる。

関数などが処理を行った結果として呼び出し元に報告される値のこと。反対に、呼び出し元から関数などに対してパラメータとして渡す値のことは「引数」(ひきすう、argument)という。

戻り値は計算結果の数値や処理結果のデータなどが代表的だが、処理が正しく終了したかどうかを表す真偽値やコード番号、メッセージなどを返す場合もある。多くの言語では「return x+y;」(変数xとyの和を返却する)のようにreturn文(リターン文)と呼ばれる記法で返す値を指定する。

ほとんどのプログラミング言語では戻り値は一つしか返すことができないが、変数への参照やメモリアドレス(ポインタ)を返したり、配列などの複合的なデータ構造、データ型に値を格納して返すことで、複数のデータの集合を返すことができるようになっていることが多い。C言語のvoid型関数のように、明示的に何も返さないよう指定できる言語もある。

関数などを定義する際に戻り値のデータ型もあらかじめ宣言するようになっていることが多く、呼び出し側で受け取る変数の型も揃える必要がある。言語によっては、同じ名前だが引数と戻り値のデータ型が異なる複数の関数やメソッドなどを同時に定義し、引数の型によって自動的に使い分ける機能(オーバーロード)が利用できる場合もある。

添字 【添え字】 ⭐⭐

文字の周囲に小さく添えられた文字。ITの分野では、プログラミングにおいて配列などに格納された個々の要素を指し示す値などをこのように呼ぶ。

配列変数は一つの変数に複数の値を並べて格納できるデータ構造で、多くのプログラミング言語に標準で用意されている。配列内の各要素を識別・指定するために通し番号が与えられており、これをコード上で変数名の隣などに記述したものを添字という。

例えば、C言語やその記法を受け継ぐ多くの言語では角括弧で囲んだ数字が配列の添字を表し、“a[0]” は配列aの先頭の要素を、“a[9]” は先頭から10番目の要素をそれぞれ指し示す。

スクリプト言語などでは配列の添字として0から始まる整数の通し番号以外に、任意のプリミティブ型(実数や文字列など)の値を指定できるデータ構造が用意されていることがあり、言語によって連想配列、ハッシュ、マップ、辞書(ディクショナリ)など様々な名称で呼ばれる。

IT以外の分野では、論文などの文章中で参照すべき注釈の位置を記した番号や記号、数学のべき乗の指数や対数の底、化学式の原子の数などのように、文字の斜め上や下などに小さく添えられた数字や文字、記号、数式などが添字の一種である。

リスト ⭐⭐

一覧(表)、目録、羅列、一覧に載せる、一覧にする、などの意味を持つ英単語。一般的の外来語としては同じ種類の情報を羅列した一覧のことを指すことが多く、ITの分野でもこの用法が多い。

プログラミングの分野では、ソースコードのことを「プログラムリスト」「ソースリスト」などと呼び、これを略してリストということがある。

データ構造のリスト

基本的なデータ構造の一つで、複数のデータを順序を付けて格納することができる複合データ型(コンテナ/コレクション)をリストという。

中でも、各データが次のデータの所在を表す参照情報(リンク/ポインタ)を持っているものを「連結リスト」(linked list:リンクリスト/リンクトリスト)と呼び、これを略してリストという場合も多い。リストは他に動的配列などを用いても実装することができる。

連結リストの各要素はデータの他に自分の隣の要素を指し示す所在情報を持っている。これを辿ることで、各要素に順番にアクセスすることができる。各要素が自分の次(後)の要素への参照のみを持つ構造を「片方向リスト」「単方向リスト」と呼び、これに加えて自分の前の要素への参照をもつものを「双方向リスト」という。

また、先頭から末尾へ直線上に要素が連結されているものを「線形リスト」、先頭も末尾もなく要素が円環状に連結されているものを「循環リスト」という。

プロパティ 【属性】

財産、資産、物件、所有物、特性、属性、性質、効能などの意味を持つ英単語。ITの分野では、ソフトウェアが取り扱う対象(オブジェクト)の持つ設定や状態、属性などの情報をプロパティということが多い。一般の外来語としてはあまり定着しておらず、不動産や資産といった意味で企業名の一部などに用いられることがある。

様々な分野や場面で用いられる一般的な用語で、それぞれの対象が持つ固有の属性値やその集合体のことを指す。例えば、「ファイルのプロパティ」と言った場合には、ファイル名やファイルの種類、ストレージ上での所在、アクセス権の設定、作成日時、最終更新日時、データサイズ、読み取り属性などが含まれる。

Windowsなどでは、対象のプロパティの表示や変更を行う設定画面や設定ソフトなどのことを「○○のプロパティ」のように表示するため、文脈によっては「プロパティを開く」といったようにこの設定画面のことを指してプロパティという場合もある。

オブジェクト指向プログラミングにおけるプロパティ

オブジェクト指向プログラミングでは、オブジェクトのフィールド(メンバ変数)を外部から直に操作するように記述できるが、実際には内部的にメソッド呼び出しを利用するよう自動的に変換してくれる機能をプロパティということがある。

通常、フィールドへ外部からアクセスするには「アクセサメソッド」(setterメソッド/getterメソッド)を定義する必要があるが、プロパティ機能のある言語ではこれを簡易化し、少ないコード量で安全にフィールドへアクセスできるようにしてくれる。

例えば、objオブジェクトのPropフィールドを外部から参照するには、クラス内でgetPropメソッドを定義し、外部から x=obj.getProp() のように記述するのが一般的だが、プロパティとして宣言することにより x=obj.Prop のように記述するだけで内部的にアクセサメソッドを呼び出して値を取り出してくれる。

アルゴリズム ⭐⭐⭐

ある特定の問題を解く手順を、単純な計算や操作の組み合わせとして明確に定義したもの。数学の解法や計算手順なども含まれるが、ITの分野ではコンピュータにプログラムの形で与えて実行させることができるよう定式化された、処理手順の集合のことを指すことが多い。

曖昧さのない単純で明確な手順の組み合わせとして記述された一連の手続きで、必ず有限回の操作で終了し、解を求めるか、解が得られないことが示される。コンピュータで実行する場合は、基礎的な演算、値の比較、条件分岐、手順の繰り返しなどを指示する命令を組み合わせたプログラムとして実装される。

数値などの列を大きい順または小さい順に並べ替える「整列アルゴリズム」、たくさんのデータの中から目的のものを探し出す「探索アルゴリズム」、データが表す情報を損なわずにより短いデータに変換する「圧縮アルゴリズム」といった基本的なものから、画像の中に含まれる人間の顔を検出する、といった複雑なものまで様々な種類のアルゴリズムがある。

同じ問題を解くアルゴリズムが複数存在することもあり、必要な計算回数や記憶領域の大きさ、手順のシンプルさ、解の精度などがそれぞれに異なり、目的に応じて使い分けられる。例えば、ある同じ問題に対して、原理が単純で簡単にプログラムを記述できるが性能は低いアルゴリズム、計算手順が少なく高速に実行できるが膨大な記憶領域を必要とするアルゴリズム、厳密な解を求めるものより何桁も高速に近似解を求めることができるアルゴリズムなどがある。

探索

未知の物事を探し求めること。情報科学では、データ集合などの中から指定の条件に合致する要素を見つけ出す操作を指すことが多い。

データの探索

何らかのデータ形式やデータ構造として集められたデータの集合に対して、一定の手順に基づいて指定の条件を満たすデータを探し出し、一致したデータやその位置を明らかにする(あるいは対象の中には存在しないことを確定させる)操作のことを「探索」(search)という。

探索アルゴリズム

コンピュータなどで実行できるよう定式化された探索手順のことを「探索アルゴリズム」(search algorithm)という。例えば、最も単純な方法として、一列に並べたデータ列に対して端から順に指定の条件に一致するか照合する方法がある。これを「線形探索」(linear search)という。

また、順位や大小が比較できるデータ群であれば、大きい順または小さい順に整列(並べ替え)して、目的のデータと半分の位置にあるデータを比較すれば、含まれる方の半分に絞り込むことができる。残ったデータ群の半分の位置と比較すれば、もう半分に絞り込める。これを繰り返して残りが一つになれば探索完了となる。この方法は「二分探索」(binary search)と呼ばれる。

線形探索では一回の比較で一つしか候補が減らないため、平均してデータの個数に比例した回数の比較が必要となる(これを O(n) と表記する)が、二分探索ならば一回の比較で候補を半分に減らせるため、平均してデータの個数の2を底とした対数で済む(これを O(logn) と表記する)。

このように、探索する対象の特性に適したアルゴリズムを選択することで効率的に探索を行うことができる。文字列内の特定のパターンを探索するためのアルゴリズムや、木構造やグラフなどのデータ構造に格納された要素を探索するためのアルゴリズムなどがよく知られている。

検索との違い

ITの分野では「検索エンジン」「全文検索」のようにデータ群から条件に一致するものを探し出す操作を「検索」と呼ぶこともある。いずれも英語では “search” であり、意味や用法に明確な違いはないが、慣例として情報科学などの学問分野では「探索」の語が、探索法を応用した具体的なシステムやサービスなどでは「検索」の語が好まれる。

線形探索 【リニアサーチ】 ⭐⭐

データ探索アルゴリズムの一つで、配列などに格納されたデータ列の先頭から末尾まで順番に、探しているデータと一致するか比較していく手法。

最も単純なアルゴリズムで、配列などに格納されたデータ列の中から、まず先頭の要素を探しているデータと比較する。一致しなければ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)という。組み込みシステムなど利用できるメモリ領域が限られる場合には、高速性よりも内部ソートであることが重視されることもある。

バブルソート 【単純交換法】 ⭐⭐

与えられたデータ列を大小などの順序通りになるよう並べ替えるソート(整列)アルゴリズムの最も基本的な手法の一つで、端から順番に隣接する要素同士を比較・交換していくもの。

すべての要素について隣接する要素と大きさを比較し、並べたい順番と逆転していたら両者を入れ替える。この手順を最高で要素数-1回繰り返すと並べ替えが完了する。要素の入れ替えが発生しなくなった時点で処理を打ち切ってもよい。

一般的な実装では、この処理を列の一方の端から反対の端まで順番に行うことが多く、繰り返しの度に未整列の要素の中で最も大きな(あるいは小さな)要素が列の端に移動していく様子を泡(バブル)が浮き上がっていく様に例えてこのような名称となった。

最良の場合の計算時間は O(n) と高速だが、最悪の場合の計算時間は O(n2) と整列法の中でも最も遅い部類に入り、平均して高速な手法とは言えない。ただし、要素の比較・交換は順序を問わず並列化しやすいという特徴があり、並列分散処理が可能な環境では高速化することができる。

整列したいデータ列以外の記憶領域を用意しなくてよいインプレースソート(内部ソート)で、同じ大きさの要素の順序が入れ替わらない安定ソートである。アルゴリズムの理解や実装が容易で、コードの記述量が少ない。実用上はあまり使われないが、整列法の学習ではほぼ必ず取り上げられ、効率化した派生アルゴリズムも多く考案されている。

ホーム画面への追加方法
1.ブラウザの 共有ボタンのアイコン 共有ボタンをタップ
2.メニューの「ホーム画面に追加」をタップ
閉じる