C言語
出典: フリー百科事典『ウィキペディア(Wikipedia)』
パラダイム: | 手続き型 |
---|---|
設計者: | デニス・リッチー |
開発者: | ベル研究所 |
型付け: | 弱い静的型付け |
主な処理系: | GCC、MSVC |
影響を受けた言語: | B言語、ALGOL、 アセンブリ言語、Pascal |
影響を与えた言語: | awk、csh、C++、Objective-C、 D言語、Java、JavaScript |
C言語(シーげんご)は、1973年にAT&Tベル研究所のデニス・リッチー (Dennis M. Ritchie) が主体となって作ったプログラミング言語である。
本来の名称はアルファベット一文字の「C」であるが、まぎらわしいため通常はC言語 (The C Programming Language) と呼ぶ。
UNIXの移植性を高めるために開発された経緯から、オペレーティングシステムカーネル向けの低レベルな記述ができることを特徴としており、移植用アセンブラと呼ばれることもある。
目次 |
[編集] 特徴
C言語は手続き型言語であり、コンパイラ言語として設計された。C言語は、自由度、実行速度、コンパイル速度などを追求したが、代わりにコンパイル後のコードの安全性を犠牲にもしているので、コンピュータ寄り、あるいは玄人好みとも言える言語仕様になっている。「扱いは難しく危険だが一旦使いこなせば非常に使い勝手が良くなる、よく切れる刃物のようなツール」という風に例えられることがある。
仕様の全貌を把握するのが難しく、アセンブラに熟知する人は、C言語よりアセンブラの方を好む人も多い。コードサイズも一般にアセンブラよりは大きくなる。
C言語の主な特徴は以下の通りである。(歴史的な経緯からBASICやPascalと比較されることが多い。)
[編集] 自由度
- 行番号を採用せず文章の区切りを区切り記号 ; セミコロン で表し、改行文字にも空白にもトークンの区切りとしての意味しか持たせない「フリーフォーマット」という形式を採用している。
- 記述作法について、しばしば議論の対象となり、本も多数出版されている。
- IOCCCのような試みはC言語の柔軟性を負の方向に追及し、難解性を昇華させた一種のアートといえる。
- ALGOLの思想を受け継いで構造化をサポートしており、手順を入れ子構造で示して見通しの良い記述をすることができる。原理的に無条件分岐(goto文)を使用する必要が軽減されるため、スパゲティプログラムと呼ばれるような読みにくいプログラムになりにくい。
- モジュール化がファイルを単位として可能。モジュール内だけで有効な名前を使うことが出来る。(スコープ)
- プログラムを関数(戻り値つきのサブルーチン)に分離できる。関数の中では独立した変数が使用でき、データの流れがブロックごとに完結しデバッグが容易になる。また、多人数での共同開発の際にも変数名の衝突が回避できる(これらもC言語で始まったアイデアではない)。なおC言語ではメインルーチンも関数の一つ(main関数)となっているため、プログラム中で再帰的にmain関数を呼ぶことも可能。(C++では不可能)
- OS記述言語として設計されたため、高級言語であるがアセンブラ的な低レベルの操作ができる。ポインタ演算、ビットごとの論理演算、シフト演算などの機能を持ち、ハードウェアに密着した処理を効率よく記述できる。これはOSやドライバなどを記述する上では便利であるが、注意深く利用しないと発見しにくいバグの原因となる。(このため、後継言語にはポインタ演算の機能を省いているものもある。)
- 配列とポインタの宣言は別物であるが、配列操作の実体はポインタ演算である。
- ポインタを配列表記でアクセスすることや、配列をポインタ表記でアクセスすることができる。(糖衣構文と呼ばれる。)
[編集] アセンブラとのインターフェース
- 多くの処理系がインラインアセンブラを搭載しているほか、アセンブラで出力したオブジェクトとのリンクが容易になっている。これにより速度が要求される部分だけをアセンブリ言語で記述するということが容易に行えることが多い。もっとも、アセンブラとのインターフェースに統一された仕様はなくCPUやOSなどが同一であっても移植性は低い。
- RISC CPUには、アセンブラでの記述が難しく、C言語での記述を前提とするものも多い。
[編集] コンパイラ仕様
- コンパイラの処理が1パスで済む仕様になっている。具体的には、変数はその使用より前に宣言をする必要があり、関数は宣言がないとint型が適用されるなど。(後継言語では記述によって先読みが必要になりうる。)
- 標準でマクロ記述やコンパイル条件の指定が出来るプリプロセッサを持ち(Cpp)、その名の通りコンパイラの処理の前に実行される。
[編集] 処理系の簡素化
現在の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言語を改良して作られた。B言語よりも進んでいるという意味を込めてC言語と命名された。
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++、Java、Visual Basic、各種スクリプト言語のシェアも増加したため、広く利用されるプログラミング言語の数は増える傾向にあるが、現在でもC言語は業務用開発やフリーソフトウェア開発、C++などの実装が困難な組み込みなどの小規模のシステムで、幅広く利用されている。
[編集] C言語の規格
[編集] K&R
1978年に出版された、リッチーとカーニハンの共著である「The C Programming Language (いわゆる「K&R」)」は、その後標準化がなされるまで実質的なC言語のリファレンスとして使用された。しかし、「The C Programming Language」の記述にはいくつか曖昧な部分が存在していた。そのため、C言語が普及するに従い、互換性のない処理系が数多く誕生することとなった。
[編集] C89
そこで、ISOとANSIは協同で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 X3010-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系以外に対応するもの
-
- GCC - 多様なCPUに対応する。
- CodeWarrior - Macintosh、家庭用ゲーム機など。
- LSI-C - 8080・Z80用のLSI-C80(セルフ版・クロス版。現在はクロス版のみ)と、8086用のLSI C-86がある。8086では機能限定(スモールモデルのプログラムしか開発できず、デバッガがない)の「試食版」がフリーソフトで公開され、広く使われた。試食版は『C MAGAZINE』(2006年4月号で休刊)の付録フロッピーディスクやCD-ROMにも収録されていた。
- High C - 元はx86向けでPC/AT互換機用だが80386のネイティブモードに対応したためFM TOWNSでも標準開発環境として使用された。現在は各社RISC向け。
- Hitech-C - Z80、PICなど。
- IAR-C - 新旧の組み込み向けCPU各種を広くカバーする。現在は統合開発環境EW・SWに移行。
- C compiler PRO68K - X68000。通称XC。X-BASICをコンパイルすることも可能だった。
- BDS-C - CP/M(8080・Z80)用。
[編集] 関連するプログラミング言語
- 先祖
- 拡張
- C++ - Cを拡張してオブジェクト指向化したもの。現在は互換性は失われている。
- Objective-C - Cを拡張してオブジェクト指向化したもの。CにSmalltalkのオブジェクトシステムを取り付けたような設計で、互換性は保たれている。Cからの拡張部分がC++と干渉しないため、C++と混在した記述が可能。
- Cg - CをGPUでのグラフィック処理用に特化させたもの。
- SystemC - Cをハードウェア記述言語に特化させたもの。
- 関連
- 後継
[編集] 参考文献
K&R として知られているThe C Programming Language の邦訳。C言語の入門書。
- プログラミング言語C; Brian Kernighan、Dennis M. Ritchie著; 石田晴久訳 第2版; ISBN 4-320-02692-6; 共立出版株式会社 1994.
[編集] 外部リンク
- The Development of the C Language; Dennis M. Ritchie著 - C言語がどのように開発されたかがわかる文書
- プログラミング言語 C の新機能: C99 で追加された新機能について詳しく書かれている。