C
読み:スィー
外語:C: Second letter of BCPL

 1972(昭和47)年、ベル研究所のデニス・リッチーによって開発された、関数を主体とするプログラミング言語
目次

情報

概要

UNIXの影響
 Cは汎用的な言語ではありつつ、実際はUNIX OS上のソフトウェアを書くためのもので、そのライブラリはUNIX上における実行環境を規定する物であった。
 またプログラムに記述する英字は小文字と大文字を区別するが、これもUNIXの影響によるものである。

仕様
 次のように分類される。
 現在はISO規格が主流である。ISO規格の初版と、元となったANSI規格とは実質的な差は殆どない。
 K&Rと呼ばれる旧仕様(標準ではない)は、"The C Programming Language" という本の第一版、ANSI仕様を採用した新仕様は同本の第二版にて解説されていて、この二冊はCの聖書と呼ばれることがある。

由来

言語の発案
 アセンブリ言語に代えてUNIXを記述するための高級言語として開発された。
 ANSI規格化を経て、現在はISOにより規格化がなされておりUNIXのためだけの言語ではなくなったが、元々Cの標準ライブラリ関数はUNIX OSのAPIをCから呼び出せる形に見せていたものであった。

名前の由来
 Cという名の語源であるが、CはBの後継であり、Bの更に先祖にBCPLという言語がある。この2言語の名称はここから来ていると言われている。
 B言語は頭文字、C言語は2文字目を取って命名されたというわけである。そのためCの後継言語はP言語になるなどと言われていたが、現在最も有名なCの後継言語はC++である。

技術

変数型
 プリミティブ型として用意される変数型は次の通り。
 なお、整数型にはsignedunsignedがある。signed/unsignedは省略可能で、省略時は概ねsignedとなる実装が一般的だが、charについてはsigned/unsignedどちらになるか実装ごとに異なる傾向にある。

複合型または別名定義
 プリミティブ型以外で、変数のようにして提供されるものは、Cでは原則としてtypedef]であるか、またはCコンパイラー独自実装の型である。
 C99以降は、Cの標準仕様として、目的に応じた長さが選べる変数型の別名定義が定義されるようになった。

プリプロセッサー
 Cの仕様は、実際のCの仕様と、プリプロセッサーの仕様とに分けられる。Cコンパイラーはプリプロセッサーが必ず搭載されている。
 Cでは、プリプロセッサー命令を使うことでコンパイル時にコンパイラーに命令を与えることが可能。代表例が #include であり、プリプロセッサーディレクティブはシャープ(#)が先頭に付く。有効範囲は#があるその行限り。どうしても行を継続する場合は、行末に \ が必要である。
 Cのプリプロセッサーはマクロプロセッサーで、コンパイルの際、実際のコンパイルの前にまず実行される。次のようなものがある。
 #の後は、通常は英字で実際の機能を記述する。殆どの場合、#の直後に記載されるが、実際の文法上は、#と機能名の間には空白を入れても良い。

プリプロセッサー演算子
 主として、#define のディレクティブのコンテキストで用いられるのが、次の四種類の演算子である。

歴史

CPL→BCPL
 Cの先々代とされるBCPLはCPLを簡略化した言語とされており、CPL→BCPLの段階で、大幅に言語仕様が削除された。特に注目される点は「データ型がない」ということである。
 CPLは複雑なデータ型の定義があったが、BCPLでは逆に、言語仕様としてデータ型の定義を削除し、プログラマーに任せることにした。

BCPL→B
 Bは、高級アセンブリ言語として開発された。より具体的には、UNIXの記述言語として開発された。BCPLを参考に開発されたとされるが、実際には殆ど共通点はない。CPLとはもちろん、現実にBCPLと似てはいない。文の構造の表現、文の区切り、注釈文の書き方すら共通性がない。
 FORTRANの頃から存在する、どんな言語にも共通的にありそうな表現の他には、ビット演算の演算子程度しか共通点が見られない。
 BがBCPLから引き継いだものは、言語仕様ではなく、哲学のみであった。それは、CPL→BCPLで仕様化された「アセンブリ言語的ななにか」である。CPL→BCPLのうちのBの部分ということもでき、Bの言語名がBであるのは、おそらく偶然であろうが、ある意味必然であったのかも知れない。
 BCPLからの影響は少ないが、PL/Iからの影響は様々確認できる。少なくともBCPL→Bの段階で、BとCPLの間には断絶が存在する。

B→C
 CはBの後継として開発された。Cの特徴は、CPL→BCPLの段階で失われたデータ型の概念を再導入したことにある。とはいえその仕様はCPLではなく、ALGOL68やPL/Iの影響を強く受けている。
 まず、型がなくても無理なく動作させるためには、いくつかの条件が必要である。例えば、アドレス(ポインター)とデータは同じ単位でなければならない。アドレスを1つ足したら、次のデータを指す、といった動作が求められる。
 当時、BやCのターゲットだったPDP-7やPDP-11は16ビットマイクロプロセッサーが使われており、データはワード単位だったが、アドレッシングはバイト単位であった。こういった設計は、現在のコンピューターも同じである。
 このような環境において型を無くすためには、どちらかに合わせる(具体的には大きな方に合わせる)ことになり、メモリーの利用効率が落ちる。Cは、高級言語の方向性ではなく、アセンブリ言語の置き換えとして計算機の仕様にあわせた処理を書くことが指向されたため、データ型を導入することになったのである。
 データ型のないBは同じくデータ型がないBCPLの頭文字、データ型のあるCはデータ型があるCPLの頭文字でありBCPLの2文字目から取られた、というのが通説ではあるが、これについては正確なところは定かではない。
 また、CはALGOL68の影響も強く受けており、都合、CPL→BCPL→B→Cという沿革は一つの表面的な出来事であり、現実には他の影響を色濃く反映しているのである。かくして、CPLとCは似ても似つかないものとなっている。

BCPL→C
 Cは、BCPL→Bで受け継がれたBCPLの「データ型がない」という特徴を捨てたことになる。これで、見た目においては、CはBCPLの影響を一つも残していないことになるが、実際はそうでもない。
 CPL→BCPLの段階で、BCPLはデータ型を捨てると共に「アセンブリ言語的ななにか」を仕様とした。これはCでも仕様の基本的な柱となっており、データ型が導入されても変わっていない。
 BCPLから生まれた言語的な哲学は、Bを経て、Cに至ってもなお健在である。

再検索