プログラミング/共通知識

このページでは、プログラミングにおいて頻出である共通の知識を説明する。
プログラミングはWindows(ウィンドウズ)、macOS(マック)、GNU/Linux(リナックス)、ChromeOS(クロームブック)、*BSD(ビーエスディー)どのOSでも、行うことができる。 スマートフォン向けのOS、iPhone(アイ フォーン) や Android(アンドロイド)などで行うこともできる。
※注釈:以下では、電子計算機を指す用語として「コンピュータ」、「コンピューター」が混在している場合があるが、どちらも同じ意味である。
「プログラム」はコンピュータにしてもらう指示をまとめたものです。「プログラミング」は、「プログラム」を作成することです。私たちはプログラムを作ってコンピュータに実行させることでコンピュータに仕事をしてもらいます。現代のコンピュータは、内部では0と1だけの2進数で動作しています。2進数で表現されていることを特に「バイナリ」と呼びます。それに合わせて、指示は0と1のみで表現される「機械語」で与える必要があります。しかし機械語は直接読み書きすることは困難です。そこで、より私たちの話す言語に近い文法や単語からなる”記号”で指示を記述して、それをあとで2進数に訳して実行させるという方法が生まれました。この「翻訳する」作業を「コンパイル」と呼びます。
プログラミングをするからには、文字の入力ができなくては始まらない。以下は、文字に関する概念を簡単に述べる。
概要: バイナリファイルとテキストファイルは人間都合の呼びわけである。
コンピュータはHDD、SSDなどの記憶媒体にファイルを保存する。「テキストファイル」とは、文字として解釈することを想定されたファイルを指す。対となる概念として、「バイナリファイル」がある。Windowsではテキストファイルには.txtという拡張子を付けることが多い。プログラムを作るとき、拡張子は言語に応じたものを付けて区別する。
概要: テキストエディタは怖くない。
文字を入力するときは、専用のアプリを起動する。以下に不完全なOSに付属しているエディターのリストを示す:
さらに、emacsやvim、Atom、VSCodeもテキストエディタと呼ばれる。エディタによっては、シンタックスハイライトと呼ばれる色分けをする機能や、折りたたみ機能など、特色ある機能を搭載している場合がある。テキストエディタのインストール方法については、ここでは取り扱わないので、各エディタのマニュアルを参照すること。
概要: マイクロソフト社のWord(ワード)のようなワープロソフトでは、テキスト以外に付属するデータがあるため、プログラミングには使えない。
ワープロソフトで保存されるのはバイナリファイルであることが非常に多い。ワープロソフトで文章を保存しても、文章がそのままテキストとして保存されるわけではない。そのファイルの拡張子を「.c」に書き換えてC言語として再解釈しようとしても、コンパイルエラーになってしまうだろう。なぜエラーになるかというと、ワープロソフトには、メタデータと呼ばれるフォントの種類、大きさ、色、位置関係の情報など、文字そのもの以外の情報もふくまれているからだ。
概要: 大半のプログラミング言語において、ほとんどの記号、数字は、半角英数字で入力しなければならない。表示させたい文章などは、その限りではない。
プログラム中に出現する記号は、ほとんどの場合、半角英数字で入力する必要がある。大抵のOSでは直接入力モードに切り替える必要がある。OSによっては、半角モードと直接入力モードとは、べつのモードの場合がありますので、気をつけましょう。なお、Windows7では、半角英数が直接入力です。
というコードがあったとしたら、「print」「(」「"」は直接入力モードで入力します。「おはよう」を全角モードで入力します。そして、ふたつめの「"」「)」は直接入力モードで入力します。つまり、例外的に日本語表示をしたい部分だけを除いて、原則的に直接入力モードで、入力することになります。
概要: ファイルの最後の「.」より後ろをw:拡張子と呼ぶ。ファイルの名前にはわかりやすくするために拡張子をつけておく。
拡張子(かくちょうし)はテキストエディタで保存する時つける必要がある。拡張子は、プログラミング言語の種類によって変わるため、それぞれのプログラミング言語についてのマニュアルを参照する。C言語で保存するには、「.c」を末尾につける。sampleという名前のファイルをC言語として保存する場合には、ファイル名をsample.cとする。
概要: キャラクターインターフェイスのみ用意されている場合は、コマンドラインで諸々の準備を行わなければならない。
真っ黒な画面、白い文字。恐怖心を覚えるかもしれないが、避けては通れない道である。プログラミング言語によっては扱う必要がないかもしれない。パッケージマネージャーによるインストールなどはここでは扱わないので、各OSのマニュアルを参照。
言語処理系とは、プログラミング言語で記述されたプログラムをコンピューターで実行するためのソフトウエア・システムです。 言語処理系は#インタプリターと#コンパイラーに大別されます。
インタープリターとは、コンピュータプログラムを解釈して実行するソフトウェアです。コンピュータが理解できる機械語にコンパイルすることなく、プログラムを直接実行することができます。
インタープリターは、プログラムの実行中に逐次的にプログラムのコードを読み込み、それを解釈して実行します。これに対して、コンパイラーはプログラム全体を処理して、機械語のオブジェクトコードを生成するため、実行が速くなりますが、実行前に完全なコンパイルが必要です。
インタープリターは主にスクリプト言語や、インタラクティブな開発環境で使用されます。スクリプト言語では、CやJavaなどのような静的型付け言語よりもコードが簡潔になる場合があります。また、インタラクティブな開発環境では、プログラムを逐次的に開発し、インタープリターのリアルタイムなフィードバックを受けられるため、効率的な開発が可能になります。
一方、インタープリターの欠点として、実行速度がコンパイラーに比べて遅いことや、プログラムが実行される際に繰り返し同じコードの部分を解釈するため、コードを効率的に実行することができないことが挙げられます。
ただし、インタープリターは実行時に「どの部分が多く実行されたか?」「分岐命令でどちらに多く分岐したか?」などの実行時の統計情報を容易に手に入れることができます。 これらに基づき実行時コンパイラー(JIT)による最適化が可能となります。よって、一概にインタープリターがコンパイラーより実行速度が劣るとは言えません。
言語処理系にインタープリターを採用している言語には
などがあります。
コンパイラーとは、プログラミング言語で書かれたソースコードを予め機械語に変換するソフトウェアのことです。 この処理をコンパイルと言います。主要な実装がコンパイラーのプログラミング言語をコンパイル型言語と呼びます。
利点:
欠点:
言語処理系にコンパイラーを採用している言語には
などがあります。

プログラミング言語処理系における「バイトコード型」とは、ソースコードをバイトコードと呼ばれる中間言語に変換し、実行する方式をとることが特徴的です。バイトコードはCPUに依存しないアーキテクチャに従ったバイナリフォーマットであり、翻訳処理の後の直接実行ではなく、擬似的な実行環境であるバイトコード仮想マシンで実行されます。これにより、異なるプラットフォームやOSでも同じバイトコードを実行することができ、移植性が高くなります。PythonやJava、.NET Frameworkなどがバイトコード方式を採用しています。
バイトコード型には
などがあります。
pコードマシン(portable code machine)とは、pコード(仮想の中央処理装置(CPU)のアセンブリ言語またはマシンコード)を実行するように設計された仮想マシンのことです。
この用語は、Java仮想マシン(JVM)やMATLABの事前コンパイルされたコードなど、すべてのこのようなマシンに一般的に適用され、特定の実装にも適用されます。
最も有名な実装は、Pascal-Pシステムのp-Machineであり、特にUCSD Pascal実装があります。p-codeのpは、ポータブルよりも擬似(pseudo)であるという意味で解釈され、擬似マシンの命令を意味する擬似コード(pseudo-code)という用語も使われます。
このコンセプトはBCPLのO-codeとEulerのP codeとして、約1966年に初めて実装されました。
しかし、p-codeという用語は、1970年代初頭に初めて現れました。初期のp-codeコンパイラーには、Kesav V. Nori、Urs Ammann、Kathleen Jensen、Hans-Heinrich Nägeli、Christian Jacobiによる1973年のPascal-Pコンパイラーと、Niklaus Wirthによる1975年のPascal-Sコンパイラーがあります。
pコードに翻訳されたプログラムは、仮想のCPUの動作をエミュレートするソフトウェアで解釈するか、プログラムが実行されるCPUのマシンコードに翻訳して実行することができます。十分な商業的関心があれば、CPU仕様のハードウェア実装が構築されることもあります(例えば、Pascal MicroEngineやJavaプロセッサなど)。
O-codeとは、BCPLコンパイラーによって生成される中間言語のことです。その後、このO-codeを特定のコンピュータで動作するためのマシンコードに再コンパイルします。このコンパイル方法によって、元のBCPLコンパイラーを新しいマシンにポーティングしやすくなり、広く使われるようになりました。このアイデアは現在の多くのコンパイラーでも使用されています。ただし、多くの場合、それらのコンパイラーは、元々の方法とは異なり、仮想マシンでO-codeの相当部分を解釈することがほとんどです。
O-codeマシンは、1960年代後半にMartin Richardsによって開発された仮想マシンで、BCPLのマシン非依存性を実現するために作成されました。O-Codeマシンのコンセプトは、BCPLコンパイラーを使用してO-codeを出力することです(Oはオブジェクトの略)。その後、O-codeは、通常はマシン固有のコードにコンパイルされます。このアイデアは、後に発行されたコンパイラーで使用されました。たとえば、一部のPascalコンパイラーではp-codeが使用され、Javaコンパイラーによって生成されるJVM用のバイトコードが使用されました。
O-codeは、BCPLコンパイラーの開発時に、一般的なコンパイルの問題と、マシン固有の実装の問題とを分離することができ、ポーティングが容易になりました。その結果、BCPLは多くのマシンで利用できるようになりました。
P codeは、Euler言語のバイトコードであり、Eulerプログラムをコンパイルして生成されます。P codeは、Eulerインタプリタで実行されます。
Euler言語は、数式処理に特化したプログラミング言語です。P codeは、数式処理を高速化するために開発されました。P codeには、数値計算とシンボリック計算を両方サポートする命令が含まれています。
P codeプログラムは、16ビットの命令と、オペランドとして使用される1〜3バイトの定数で構成されており、一般的なプログラムに必要な命令をカバーしています。P codeには、演算、論理、制御、スタック操作などの命令が含まれています。命令が実行されると、スタックに結果がプッシュされます。スタックは、計算途中の値や戻り値を格納するために使用されます。
P codeは、コンパクトなバイトコード形式であり、高速な処理を可能にします。また、Eulerインタプリタは、P codeを直接実行できるため、コンパイル時のオーバーヘッドがなく、動的なコンパイルも可能です。
Java仮想マシン (JVM) は、Javaバイトコードを実行するための仮想マシンです。Javaバイトコードは、Javaプログラムを機械語に変換することなく、クロスプラットフォームで実行可能な形式であります。
JVMは、Javaプログラムが実行される際に、バイトコードを解釈し、ハードウェアやオペレーティングシステムに依存しない同じ結果を得ます。JVMは、メモリ管理、例外処理、動的なリンク、セキュリティなど、Javaプログラムの実行に必要なさまざまな機能を提供します。JVMは、Garbage Collectionを使用してJavaプログラムのメモリに自動的に割り当てられたオブジェクトを解放し、メモリリークやセキュリティ問題を回避します。
JVMは、Javaの重要な要素であり、Javaの大部分の魅力的な特徴を可能にしています。Javaのクロスプラットフォームの特性は、JVMによって実現されています。JVMは、Javaプログラムの実行に必要な環境を提供し、Javaプログラムが広く使用されている理由の1つです。
また、JVMを利用するJava以外の言語として、Groovy、Scala、Kotlin、Clojureなどが登場しています。
Java仮想マシンのアーキテクチャは、その後の共通言語ランタイムなどに影響を与えました。
共通言語ランタイム(Common Language Runtime、略称CLR)とは、マイクロソフトが開発した、.NET Frameworkの一部である実行環境のことです。CLRは、プログラマがC#、Visual Basic .NET、F#などの.NET対応言語で開発したアプリケーションを実行するために必要な環境を提供します。
CLRは、様々な機能を提供しています。例えば、メモリの自動管理や、例外処理、スレッドの管理、セキュリティの管理などがあります。これらの機能によって、開発者はアプリケーションの開発において、より高い生産性と品質を実現することができます。
また、CLRは、プログラムの実行速度にも影響を与えます。CLRによって、プログラムがJIT(Just-In-Time)コンパイラーによってコンパイルされます。JITコンパイラーによるコンパイルによって、プログラムの実行速度が向上することがあります。
CLRは、Windows上で.NET対応アプリケーションの実行環境として使用されます。開発者は、Visual Studioなどの開発ツールを使って、CLRを使用したアプリケーションの開発を行うことができます。
この様に、言語処理系の主要な実装があるいは多くの場合は最初の実装が、インタプリタなのかコンパイラーなのかで分類しているので、例外が生じる余地があります。
字句解析器( Lexical Analyzer ) とは、コンピュータプログラムの中で文字列からトークン列( Token Stream )を作るためのプログラムです。 字句解析は、コンピュータ言語の文法規則に基づいて行われます。字句解析の目的は、ソースコードをトークン列に分割し、それを後続の解析プロセスで利用することです。
字句解析器の主な機能は、入力文字列をトークン( Token )に分割することです。すなわち、入力文字列をトークンに分解し、それぞれに意味を持たせることです。 トークンは、予約語、演算子、識別子、定数などの要素に分類されます。字句解析器は、毎秒数百万回以上のトークンの判別を行うことができます。
一般に、字句解析器は次の手順に従って動作します。
字句解析器は、プログラミング言語処理系の中で非常に重要な役割を果たしています。 例えば、コンパイラでは、字句解析器が入力ソースコードをトークン列に変換し、構文解析器( Parser )によって文法的に正しいかどうかをチェックします。 また、インタプリタでも、字句解析器が入力文字列をトークン列に分割し、それを解釈するプロセスで利用します。
構文解析器( Parser )は、プログラミング言語などの形式言語を解析し、その構文構造を特定の形式(構文木など)で表現するシステムです。構文解析は、自然言語処理やコンパイルなどの分野で活用されます。
構文解析器は、トークンと呼ばれる基本的な言語要素を入力として取り、文法規則に基づいて構文解析を実行します。構文解析の結果、入力されたテキストが文法的に正しいかどうかが判断され、構文木などの特定の形式で表現されます。
構文解析器は、主に2つの方法で実装されます。一つは、手動で文法規則を記述し、それに基づいて構文解析を行う方法です。もう一つは、自動生成された構文解析器を使用する方法です。自動生成された構文解析器は、文法の定義から直接作成されます。
構文解析器は、プログラミング言語やデータベースクエリ言語など、様々な分野で使用されます。例えば、プログラムのコンパイルに際しては、ソースコードをトークンに分解し、構文解析器によって構文解析された結果をもとに、最終的な実行ファイルを生成します。
構文解析は、自然言語処理の分野でも重要な役割を果たします。例えば、文書を形態素に分割し、それらから構成される文節を特定するような解析を行うことができます。また、質問応答システムなどでは、ユーザーの入力を構文解析して、それに適切な回答を返すことが求められます。
まず、プログラミングにおける「変数」とは、情報を格納するために使用されるメモリ上の場所を指します。 データを扱う必要がある全てのプログラムで変数が使用され、データを一時的に保持するために使用されます。
変数には値を代入することができます。このプロセスは「代入」と呼ばれます。代入演算子(=)を使用して変数に値を代入することができます。例えば、以下のようになります。
静的型付け言語の例を示します。C言語では、変数は使用する前にデータ型を宣言する必要があります。例えば、以下のようになります。
一方、動的型付け言語の例を示します。Pythonでは、変数にはデータ型の宣言が必要ありません。以下のように使用できます。
このように動的型付け言語では、変数に代入する値の型は実行中にも変えることが出来ます。
静的型付け言語との違いを強調するため、「変数xに整数10を束縛します」のように「代入」ではなく「束縛」という用語を使うことがあります。
文は出現順序が先の方から順に実行されることがほとんどです(逐次実行)。(C言語では)式の後に; (セミコロン) を後置すると文(式文)となります。
ソースコードで記述する整数リテラルおよび小数リテラルは、特に指定がない限り、10進数であることが一般的です。また、ほとんどの場合、IEEE 754に準拠した有限の桁数を持つ浮動小数点数が使用可能です。浮動小数点数に関しては、有限の精度の近似値として表現され、誤差を含みます。
過去の編集で、浮動小数点数による誤差 をケタ落ちとしていましたが、桁落ちとは、丸め誤差を含む非常に近い大きさの浮動小数点数同士で減算を行ったときに、有効数字が減る現象のことを言い有限の仮数部と指数部で表すことによる誤差とは違う概念です。また一般に浮動小数点数は2進数が採用されているので、十進数では有限桁数で表現できても浮動小数点数では循環小数になることがあります(例えば、 0.110 = 0.000110011001100...2)。