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

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動

このページでは、プログラミングにおいて頻出である共通の知識を説明する。

概要[編集]

プログラミングはWindows(ウィンドウズ)、macOS(マック)、GNU/Linux(リナックス)、ChromeOS(クロームブック)、*BSD(ビーエスディー)どのOSでも、行うことができる。 スマートフォン向けのOS、iPhone(アイ フォーン) や Android(アンドロイド)などで行うこともできる。

※注釈:以下では、電子計算機を指す用語として「コンピュータ」、「コンピューター」が混在している場合があるが、どちらも同じ意味である。

「プログラミング」とは?[編集]

プログラム」はコンピュータにしてもらう指示をまとめたものです。「プログラミング」は、「プログラム」を作成することです。私たちはプログラムを作ってコンピュータに実行させることでコンピュータに仕事をしてもらいます。現代のコンピュータは、内部では0と1だけの2進数で動作しています[1]。2進数で表現されていることを特に「バイナリ」と呼びます。それに合わせて、指示は0と1のみで表現される「機械語」で与える必要があります。しかし機械語は直接読み書きすることは困難です。そこで、より私たちの話す言語に近い文法や単語からなる”記号”で指示を記述して、それをあとで2進数に訳して実行させるという方法が生まれました。この「翻訳する」作業を「コンパイル」と呼びます。

文字入力[編集]

プログラミングをするからには、文字の入力ができなくては始まらない。以下は、文字に関する概念を簡単に述べる。

バイナリファイルとテキストファイル[編集]

概要: バイナリファイルとテキストファイルは人間都合の呼びわけである。

コンピュータはHDD、SSDなどの記憶媒体にファイルを保存する。「テキストファイル」とは、文字として解釈することを想定されたファイルを指す。対となる概念として、「バイナリファイル」がある。Windowsではテキストファイルには.txtという拡張子を付けることが多い。プログラムを作るとき、拡張子は言語に応じたものを付けて区別する。

テキストエディタ[編集]

概要: テキストエディタは怖くない。

文字を入力するときは、専用のアプリを起動する。以下に不完全なOSに付属しているエディターのリストを示す:

  • Windows: メモ帳 (notepad.exe)
  • macOS: vi, emacs
  • GNU/Linux: nano

さらに、emacsやvim、Atom、VSCodeもテキストエディタと呼ばれる。エディタによっては、シンタックスハイライトと呼ばれる色分けをする機能や、折りたたみ機能など、特色ある機能を搭載している場合がある。テキストエディタのインストール方法については、ここでは取り扱わないので、各エディタのマニュアルを参照すること。

ワープロソフトは使えない[編集]

概要: マイクロソフト社のWord(ワード)のようなワープロソフトでは、テキスト以外に付属するデータがあるため、プログラミングには使えない。

ワープロソフトで保存されるのはバイナリファイルであることが非常に多い。ワープロソフトで文章を保存しても、文章がそのままテキストとして保存されるわけではない。そのファイルの拡張子を「.c」に書き換えてC言語として再解釈しようとしても、コンパイルエラーになってしまうだろう。なぜエラーになるかというと、ワープロソフトには、メタデータと呼ばれるフォントの種類、大きさ、色、位置関係の情報など、文字そのもの以外の情報もふくまれているからだ[2]

入力モード[編集]

概要: 大半のプログラミング言語において、ほとんどの記号、数字は、半角英数字で入力しなければならない。表示させたい文章などは、その限りではない。

プログラム中に出現する記号は、ほとんどの場合、半角英数字で入力する必要がある。大抵のOSでは直接入力モードに切り替える必要がある。OSによっては、半角モードと直接入力モードとは、べつのモードの場合がありますので、気をつけましょう。なお、Windows7では、半角英数が直接入力です。

print("おはよう")

というコードがあったとしたら、「print」「(」「"」は直接入力モードで入力します。「おはよう」を全角モードで入力します。そして、ふたつめの「"」「)」は直接入力モードで入力します。つまり、例外的に日本語表示をしたい部分だけを除いて、原則的に直接入力モードで、入力することになります。

拡張子[編集]

概要: ファイルの最後の「.」より後ろをw:拡張子と呼ぶ。ファイルの名前にはわかりやすくするために拡張子をつけておく。

拡張子(かくちょうし)はテキストエディタで保存する時つける必要がある。拡張子は、プログラミング言語の種類によって変わるため、それぞれのプログラミング言語についてのマニュアルを参照する。C言語で保存するには、「.c」を末尾につける。sampleという名前のファイルをC言語として保存する場合には、ファイル名をsample.cとする。

コマンドラインと慣れ親しむ[編集]

概要: キャラクターインターフェイスのみ用意されている場合は、コマンドラインで諸々の準備を行わなければならない。

  • Windowsの場合: cmdまたはpowershell
  • macOS場合: /bin/tcsh
  • GNU/Linuxの場合: /bin/bash

真っ黒な画面、白い文字。恐怖心を覚えるかもしれないが、避けては通れない道である。プログラミング言語によっては扱う必要がないかもしれない。パッケージマネージャーによるインストールなどはここでは扱わないので、各OSのマニュアルを参照。

  • コマンドラインから抜ける: exit

実行、意味論の解釈[編集]

コンピュータが認識できるのは機械語のみであることは先で述べました。しかしプログラミング言語は文法に沿った言語で書かれています。それらの書かれた文章をソースコードと呼びます。では、プログラミング言語→機械語の変換 (翻訳) はどうするのか。

インタプリタ[編集]

  1. ソースコード(あるいはソースコードから変換した中間表現)を読み込み解釈しながら実行するプログラムのこと。
  2. ソースコードを翻訳する部分。

スクリプト言語と呼ばれる言語は、おおむねインタプリタ方式を採用しています。インタプリタ方式を採用しているプログラミング言語は、JavaScriptPythonなどがあります。 手軽に書いてすぐ実行できるというメリットがある反面、プログラムの実行時に毎回解釈をする必要があるのでプログラムの実行速度はコンパイル方式のプログラミング言語に実行速度が劣る場合があります[3]。 インタプリタ方式を採用した言語の処理系は、ソースコードを直接実行するのでプログラムを書き換えると、即時に実行結果もそれに応じて変化します。

コンパイル[編集]

ソースコードを予めに機械語に翻訳し、機械語のファイルを実行するという方法もあります。プログラムのコードを機械語に変換することを、コンパイルと言います。コンパイルするためのソフトウェアのことをコンパイラといいます。コンパイルが必要な言語をまとめてコンパイル型言語と言うことがあります。また実行時コンパイラ(JIT; Just-In-Time Compiler)との対比で、事前コンパイラ(AOT;)と呼ばれます。

コンパイル型言語は

などがあります。

コンパイル型言語では、ソースコードが書かれたファイルと、実行ファイルとは、別のファイルです。 そのためソースコードを変更してもコンパイルしなければ変更が反映されません。 コンパイル型言語の実行ファイルは、機械語で書かれています。 コンパイル型言語のプログラムの実行では、機械語で書かれた実行ファイルをそのまま実行するので処理が高速です。 実行ファイルは、それぞれのハードウェアに合わせた機械語になっています[4]。 Windowsをターゲットにした実行ファイルをGNU/Linuxにコピーしても実行できません[5]。 実行ファイルから元々のソースコードを取り出すこと (デコンパイル) は一般に困難です。 機械語にはそのハードウェアたいする命令だけが書かれており、ソースコードは機械語には書かれていません。 機械語に変換された実行ファイルは、配布するプログラムのソースコードを秘密にすることが可能というメリットもあります。 プログラムのコードをコンパイルしたファイルを実行ファイルにまとめる前のファイルをオブジェクトファイル言います。 ソースコード → オブジェクトファイル → 実行ファイルという流れになります。

違いは?[編集]

  • ソースコードを書き換えた場合
    • インタプリタ型:実行結果が変化する
    • コンパイル型:コンパイルし直さないと実行結果が変化しない

どちらでもない言語、両方できる言語[編集]

ここまでプログラミング言語をスクリプト言語とコンパイル型言語に分けて説明してきましたが、どちらにも当てはまらないものや、両方の方法で実行できるものも存在します。

中間言語を生成するプログラミング言語[編集]

ソースコード→classファイル→機械語

プログラミング言語のなかには、インタプリタかコンパイラかの分類に当てはまらない言語もあります。例えば、Javaはソースコードを、Java仮想マシンが解釈できる中間言語 (Javaバイトコード) にコンパイルします。そして実行時に、その中間言語を読み込みそれを実行するという仕組みです(中間コード・インタプリタ)。中間言語ファイルは機械語から独立しているため、どのハードウェアでも使うことができます。かわりにユーザーは、Java中間言語を実行するソフトウェア (JRE; Java Runtime Environment) をインストールします。そして、そのJavaのランタイムは、Windows、macOS、GNU/Linux系列といったそれぞれのOSごとで動作するように開発・維持されています。ユーザーから見れば、Javaのように中間言語を生成するプログラミング言語は、どのOSにも依存せず動作するので理想的なように見えます。しかし、ユーザーから見て統一的なAPIを提供しつつ、統一的なAPIとそれぞれのOSの違いを吸収する部分を実装することは非常に手間がかかります。

両方できる言語[編集]

また、コンパイルして実行することもインタプリタ実行も両方できる場合がある。Python、Go言語、Haskellは、その例である。

例外[編集]

コンパイル型言語を逐次実行、あるいはインタプリタ型の言語をコンパイルして使用する場合

コンパイル型言語であるC言語を逐次実行したり、インタプリタ型のBASIC[6]をコンパイルしたりする場合は分類に当てはまらない。

現状[編集]

インターネットとの関係[編集]

ウェブページ用プログラミング言語としても 普及しているJavaScriptは、ブラウザ付属のインタプリタとしてウェブブラウザに実装されていることがほとんどだ。インタプリタかコンパイラかどうかは、けっして言語の仕様そのものによるものではなく、実装による違いだ。Pythonのようにインタプリタとして実装されているプログラミング言語に、追加モジュールとしてウェブプログラミング用モジュールを付け加えて(すでにそのようなモジュールが開発されており配布されている)、それでpythonなどでウェブプログラミングを行うという方法もあります。

レキシカル・アナライザ[編集]

ソースコードは通常の文字列ですが、文字列のママ構文解析を行うことは出来ないので、文字列からトークンを切りだします。 トークンを切り出すプログラムのことをレキシカル・アナライザあるいは構文解析器(こうぶんかいせきき)と呼びます。 トークンとは、プログラミング言語のキーワード・識別子・デリミターなどのこれ以上分解すると意味が変わってしまう構文単位で、自然言語学の語に近い概念です。

パーサ[編集]

レキシカル・アナライザの出力は、トークンの1次元配列(トークン列)でこれから直接機械語に変換する事はできません。 そこでトークン列をプログラミング言語の構文の何に当てはまるか解析して内部表現(構文木)に変換します。 このようなプログラムのことを、トークン列をを解析して解釈する機械という意味で、「構文解析器」(こうぶんかいしゃくき、パーサ parser)と言います。

字句解析と構文解析を別々に行うことが可能なプリグラミング言語もありますが、多くのプログラミング言語では(文法に曖昧さがあったり、字句に対し意味論が重複しているなどの理由で)字句解析と構文解析は連携するする必要があります。

文法[編集]

代入[編集]

注釈: a = a + 1が何を指すかご存知だろうか。aが変数、 x = yが変数xに式yの評価結果を代入していることが理解できるのであればこの文章は読み飛ばしても良い。

プログラミングと数学では、=が指す意味が違う。数学ではとすることで、が同一であることを意味するが、プログラミングにおいてa = bは変数aに式bの評価結果を代入する。たとえば、a = a + 1で、aが2とすると、a = 2 + 1となり、2 + 1の評価結果がaに設定される。ほとんどの場合は、2 + 13に評価されて代入される。

変数[編集]

なお、上記の説明で、当然のように「変数」という言葉を用いたが、この「変数」という用語も、数学とは扱いかたが微妙に違うので、気をつける必要がある。 変数名の命名規則については、それぞれのプログラミング言語のマニュアルを参照すること。 また、なお、たいていの言語では、大文字、小文字を区別 (case-sensitive) する。 C言語で例を示す:

例1
a = 2;
a = A + 1;

以上のプログラムはエラーになる。aAは区別され、Aが定義されていないためである。 変数aを1増やしたいのであれば、例2のようにする。

例2
a = 2;
a = a + 1;

実行すれば、aの値は3になる。

静的型付け言語と動的型付け言語
プログラミング言語は、静的型付け言語と動的型付け言語に大別されます。両者の間で、代入や変数の意味論が異なるので明確に区別する必要があります。
静的型付け言語
具体例
Fortran, COBOL, C言語, C++, Java, Go, Rust
特徴
変数は型を持つ
代入は、変数と結びついた記憶領域への右辺値のコピー
動的型付け言語
具体例
LISP, JavaScript, Python, Ruby
特徴
変数に型はなく、変数に束縛された値(=オブジェクト, =インスタンス)が型を持つ
代入は、変数への値の束縛

BASICのような変数名に型情報を持った言語や、関数型言語の一部のように変数そのものを持たない言語もあります。

プログラミング言語の学習において、その言語のパラダイムにおける型システム・変数システム(オブジェクトシステム)の理解は初学時の重要な要素です。


実行順序[編集]

単文は出現順序が先の方から順に実行されることがほとんどである。文を区切るのは改行、あるいは; (セミコロン) を使用することが多い。例2で示したプログラムなら、a = 2;のあとに、a = a + 1;が実行される。

数値[編集]

ソースコードで記述する整数リテラル、及び小数リテラルは、特に指定をしないかぎり、10進数である。整数と、(ほとんどの場合、IEEE 754に準拠した) 有限のケタの小数が、普通のプログラミング言語では使える。分数や平方根( など)などは、関数として用意されている場合でも、評価結果が近似される。また、小数も精度以下の部分は近似して表されます。

もし に近似されたなら、コンピュータ内部では、ではなく、という値として表現されています。上記のように、本来なら数学的には無限のケタの平方根などの無理数を有限ケタの小数に近似してしまうため、誤差が発生する。このような、無限小数を有限小数に近似したために誤差の発生する現象のことを浮動小数点数による誤差という。

過去の編集で、浮動小数点数による誤差ケタ落ちとしていましたが、桁落ちとは、丸め誤差を含む非常に近い大きさの小数同士で減算を行ったときに、有効数字が減る現象のことを言い有限の仮数部と指数部で表すことによる誤差とは違う概念です。また一般に浮動小数点数は2進数が採用されているので、十進数では有限桁数で表現できても浮動小数点数では循環小数になることがあります(例えば、 0.110 = 0.000110011001100…2)。

関連項目[編集]

脚注[編集]

  1. ^ フラッシュメモリーのMLC/TLCに代表されるw:多値論理など、特殊なアーキテクチャを採用しているコンピューターを除く
  2. ^ 実は多くのワープロソフトではテキストファイルを保存する方法が用意されており、それで保存すればプログラミングもできないこともありません。ただしワープロソフトはプログラミングを意図した設計になっていないので、ワープロソフトでやるメリットはほとんどありません。
  3. ^ インタープリタは実行時に「どの部分が多く実行されたか?」「分岐命令でどちらに多く分岐したか?」などの実行時統計情報を容易に手に入れることができ、これらに基づき実行時コンパイラ(JIT)による最適化が可能となりる。よって、一概にインタプリタ方式がコンパイル方式より実行速度が劣るとは言えない。
  4. ^ 異なるハードウェアの実行ファイルは、通常は仮想機械環境を使わない限り実行できません。
  5. ^ 同じハードウェアでも異なったOSで相互に実行ファイルが実行できない理由は、いくつかありますが、実行ファイルの形式の違いとOSの提供するシステムコールの違いが主なもので、この2つを克服したWine(GNU/LinuxでWindowsの実行ファイルを実行可能にする環境)やWSL(WindowsでGNU/Linuxの実行ファイルを実行可能にする環境)では異なったOSの実行ファイルの実行を実現しています。
  6. ^ 注釈: Quick BASIC というBASIC実行ソフトがあり、これが、コンパイルすることによって実行速度を速めた改良型のBASICでした。