WisdomSoft - for your serial experiences.

1.2 プログラミング言語 C++

CPU はバイナリ(2進数)の機械語しか実行できないため、より人間が理解しやすい言葉で命令を記述できるようにしたものがプログラミング言語です。C++ などプログラミング言語で記述されたプログラムが、どのように機械語に変換されて実行されるか解説します。

1.2.1 プログラミング言語の役割

CPU が解釈できる命令は、電気的なオンとオフで表現された機械語と呼ばれる 2 進数列です。人間のような言葉で理解しているわけではないため、単純な計算であってもオペコードと呼ばれる数値で命令を構築する必要があります。しかも、命令の意味を表す数値は CPU の種類によっても異なります。現代の PC の多くは Intel 社の x86 CPU をベースとした命令形態となっていますが、携帯機器では ARM が有名です。

人間にとって、数値の組み合わせで命令を作るというパズルのような行為は複雑で面倒な作業となり、間違いも生み出しやすくなります。しかも、CPU の種類によって仕組みも機械語も異なるため、複雑な機械語を CPU の種類ごとに学習しなければなりません。これは、開発者にとって大変な負担です。そこで、より人間に近い言葉でプログラムできるようにと生み出されたものがプログラミング言語なのです。

プログラミング言語は、英単語の組み合わせで命令を記述するのでテキスト形式でプログラムを保存できます。多くのプログラムは、完成した後もビジネス環境の変化に合わせて修正していかなければなりませんが、テキストによるプログラムの表現であれば読み直しや修正が機械語よりも容易です。

最初のプログラミング言語は、機械語の命令と一対一の関係を持ったアセンブリ言語や、アセンブリ言語に一部の処理を簡素化させる疑似命令を追加したマクロアセンブラなどが使われていました。アセンブリ言語は、単に数値で表される機械語の命令に、ニーモニックと呼ばれる省略された英単語を与えただけです。

図1 機械語とアセンブリ言語
図1 機械語とアセンブリ言語

例えば、Intel x86 の機械語で 32bit の値を EAX レジスタに読み込んで加算せよという命令は 05 というオペコードで表されます。アセンブリ言語では 05 というオペコードに対応する ADD EAX というニーモニックで記述します。05 という数値よりは、このような英単語による文字の方が理解しやすいでしょう。しかし、アセンブリ言語を理解するには CPU の仕組みと、ニーモニックに対する機械語を理解しなければなりません。

そこで、アセンブリ言語よりも機械語を抽象化し、プログラマが処理したい目的を記述できるようなプログラミング言語が生まれました。1950 年代に誕生したプログラミング言語 FORTRAN、LISP、COBOL などが最も古いプログラミング言語ですが、その後に誕生したプログラミング言語に多くの影響を与えています。これらの言語はアセンブリ言語と違い、英文や記号、数式の組み合わせで命令を記述できます。

アセンブリ言語のような、機械語と一対一またはそれに近いようなプログラミング言語を低水準プログラミング言語と呼びます。これに対して FORTRAN や LISP のような機械語と直接の関係を持たない言語を高水準プログラミング言語と呼びます。もちろん C++ も、高水準プログラミング言語です。 

1.2.2 コンパイラ

アセンブリ言語も、その他の高水準言語も、テキストエディタで編集可能なテキスト形式で書かれます。しかし、CPU が認識できる命令は常にバイナリ表現の機械語だけです。従って、プログラミング言語で書かれたプログラムを CPU が理解することはできません。プログラムを実行するには、プログラミング言語を機械語に翻訳する必要があるのです。

アセンブリ言語で書かれたプログラムを機械語に変換するプログラムをアセンブラと呼びます。また、アセンブラでアセンブリ言語を翻訳することをアセンブルと言います。アセンブリ言語は機械語の命令に近いため、かつては人間がアセンブリ言語を読み取って、手作業で機械語に翻訳するハンドアセンブルと呼ばれる職人技も見られました。

これに対して、高水準言語を機械語に変換するプログラムのことをコンパイラと呼びます。また、コンパイラでプログラムを翻訳することをコンパイルと言います。コンパイラは、プログラミング言語ごとに用意しなければなりません。C++ 言語を翻訳するプログラムは C++ コンパイラと呼びます。

図2 コンパイルの流れ
図2 コンパイルの流れ

プログラミング言語が記述されたテキストをソースファイルと呼びます。高水準言語で書かれたプログラムの実体は単純なテキストファイルにすぎないため、これを直接実行することはできません。そこで、コンパイラがソースファイルを解析し、CPU が実行できる機械語に変換します。通常、コンパイラはオブジェクトファイルと呼ばれる機械語を含む中間ファイルを生成します。

オブジェクトファイルは、機械語の他に他のプログラムと組み合わせに必要な情報を含んでいます。ここから実行可能ファイル(Windows における exe 拡張子のファイル)を生成するには、コンパイラによって生成されたオブジェクトファイルや他の必要なファイルを結合しなければなりません。この工程をリンクと呼び、オブジェクトファイルをリンクさせるプログラムのことをリンカと呼びます。

一般的な開発環境にはコンパイラとリンカがセットで付属しています。本書で解説する Microsoft Visual C++ は、コンパイラやリンカはもちろん、ソースファイルを記述するエディタや、作成したプログラムをテストするための各種ツールが統合されています。

1.2.3 C と C++ 言語

本書で学習する C++ 言語について解説するには、その前身となっている C 言語について説明する必要があるでしょう。C 言語は 1972 年に誕生したプログラミング言語で、C++ 言語も含めて現在使われている多くのプログラミング言語の基礎となっています。高水準言語でありながらもアセンブリ言語に近いハードウェアよりのプログラムに適している言語のため、OS の中核部分や家電製品などに組み込まれる機器の制御用プログラム、ゲームなどの幅広い分野で実用されています。

C++ 言語は、1980 年代に登場した C 言語を拡張したプログラミング言語です。文法を C 言語から引き継いでいるため、C 言語で書かれたプログラムの多くは、そのまま C++ 言語としてコンパイルできます。そのため、C++ 言語のコンパイラは C 言語のコンパイラとしても利用できるものが一般的です。C++ 言語を学習するということは、C 言語を学習することにも繋がります。

C++ 言語で追加された機能は非常に多く、主にオブジェクト指向と呼ばれるプログラミング手法を取り入れていることが大きな特徴となっています。C++ 言語で追加された機能は、未経験者にとっては複雑に感じるものでしょう。本書では C 言語と共通する基本的な文法を中心に解説し、より高度な C++ 言語で追加された機能の学習へと導きます。

1.2.4 国際標準

前述したように C++ 言語で書かれたプログラムはコンパイラによって機械語に翻訳されなけれな実行できません。そこで、様々なシステム向けにコンパイラが作られるわけですが、コンパイラを作る人が勝手に新しい機能(文法)を追加したり、一部の機能を改変したらどうなるでしょう。C++ 言語の方言が大量に生成され、ソースコードが固有のコンパイラに依存してしまい、他のシステム用のコンパイラではコンパイルできなくなってしまいます。

こうした問題が発生しないように、世界中で使われる実用度の高いプログラミング言語の多くは国際標準化機構 (International Organization for Standardization, ISO)で、明確に文法が定められています。標準化機関によって定められている文法のことを仕様と呼び、この仕様に基づいて開発されたプログラムを実装(または処理系)と呼びます。ISO 標準に従っていれば、実装に依存することなく同じコードを確実にコンパイルできます。

C++ 言語のような歴史のある言語の場合、ISO 標準にもいくつかのバージョンが存在します。最初の標準は 1998 年に制定された ISO/IEC 14882:1998 であり、本書執筆時点での最新のバージョンは 2003 年に制定された ISO/IEC 14882:2003 です。現在は、次期標準として C++ 0x と呼ばれる改定案が議論されています。

図3 C言語とC++言語の歴史
図3 C言語とC++言語の歴史

図3は C 言語と C++ 言語の関係と標準化の歴史を簡単にまとめたものです。互いに互換性を意識しながら、しかし独立したプログラミング言語として進化しています。

標準化が行われる前の時代は、公式書籍が事実上の標準として参考にされてきました。C 言語では C 言語を開発した Brian Kernighan 氏と Dennis Ritchie 氏による共著「プログラミング言語 C」(The C Programming Language)が標準でした。これを二人の名前の頭文字から K&R とも呼びます。C++ 言語では C++ 言語を開発した Bjarne Stroustrup 氏による「プログラミング言語 C++」(The C++ Programming Language)が参考にされてきました。

本書では、執筆時点で標準的に使われている ISO/IEC 14882:2003 を基本に解説を行います。コンパイラを含む開発環境にはVisual C++ を採用していますが、標準 C++ に準拠しているコンパイラであれば Visual C++ 以外でも本書のサンプルコードをコンパイルできます。