C言語

出典: フリー百科事典『ウィキペディア(Wikipedia)』

C言語
パラダイム 手続き型
設計者 デニス・リッチー
開発者 ベル研究所
型付け 弱い静的型付け
主な処理系 GCCMSVC
影響を受けた言語 B言語ALGOL
アセンブリ言語Pascal
影響を与えた言語 awkcshC++Objective-C
D言語JavaJavaScript
  

C言語(しーげんご)は、1972年AT&Tベル研究所デニス・リッチー (Dennis M. Ritchie) が主体となって作ったプログラミング言語である。英語圏では単に Cと呼称されており、日本でも著作によっては C と記述される。

UNIXの移植性を高めるために開発された経緯から、オペレーティングシステムカーネル向けの低レベルな記述ができることを特徴としており、移植用アセンブラと呼ばれることもある。

目次

[編集] 特徴

Cは手続き型言語であり、コンパイラ言語として設計された。Cは、自由度、実行速度、コンパイル速度などを追求したが、代わりにコンパイル後のコードの安全性を犠牲にもしているので、コンピュータ寄りの言語仕様になっている。

  • アマチュアからプロのエンジニアまで、非常にプログラマ人口が多い。Cは正負の両面含めてコンピュータの世界に大きな影響を及ぼしているが、最大の原因はそのプログラマ人口の多さであると言われている。
  • パソコンはもちろんのこと、組込み用マイコンから大型コンピュータまで、Cを使用できるプラットホームが多様である。また、仕様規格・派生言語も多い。
  • 採用されているソフトウェア分野が広い。極論すれば、Cの採用が最適である分野は一つもなく各々の分野に特化した言語に劣ると言える。しかし、あらゆる分野に対してある程度の言語適性があり現実的な選択肢としてよく用いられる。発祥の地であるUNIXの場合、大抵のことがスクリプト言語マクロプロセッサフィルタで処理できるため、Cを使うのはある意味最後の手段であって、うまく分野の棲み分けができていた面があるのだが、幅広い領域に移植された結果、適切でない分野にCが使われている場面もある。
  • 低水準な記述が出来る高級言語とも、高級言語の顔をした低級言語とも言われる。また、コーディング上の“自由度”が非常に高い。そのため良くも悪くも“何でも出来てしまう”パワフルさは多くのプログラマの支持を集める一方で、単なる無秩序無分別な下品さと揶揄されることもありセキュリティー脆弱性や潜んだバグによる想定外の動作、コンパイラによる最適化の難しさ(そのためCはコンパイラ言語として決して高速ではない)といった欠点の原因ともなっている。
  • 商用・非商用を問わずコンパイラやC向けのエディタが豊富で開発環境が整備しやすい。

Cの主な特徴は以下の通りである(歴史的な経緯からBASICPascalと比較されることが多い)。

[編集] 自由度

  • 行番号を採用せず文の区切りを区切り記号 ; セミコロン で表し、改行文字にも空白にもトークンの区切りとしての意味しか持たせない「フリーフォーマット」という形式を採用している。
    • 記述作法について、しばしば議論の対象となり、本も多数出版されている。
    • IOCCCのような試みはCの柔軟性を負の方向に追求し、難解性を昇華させた一種のアートといえる。
  • ALGOLの思想を受け継いで構造化をサポートしており、手順を入れ子構造で示して見通しの良い記述をすることができる。原理的に無条件分岐goto文)を使用する必要が軽減されるため、スパゲティプログラムと呼ばれるような読みにくいプログラムになりにくい。
  • モジュール化ファイルを単位として可能。モジュール内だけで有効な名前を使うことが出来る。(スコープ)
  • プログラムを関数戻り値つきのサブルーチン)に分離できる。関数の中では独立した変数が使用でき、データの流れがブロックごとに完結しデバッグが容易になる。また、多人数での共同開発の際にも変数名の衝突が回避できる(これらもCで始まったアイデアではない)。なおCではメインルーチンも関数の一つ(main関数)となっているため、プログラム中で再帰的にmain関数を呼ぶことも可能。(C++では不可能)
  • OS記述言語として設計されたため、高級言語であるがアセンブラ的な低レベルの操作ができる。ポインタ演算、ビットごとの論理演算、シフト演算などの機能を持ち、ハードウェアに密着した処理を効率よく記述できる。これはOSやドライバなどを記述する上では便利であるが、注意深く利用しないと発見しにくいバグの原因となる。(このため、後継言語にはポインタ演算の機能を省いているものもある)
  • 配列とポインタの宣言は別物であるが、配列操作の実体はポインタ演算である。
    • ポインタを配列表記でアクセスすることや、配列をポインタ表記でアクセスすることができる。(糖衣構文と呼ばれる)

[編集] アセンブラとのインターフェース

  • 多くの処理系がインラインアセンブラを搭載しているほか、アセンブラで出力したオブジェクトとのリンクが容易になっている。これにより速度が要求される部分だけをアセンブリ言語で記述するということが容易に行えることが多い。もっとも、アセンブラとのインターフェースに統一された仕様はなくCPUやOSなどが同一であっても移植性は低い。
  • RISC CPUには、アセンブラでの記述が難しく、Cでの記述を前提とするものも多い。

[編集] コンパイラ仕様

  • コンパイラの処理が1パスで済む仕様になっている。具体的には、変数はその使用より前に宣言をする必要があり、関数は宣言がないとint型が適用されるなど。(後継言語では記述によって先読みが必要になりうる)
  • 標準でマクロ記述やコンパイル条件の指定が出来るプリプロセッサを持ち(C Preprocessor)、その名の通りコンパイラの処理の前に実行される。

[編集] 処理系の簡素化

現在のPCではこれらの脆弱性対策を施しても実行速度の低下は殆どの場合において無視できる程度であるため、そのような環境でCを使う者からは欠点・不要などと言われることが多い。

配列参照時の自動的な添字のチェックをしない
このため、バッファオーバーフローを簡単に実現できる。標準ライブラリにはバッファオーバーフローを考慮していない関数があり、かつ多用されがちなため、しばしば脆弱性の原因となる。
文字列を格納するための特別な型が存在しない
文字列にはchar型の配列やポインタを利用する。言語仕様上に特別な扱いはないが、ナル文字(ヌル文字、'\0')を終端とする文字列表現を使い、その操作をする標準ライブラリ関数が提供されている。これは実質的にメモリ領域のポインタアクセスそのもので、バッファオーバーランの元凶の一つとなっている。後継言語では文字列処理が特に強化されている場合が多い。
自動変数の自動的な初期化をしない
自動変数(静的でないローカル変数)は変数の中でも最も頻繁に用いられる。初期化しない変数の初期値は不定(その変数のアドレスに元から入っていた値)である。変数宣言・初期化の仕様による制限から、変数宣言の時点で初期化せず後で代入することで初期化に代えることが日常的で、誤って不定の値の変数を読み出すバグを作り込みやすい。なお自動変数の自動とはスタック上に自動的に変数の領域が確保されるという意味であり、自動的な初期化の自動とは異なる意味である。

[編集] その他

  • 文字の大文字・小文字が区別される。
  • 入出力を含め、実行時の言語独自のランタイムシステムの存在をほとんど期待しない。ほとんどの機能をC自身で書かれたライブラリが提供する。すなわち、I/O関係は言語の外にある。このことは、Cが機種依存性が低い、I/O関係ライブラリをのぞいた部分は移植性(ポータビリティ)が高いことを意味する。さまざまな機種があるUNIXの世界でCが普及した理由の一つである。
  • プログラムの実行に必要とするハードウェア資源が、(アセンブラよりは多いが)他の高級言語より少なくてすむため、現在さまざまな電化製品等の組み込みシステムにも使用されている。

[編集] コード例

Hello worldプログラム

CのHello worldプログラムには、入門書によって趣が異なるいくらかのバリエーションが存在する。Cライブラリのprintf関数を利用したものが最も一般的で、以下のようなものである。

#include <stdio.h>
 
int main(void)
{
  printf("Hello, World!\n");
  return 0;
}

なお、printf関数は変数や書式化された文字列などが表示できる比較的高機能な出力関数であり、Hello worldプログラムにはオーバースペックであると言える。Cライブラリには固定文を表示するためのputs関数が用意されており、これを用いる入門書もある。

#include <stdio.h>
 
int main(void)
{
  puts("Hello, World!");
  return 0;
}

また、Cの仕様から言えば、puts関数に渡している引数は文字列ではなく文字列へのポインタである。よって、入門者にとって難関と言われるポインタを早くから理解させるために、Hello Worldプログラムからポインタを使ったコードを例示する入門書もある。

#include <stdio.h>
 
int main(void)
{
  char *str = "Hello, World!";
  puts(str);
  return 0;
}

さらには、文字列をchar型へのポインタではなく配列として扱うことを好み、以下のようなコードを例示する入門書もある。

#include <stdio.h>
 
int main(void)
{
  char str[] = "Hello, World!";
  puts(str);
  return 0;
}

このように、入門書によって多様なHello World!プログラムが見られるのも、自由度の高いCならではの現象といえよう。

[編集] 主な制御構造

[編集] 主な標準ライブラリ関数

詳細は標準Cライブラリを参照。

[編集] 歴史

[編集] 誕生

Cは、AT&Tベル研究所のケン・トンプソン (Ken Thompson) が開発したB言語を改良して作られた。

1973年、トンプソンとUNIXの開発を行っていたデニス・リッチー (Dennis MacAlistair Ritchie) はBを改良し、実行可能な機械語を直接生成するCコンパイラを開発した。UNIXは大部分がCによって書換えられ、後にCは広く利用されるようになった。

[編集] UNIX環境とC

アセンブラとの親和性が高いためにハードウェアに密着したコーディングがやりやすかったこと、言語仕様が小さいためコンパイラの開発が楽だったこと、小さな資源で動く実行プログラムを作りやすかったこと、UNIX環境での実績があり、後述のK&Rといった解説文書が存在していたことなど、さまざまな要因からCは業務開発や情報処理研究でのシェアを増やしていった。特にメーカー間でOS・CPUなどのアーキテクチャが違うUNIX環境では再移植の必要性がしばしば生じて、プログラムをCで書いて互換性を取ることが標準となった。

[編集] パソコンの歴史とC

1980年代にROM-BASICを搭載するパーソナルコンピュータ(パソコン)が普及してBASICで初めてプログラミングに触れるプログラマが世界的に多数を占めるようになった。これらのパソコンの主流がROM-BASIC搭載機からMS-DOS実行機に移った1980年代後半には、当時パソコン向けのコンパイラとしては安価な2万円前後のコンパイラが存在したことなどから、ユーザーが急増した。8ビットや8086系のパソコンへの移植は、ポインタなどに制限や拡張を加えることで解決していた。

[編集] 現在のC

1990年代中盤以降は、最初に学ぶプログラミング言語としても主流となった。GUI環境の普及とオブジェクト指向の普及によりC++JavaVisual Basic、各種スクリプト言語のシェアも増加したため、広く利用されるプログラミング言語の数は増える傾向にあるが、現在でもCは業務用開発やフリーソフトウェア開発、C++などの実装が困難な組み込みなどの小規模のシステムで、幅広く利用されている。

[編集] Cの規格

[編集] K&R

1978年に出版された、リッチーとカーニハンの共著である「The C Programming Language (いわゆる「K&R」)」は、その後標準化がなされるまで実質的なCのリファレンスとして使用された。しかし、「The C Programming Language」の記述にはいくつか曖昧な部分が存在していた。そのため、Cが普及するに従い、互換性のない処理系が数多く誕生することとなった。

[編集] C89

そこで、ISOANSIは協同でCの規格の標準化を進め、1989年12月にANSIのANSI X3.159-1989, American National Standard for Information Systems -Programming Language-C が、1990年12月にISOの INTERNATIONAL STANDARD ISO/IEC 9899 : 1990(E) Programming Languages-C が発行された。このISO Cを特にC90と呼ぶことがあるが、内容はC89と同一である。

日本では、これを翻訳したものが日本工業規格『JIS X3010-1993 プログラム言語C』として、1993年10月に制定された。

最大の特徴は、C++と同様の関数プロトタイプを導入して引数の型チェックを強化したことと、voidやenumなどの新しい型を導入したことである。一方、「処理系に依存する」とするに留めた部分も幾つかある(int型のビット幅、char型の符号、ビットフィールドのエンディアン、シフト演算の挙動、構造体などへのパディング、等)。

  • 型の大きさは厳密に決められてはおらず、バイト数はsizeof演算子で取得し、最大最小値はlimits.hで参照することとされている。もっとも、多くの処理系ではchar型は8ビット、short型は16ビット、long型は32ビットである。またAPIなどの呼び出しには、ヘッダでBYTEやWORDなどとtypedefした型を使用して回避するのが一般的になっている。char型以外で符号を明示しない場合はsignedになる。

規格上には、コメントのネストや、BCPL・C++タイプの一行コメント(//)は無いが、オプションでサポートした処理系も多い。

[編集] C95

主として英語圏での利用を想定して制定されたC89に対して、主に国際化のためワイド文字版ライブラリを追加したAmendment1が1995年に発行された。

[編集] C99

1999年12月には、ISOで規格の改定が行われ、C++の機能のいくつかを取り込むことを含めた機能拡張がなされ INTERNATIONAL STANDARD ISO/IEC 9899 : 1999(E) Programmin Language-C (Second Edition) が制定された。この版のCの標準規格を通称としてC99と呼ぶ。

日本では、日本工業規格版として『JIS X 3010-2003 プログラム言語C』がある。

[編集] MISRA-C

正式名称は“Guidelines for the Use of the C Language in Vehicle Based Software”。欧州の自動車業界団体MISRA (Motor Industry Software Reliability Association)によって発表された、車載用ソフトウェアを対象としたCによるコーディングガイドライン。

[編集] 主なC処理系

現在はC/C++兼用となっている処理系が多い。

[編集] x86系のみ対応するもの

MS-C
Microsoft Visual C++の前身。
Quick-C
MS-Cの廉価版の位置づけ。
Borland C, Turbo C
コンパイルが速い。
Digital Mars C
Lattice Cを起源とするx86用のC/C++コンパイラで、フリーソフト版もある。
Watcom C
PC/AT互換機用。

[編集] x86系以外に対応するもの

GNUコンパイラコレクション (GCC)
多様なCPUに対応する。
CodeWarrior
Macintosh家庭用ゲーム機など。
LSI C
8080Z80用のLSI C-80(セルフ版・クロス版。現在はクロス版のみ)と、8086用のLSI C-86がある。8086では機能限定(スモールモデルのプログラムしか開発できず、デバッガがない)の「試食版」がフリーソフトで公開され、広く使われた。試食版は『C MAGAZINE』(2006年4月号で休刊)の付録フロッピーディスクCD-ROMにも収録されていた。
High C
元はx86向けでPC/AT互換機用だが80386のネイティブモードに対応したためFM TOWNSでも標準開発環境として使用された。現在は各社RISC向け。
Hitech-C
Z80PICなど。
IAR-C
新旧の組み込み向けCPU各種を広くカバーする。現在は統合開発環境EW・SWに移行。
C compiler PRO68K
X68000。通称XC。X-BASICをコンパイルすることも可能だった。
BDS-C
CP/M(8080・Z80)用。

[編集] 関連するプログラミング言語

[編集] 先祖

BCPL
MULTICSで作成された高級言語。
B言語
初期のUNIXで作成されたインタプリタ方式の高級言語。BCPLを元に作られ、Cの原型となった。

[編集] 拡張

C++
Cを拡張してオブジェクト指向化したもの。現在は互換性は失われている。
Objective-C
Cを拡張してオブジェクト指向化したもの。CにSmalltalkのオブジェクトシステムを取り付けたような設計で、互換性は保たれている。Cからの拡張部分がC++と干渉しないため、C++と混在した記述が可能。
Cg
CをGPUでのグラフィック処理用に特化させたもの。
SystemC
Cをハードウェア記述言語に特化させたもの。

[編集] 関連

Pascal
教育向けの構造化言語の一つで、Cより先行して普及した。
Java
仮想マシン方式のオブジェクト指向言語。

[編集] 後継

C#
仮想マシン方式のオブジェクト指向言語。C・C++との互換性はない。
D言語
Cの後継を目指している言語の一つ。C・C++との互換性はない。

[編集] その他

サーティファイが実施しているC言語プログラミング能力認定試験がある。

[編集] 参考文献

プログラミング言語C; Brian Kernighan、Dennis M. Ritchie著; 石田晴久訳 第2版; ISBN 4-320-02692-6; 共立出版株式会社 1994.
K&R として知られているThe C Programming Language の邦訳。Cの入門書。

[編集] 外部リンク

ウィキブックス
ウィキブックスC言語関連の教科書や解説書があります。