「C言語」の版間の差分
C言語に関数型の側面があるとかいう、まるでおかしな記述を削除 |
Goldensundown2 (会話 | 投稿記録) 冒頭文 |
||
(同じ利用者による、間の3版が非表示) | |||
25行目: | 25行目: | ||
{{プログラミング言語}} |
{{プログラミング言語}} |
||
{{Wikibooks|C言語|C言語}} |
{{Wikibooks|C言語|C言語}} |
||
'''C言語'''(シーげんご)は、幅広い分野で多目的に用いられている古典的かつ世界で最も普及した[[プログラミング言語]]である。[[機械語]]コードとの対応が比較的容易に推測できるハードウェア寄りの[[低水準言語]]であり、基幹系システムや動作環境の厳しいソフトウェアの開発に用いられる事が多い。パソコン、[[スーパーコンピュータ|スパコン]]から機器[[組込システム]]、[[マイクロコントローラ]]まで、C言語のコード資産が蓄積されている環境は多岐に渡る。言語仕様としてはフロー制御とスコープおよび構造体などの書式を持ち、[[構造化プログラミング|構造化されたプログラミング]]が可能である。 |
|||
'''C言語'''(シーげんご)は、[[1972年]]に[[ベル研究所|AT&Tベル研究所]]の[[デニス・リッチー]]が主体となって開発した[[プログラミング言語]]である。英語圏では単に '''C''' と呼んでおり、日本でも文書や文脈によっては同様に C と呼ぶことがある。 |
|||
C言語は、1972年に[[ベル研究所|AT&Tベル研究所]]所属の計算機科学者[[デニス・リッチー]]によって制作された。開発元英語圏での名称はアルファベット一文字の「'''C'''」であり、その由来は同僚が作ったB([[B言語]])の次であるからというものだった。当初は[[UNIX|Unix]]用のプログラム開発が主な用途であったが、その利便性が注目された事で学術機関からソフトウェア業界へも広まった。1980年代に入ると様々な[[コンピュータアーキテクチャ]]に適用されて人気を博し、プログラミング言語の中心的存在となった。それに伴い数多くの開発元からC言語[[コンパイラ]]が販売されたので、1989年に[[米国国家規格協会|ANSI]]がコンパイラ規格の標準化を行い、その後は[[国際標準化機構|ISO]]によってもC言語開発環境の規格が制定された。 |
|||
==特徴== |
==特徴== |
2019年1月26日 (土) 03:29時点における版
パラダイム | 手続き型 |
---|---|
登場時期 | 1972年 |
設計者 | デニス・リッチー |
開発者 | ベル研究所 |
最新リリース | ISO/IEC 9899:2011/ 2011年12月8日 |
型付け | 弱い静的型付け |
主な処理系 | GCC, Clang, Visual C++ |
方言 | C89, C99, C11 |
影響を受けた言語 | B言語、ALGOL、アセンブリ言語、pascal |
影響を与えた言語 | awk、csh、C++、Objective-C、D言語、Java、JavaScript、Limbo |
C言語(シーげんご)は、幅広い分野で多目的に用いられている古典的かつ世界で最も普及したプログラミング言語である。機械語コードとの対応が比較的容易に推測できるハードウェア寄りの低水準言語であり、基幹系システムや動作環境の厳しいソフトウェアの開発に用いられる事が多い。パソコン、スパコンから機器組込システム、マイクロコントローラまで、C言語のコード資産が蓄積されている環境は多岐に渡る。言語仕様としてはフロー制御とスコープおよび構造体などの書式を持ち、構造化されたプログラミングが可能である。
C言語は、1972年にAT&Tベル研究所所属の計算機科学者デニス・リッチーによって制作された。開発元英語圏での名称はアルファベット一文字の「C」であり、その由来は同僚が作ったB(B言語)の次であるからというものだった。当初はUnix用のプログラム開発が主な用途であったが、その利便性が注目された事で学術機関からソフトウェア業界へも広まった。1980年代に入ると様々なコンピュータアーキテクチャに適用されて人気を博し、プログラミング言語の中心的存在となった。それに伴い数多くの開発元からC言語コンパイラが販売されたので、1989年にANSIがコンパイラ規格の標準化を行い、その後はISOによってもC言語開発環境の規格が制定された。
特徴
- 汎用性が高い。プログラムの自由度や、目的に応じた拡張が容易であるため、オペレーティングシステムやアプリケーションソフトウェア・ファームウェアの記述、デバイスドライバー開発や機械制御など、あらゆる分野に適応している。
- 対応する機器の範囲が広い。パーソナルコンピュータはもちろん、自動車や家電の組み込み用マイコンからスーパーコンピュータまで、C言語を使用できるハードウェアは多様である。多目的性と、対応機器の多彩さのため、「コンピュータを使ってやること」は大抵、C言語で対応可能である。
- 商用・非商用を問わず、採用ソフトウェア分野が広い。作成や使用のための補助的なソフトウェアが豊富である。
- 機械語に変換するソフトなどの開発環境がCPUに付属していたり無償だったりするものもあるため、ライセンス料の支払いをしなくても使用が始められる。
- 開発時期が古く、文法に機械語の影響が強く、複雑である。この欠点を補正するためのちに開発された新言語に比較し、記述することが多く、面倒で習得しにくい低水準言語である。
- アマチュアからプロ技術者まで、プログラマ人口が多く、プログラマのコミュニティが充実している。C言語は使用者の多さから、正負の両面含め、プログラミング文化に大きな影響を及ぼしている。
- 言語の適用先であるUNIXの場合、大抵のことがスクリプト言語・マクロプロセッサやフィルタやそれらの組み合わせで処理できるため、うまく分野の棲み分けができていた面があった。仕様規格・派生言語も多く幅広い領域への移植の結果、適切でない分野にC言語が使われている場合もある。
- C言語は手続き型言語である。コンパイラ言語とOSを念頭に設計している。アセンブラのコードと同じことを実現できるようなコンピュータ寄りの言語仕様になっている。低水準な記述が出来る高級言語とも、高級言語の顔をした低級言語と言うことがある。
- Cコンパイラは、移植の容易性、自由度、実行速度、コンパイル速度などを追求した。代わりにコンパイル後のコードの安全性を犠牲にしている。セキュリティーの脆弱性や潜んだバグによる想定外の動作、コンパイラによる最適化の難しさがある。最適化するとコンパイル速度が遅くなるなどの欠点が生じることがある。自動車分野ではMISRA CというC言語の部分集合(subset)を定義して、C言語の弱点を補っている。
- UNIXおよびCコンパイラの移植性を高めるために開発してきた経緯から、オペレーティングシステムカーネルおよびコンパイラ向けの低水準記述ができる。
自由度
- 文の区切りを終端記号 セミコロン「
;
」で表し、改行文字にも空白にもトークンの区切りとしての意味しか持たせない「フリーフォーマット」という形式を採用している。- 記述作法についてはしばしば議論の対象となり、書籍も多数出版されている。
- ALGOLの思想を受け継いで構造化に対応している。手順を入れ子構造で示して見通しの良い記述をすることができる。原理的に無条件分岐(
goto
)を使用する必要はなく、MISRA Cでは当初goto文を禁止していた。goto文を使わなければ、スパゲティプログラムと呼ばれる読みにくいプログラムになりにくい。 - モジュール化がファイルを単位として可能。モジュール内だけで有効な名前を使うことが出来るスコープを持っている。
- プログラムを戻り値つきのサブルーチンに分離できる。C言語ではこれを関数と呼び、関数内のプログラムコードでは、独立した変数が使用できる。これにより、データの流れがブロックごとに完結するのでデバッグが容易になり、また関数の再帰呼び出しも可能となる。また、多人数での共同開発の際にも変数名の衝突が回避しやすくなる。なお、C言語ではUNIXのようなOSを前提としたホスト環境と、割り込み制御のようなOSを前提としないフリースタンディング環境とがある。ホスト環境では、プログラム開始直後に実行するプログラム要素を
main
という名前の関数として定義する[1]。プログラム中で再帰的にmain
関数を呼ぶことも可能(C++では不可能[2][3])。フリースタンディング環境では、エントリポイントと呼ばれるアドレスに置かれたコードをプログラムの開始点とするが、それがmain関数である必要はない。なお再帰呼び出しは、スタックオーバフローの原因となるため、MISRA Cでは禁止している。 - システム記述言語として開発されたため、高級言語であるがアセンブラ的な低水準の操作ができる。ポインタ演算、ビットごとの論理演算、シフト演算などの機能を持ち、ハードウェアに密着した処理を効率よく記述できる。これはオペレーティングシステムやドライバなどを記述する上では便利であるが、注意深く利用しないと発見しにくいバグの原因となる。ライブラリ関数は、C言語規格が規定している関数と、OSが規定している関数との間の整合性、棲み分けなどが流動的である。MISRA Cのようないくつかの制約では、C言語規格が規定している関数の妥当性について指摘し、いくつかの関数を利用しないように規定している。
- ソースコードの記述に使う文字集合はANSI-C:1989(ISO/IEC 9899:1990)ではASCIIを標準としている。他のISO 646でも書けるように、3文字利用したトライグラフと呼ばれる表記法も存在する。その後、ISO/IEC 9899:1995 AMDなどでは多バイト対応の拡張を規定している。さらに、その後トライグラフは複数のコードを利用したシステムでしか利用がないため、より分かり易い2文字によるダイグラフを規定している。
アセンブラとのインタフェース
- 多くの処理系がインラインアセンブラを搭載しているほか、アセンブラで出力したオブジェクトとのリンクが容易になっている。これにより速度が要求される部分だけをアセンブリ言語で記述するということが容易に行えることが多い。アセンブラとのインタフェースは#pragma asmなどを用いて局所化を図る努力はあるが、コンパイラごとに定義があり、CPUが同一であっても移植性が低い場合がある。
コンパイラ仕様
- コンパイラの処理が1パスで済む仕様になっている。ANSI-C:1989では宣言のない変数はintを想定することになっていた。ISO/IEC C:1999以降では変数はその使用より前に宣言する必要がある。関数の宣言がないと、戻り値や引数をint型とみなす仕様は、自由な発想を促すプログラミングの視点で好ましいが、型検査・型証明の仕組みが十分にないと不具合の原因になることがある。後継言語では記述によって先読みが必要になりうる。
- マクロ記述やコンパイル条件の指定などが出来る前処理指令が標準化されている。前処理指令の解釈をするプリプロセッサを持っている。プリプロセッサ(preprocessor)は、その名の通りコンパイル処理の前に自動的に実行される。コンパイラの機能として、プリプロセッサを通しただけの段階のソースコードを出力可能になっているものがある。前処理の結果を検査することで、設計者の意図と前処理の結果のずれがないか確認できる。
処理系の簡素化
ホスト環境やプログラムの内容によっては、以下に対して脆弱性対策を施しても実行速度の低下が無視できる程度であることも多く、欠点とみなされることも少なくない。
- 配列参照時の自動的な添字のチェックをしない
- これを要因とする代表的なバグがバッファオーバーフロー(固定長のバッファをはみだして上書きが行われてしまう)である。標準ライブラリにはバッファオーバーフローを考慮していない関数があり、かつ多用されがちなため、しばしば脆弱性の原因となる。また、プログラムにより制御する事で可変長配列を可能にしている。
- 文字列を格納するための特別な型が存在しない
- 文字列にはchar型の配列を利用する。言語仕様上に特別な扱いはないが、ヌル文字(
\0
)を終端とする文字列表現を使い、その操作をする標準ライブラリ関数がある。これは実質的にメモリ領域のポインタアクセスそのもので、固定長バッファに対して、それより長い可変長の文字列を書き込んでしまうことがあり、バッファオーバーランの元凶の1つとなっている。後継言語では文字列処理を特に強化している場合が多い。 - 自動変数の自動的な初期化をしない
- 自動変数(静的でないローカル変数)は変数の中でも最も頻繁に用いられる。初期化されていない変数を参照した場合、値は不定となるが、不定な値へのアクセスは未定義の動作であるので、コンパイラ最適化の過程で想定しない形に改変することもある[4]。変数宣言・初期化の仕様による制限から、変数宣言の時点で初期化せず後で代入することで初期化に代えることが日常的で、誤って不定の値の変数を読み出すバグを作り込みやすい。なお自動変数の自動とは変数の領域の確保と開放が自動であるという意味であり、自動的に初期化されるという意味ではない。
その他
- 文字の大文字・小文字を区別する。
- 入出力を含めほとんどの機能が、C言語自身で書かれたライブラリによって提供される。このことは、C言語の機種依存性が低く、入出力関係ライブラリをのぞいた部分は移植性(ポータビリティ)が高いことを意味する[要出典]。さまざまな機種があるUNIXの世界でC言語が普及した理由のひとつである。
- プログラムの実行に必要とするハードウェア資源が、アセンブラよりは多いが他の高級言語より少なくてすむため、現在さまざまな電化製品などの組み込みシステムでも使用されている。
- 組み込み向けの場合は、プログラミング言語として、アセンブラ以外ではCとC++しか用意されていないことがある。その場合、他のプログラミング言語は、CやC++で書かれた処理系が存在すればコンパイルすることにより利用可能となることもあるが、メモリ制約などで動作しないことがある。
コード例
- Hello worldプログラム
C言語のHello worldプログラムには、ホスト環境を前提とするか、フリースタンディング環境を前提とするかで、方向性が異なる。入門書によって趣が異なるいくらかの方向性が存在する。ホスト環境を前提とする場合には、標準入出力の利用により、動作をすぐに確かめることができる。標準Cライブラリのprintf
関数 (ヘッダーファイルstdio.h
にて宣言) を利用したものを例示する場合、以下のようなものがある。
#include <stdio.h>
int main(void)
{
printf("Hello, world!\n");
return 0;
}
ここでサンプルソース中の「\n
」は改行を表す。なお、printf
関数は変数や書式化された文字列などが表示できる比較的高機能な出力関数である。C言語として可変引数である特殊なmainとprintfを使っていることにより、C言語の関数プログラミングに対する誤解を生む原因にもなっている。
主な制御構造
主な標準ライブラリ関数
歴史
誕生
C言語は、AT&Tベル研究所のケン・トンプソンが開発したB言語の改良として誕生した(#外部リンクの「The Development of the C Language」参照)。
1972年、トンプソンとUNIXの開発を行っていたデニス・リッチーはB言語を改良し、実行可能な機械語を直接生成するC言語のコンパイラを開発した[5]。後に、UNIXは大部分をC言語によって書き換えられ、C言語のコンパイラ自体も移植性の高い実装のPortable C Compilerに置き換わったこともあり、UNIX上のプログラムはその後にC言語を広く利用するようになった。
ちなみに、「UNIXを開発するためにC言語が作り出された」と言われることがあるが、「The Development of the C Language」によると、これは正しくなく、経緯は以下の通りである。C言語は、当初はあくまでもOS上で動くユーティリティを作成する目的で作り出されたものであり、OSのカーネルを記述するために使われるようになるのは後の展開である。
- UNIXの開発当初、Multicsプロジェクトが目指していた高級言語によるOSの開発という目標は見送られた。
- アセンブリ言語でUNIXが作成されると、OS上で動くユーティリティを作成するためのプログラミング言語が必要とされた。
- ケン・トンプソンは、当初Fortranコンパイラを作ろうとしたが、途中で放棄し、新しい言語であるB言語を作成した。
- B言語はインタプリタ言語であったため動作が遅く、B言語でユーティリティを作ることはあまりなかった。(開発者達は、コンパイラなどのユーティリティを「システムプログラム」と呼んでいたが、それらの作成に使われる「システムプログラミング言語」は、OSのカーネルを作成するための言語という意味ではない[6]。)
- B言語の欠点を解消するため、1971年に改良作業を開始した。
- 1972年にC言語のコンパイラができあがり、UNIXバージョン2において、いくつかのユーティリティを作成するために使用された。
UNIX環境とC言語
アセンブラとの親和性が高いために、ハードウェアに密着したコーディングがやりやすかったこと、言語仕様が小さいためコンパイラの開発が楽だったこと、小さな資源で動く実行プログラムを作りやすかったこと、UNIX環境での実績があり、後述の K&R といった解説文書が存在していたことなど、さまざまな要因からC言語は業務開発や情報処理研究での利用者を増やしていった。特にメーカー間でオペレーティングシステムやCPUなどのアーキテクチャが違う UNIX環境では再移植の必要性がしばしば生じて、プログラムをC言語で書いてソースレベル互換[7]を確保することが標準となった。
PCとC言語
1980年代に普及し始めたパーソナルコンピュータ(PC)は当初、8ビットCPUでROM-BASICを搭載していたものも多く、BASICが普及していたが、1980年代後半以降、16ビットCPUを採用しメモリも増えた(ROM-BASIC 非搭載の)PCが主流になりだすと、2万円前後の安価なコンパイラが存在したこともあり、ユーザーが急増した。8ビットや8086系のPCへの移植は、ポインタなどに制限や拡張を加えることで解決していた。
現在のC言語
1990年代中盤以降は、最初に学ぶプログラミング言語としても主流となった。また、90年代中盤にはゲーム専用機(ゲームコンソール)の性能向上とプログラムの大規模化、マルチプラットフォーム展開を受け、開発言語がアセンブラからC言語に移行した。GUI環境の普及とオブジェクト指向の普及により Java、Objective-C、C++、PHP、Visual Basic、などの言語の利用者も増加したため、広く利用されるプログラミング言語の数は増加傾向にある。現在でもJava, C#, C++などC言語派生の後発言語を含めて、C言語は比較的移植性に優れた言語であり、業務用開発やフリーソフトウェア開発、C++などの実装が困難な組み込みなどの小規模のシステムで、幅広く利用されている。
C言語の規格
K&R
リッチーとカーニハンの共著である「The C Programming Language」[8]1978年を出版。その後標準ができるまで実質的なC言語の標準として参照。C言語は発展可能な言語で、この本の記述も発展の可能性のある部分は厳密な記述をしておらず、曖昧な部分が存在していた。C言語が普及するとともに、互換性のない処理系が数多く誕生した。これはプログラミング言語でしばしば起こる現象であり、C言語固有の現象ではない。
C89/C90
そこで、ISO/IEC JTC1と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/IEC規格のほうが章立てを追加しており、その後ANSIもISO/IEC規格にならって章立てを追加した。それぞれC89 (ANSI C89) 及びISO/IEC C90という通称で呼ぶことがある。
日本では、これを翻訳したものを日本工業規格『JIS X3010-1993 プログラム言語C』として、1993年10月に制定した。
最大の特徴は、C++と同様の関数プロトタイプ[9]を導入して引数の型チェックを強化したことと、void
やenum
などの新しい型を導入したことである。一方、処理系に依存するとするに留めた部分も幾つかある(int
型のビット幅、char
型の符号、ビットフィールドのエンディアン、シフト演算の挙動、構造体などへのパディング等)。
16ビット/32ビットCPUの両方に対応できるようにするため、定義しないことを決めている未定義、定義したもののどれにするかを決めていない未規定、処理系ごとに決めて文書化する処理系定義など、CPUとの相性による有利不利が生じないような規定になっている
型の大きさは16ビット/32ビットCPUの両方に対応できるように決めている。バイト数はsizeof
演算子で取得し、最大最小値はlimits.h
で参照することとしている。多くの処理系ではchar
型は8ビット、short
型は16ビットである。int
やlong
はCPUのレジスタの幅などによって決めている。またAPIなどの呼び出しには、ヘッダでBYTE
やWORD
などとtypedef
で定義した型を使用して回避することがある。char
型以外で符号を明示しない場合はsigned
(符号付き)にするかどうかも処理系。
規格上には、BCPL・C++タイプの一行コメント(「//…
」)は無いが、オプションで対応した処理系も多く、gccやClangはGNU拡張-std=gnu89
でサポートしている。
GNU Cコンパイラ や Clang では、-std=c89
(または-ansi
もしくは-std=c90
)をつけることにより、GNU拡張を使わないC89規格に準拠したコンパイルを行うことができる[10]。加えて、-pedantic
をつければ診断結果が出る。商用のコンパイラではWatcom Cコンパイラが規格適合の比率が高いと言われていた。現在Open Watcomとして公開している。
C89には、下記の追加の訂正と追加を行った。
- ISO/IEC 9899/COR1:1994
- ISO/IEC 9899/AMD1:1995 - 英語圏での利用を想定して制定したC89に対して、国際化のためワイド文字版ライブラリを追加した Amendment1 が1995年に発行された。
- ISO/IEC 9899/COR2:1996
C99
1999年12月1日に、ISO/IEC JTC1 SC22 WG14 で規格の改定を行い、C++の機能のいくつかを取り込むことを含め機能を拡張しISO/IEC 9899:1999(E) Programming Language--C (Second Edition)を制定した。この版のC言語の規格を、通称としてC99と呼ぶ。Intel C++ CompilerはC99に完全準拠していると公称している。GNU Cコンパイラ(gcc)はC99にほとんど対応しているが一部未対応部分も残っている[11]。
日本では、日本工業規格 JIS X 3010:2003「プログラム言語C」がある。
主な追加機能:
- 変数宣言がブロックの先頭でなくても良くなった。
- ブール代数を扱うための
_Bool
型が予約語に追加され、標準ライブラリとしてstdbool.h
を追加した。 - 複素数を扱うための
_Complex
型や_Imaginary
型を予約語に追加し、標準ライブラリとして、complex.h
を追加した。 - 64ビット整数値を保持できる
long long int
型の追加。 //
による1行コメント。- インライン関数(
inline
キーワード)。 - 可変長配列(
alloca
関数の代替)[12]。
C99は下記の訂正がある。
- ISO/IEC 9899:1999 Cor. 1:2001(E)
- ISO/IEC 9899:1999 Cor. 2:2004(E)
- ISO/IEC 9899:1999 Cor. 3:2007(E)
C11
2011年12月8日に改定されたISO/IEC 9899:2011(通称 C11)が現在の最新規格である。gccやClangなどが部分的に対応している。改定による変更・追加・削除機能の一部を以下に記述する。
C11はUnicode文字列(UTF-32、UTF-16、UTF-8の各符号化方式)に標準で対応している。そのほか、type-generic
式、C++と同様の無名構造体・無名共用体、排他的アクセスによるファイルオープン方法、quick_exitなどのいくつかの標準関数などを追加した。
また、_Noreturn
関数指示子を追加した。_Noreturn
は従来各処理系毎に独自に追加していた(たとえばgccでは__attribute__((__noreturn__))
)ものを共通化したもので、「呼び出し元に戻ることがない」という特殊な関数についてその特性を示すためにある。return
文を持たない関数という意味ではなく(規格ではreturn
文を持たなくとも、関数の最後の文の実行が終われば制御は呼び出し元に戻る)、この指示が意味するものは、当該の関数、ないしその内部から呼び出している関数の実行中に、必ず_exit
やexecve
を実行したり、例外などで終了する、あるいは、longjmp
による大域ジャンプで抜け出す[13]、継続渡しスタイル変換されたコードである、などのために、絶対に制御が呼び出し元に戻らない、という関数を指示するためにある。そのような関数は、スタックに戻りアドレスを積む通常の呼び出しではなく、スタックを消費しないジャンプによって実行できる。
アラインメント機能、_Atomic
型やC言語ネイティブの原始的なスレッド機能などを省略可能な機能として規格に組み込んだ。また、C99では規格上必須要件とされていた機能のうち、複素数型と可変長配列を省略可能なものに変更した。これらの省略可能な機能はC11規格合致の必須要件ではないので、仮に完全に規格合致の処理系であっても、対応していないかもしれない。C11規格では、省略可能な機能のうちコンパイラがどれを提供しているかを判別するために利用できる、テスト用のマクロを用意している。
これにより、gets
関数は廃止されている。
主なC言語処理系
gcc、clang、Visual C++、C++Builderなど著名な4つがC言語とC++を一つの処理系で対応している。C言語とC++の共通部分を明確にし、二つの言語の違いに矛盾が生じないようにすることが課題になっている。
Linux、Windows、UNIX用
- C++ Builder
- Windows用のx86用C言語・C++のコンパイラ。RAD。前身は DOS、Windows用の Borland C/C++。さらに前身としてTurbo C/C++がある。
- clang
- LLVMをバックエンドとして用いるオープンソースのC言語・C++・Objective-Cコンパイラ。多数のCPUに対応。
- GNUコンパイラコレクション(GCC)
- C/C++以外の言語もサポートし、多数のCPUやオペレーティングシステムに対応、組み込み向けも含む多様な開発に広く使われるオープンソースのコンパイラ。
- Microsoft Visual C++
- Windows系プラットフォーム用のC言語・C++コンパイラ。ANSI C準拠(バージョン2013にてC99ライブラリをほぼ実装したが、規格はサポートされていない)。x86・x64が主だが Xbox 360、Windows CE等向けに PowerPC、ARM、MIPS、Itanium等に対応した版もある。前身としてMS-DOS・Windows用のMicrosoft C Compilerがある。またその廉価版としてQuick Cがあった[14]。
- Intel C++ Compiler
- インテル製のx86・x64用のC言語・C++コンパイラ。Windows・Linux・macOS向けがある。gcc互換。
- Open Watcom C/C++
- Windows・Linux・OS/2・MS-DOS・DOSエクステンダを対象とするx86用C言語・C++コンパイラ。商用だったWatcom C/C++がオープンソース化したもの。
- Portable C Compiler
- gccが普及する以前のUNIXにおける標準的C言語コンパイラ。現在はオープンソース。
- Digital Mars C/C++
- Windows・MS-DOS・DOSエクステンダを対象とする x86用のC言語・C++コンパイラ。無料版もある。ウォルター・ブライト作でDatalight C、Zorland C、Zortech C/C++、Symantec C/C++と変遷している。
組み込み用、8ビット・16ビット・32ビット・64ビットCPU用(クロスコンパイラ)
- GreenHILS C/C++
- 組み込み向けのC言語・C++コンパイラ。 Windows用・Solaris用・Linux用があり、HP/UX用がver4ではあった。
- CodeWarrior C/C++
- 組み込み向けやゲーム機開発向けのC言語・C++コンパイラ。Classic Mac OS用として発祥、かってはWindows用・BeOS用・Palm用もあった。
- ARM C/C++
- ARM CPU用C言語・C++コンパイラ。
- IAR C/C++
- 新旧の組み込み向けCPU各種を広くカバーする。現在は統合開発環境EW・SWに移行。ARM CPU用C言語・C++コンパイラが著名。ARMをコアにした各社のCPUに対応している。
- High C
- 元はx86向けでPC/AT互換機用だが80386のネイティブモードに対応したためFM TOWNSでも標準開発環境、「High C 386」として使用された。現在は各社RISC向け。
- BDS-C
- CP/M(8080・Z80)用のサブセット(整数のみ)のK&R系のC言語コンパイラ。現在はパブリックドメインソフトウェア。
- Hitech-C
- Z80、PICなど。
- Lattice C
- 1980年代に、日本で高い普及率を見せたコンパイラ。解説書も多く出版されていた。日本での発売はライフボート。初期版はマイクロソフトCコンパイラ1.0として発売された。商用利用のできない個人向けの「personal」版も販売されており、これの価格は19,800円であった[15][16]
- LSI C
- 8080・Z80用のLSI C-80(セルフ版・クロス版。現在はクロス版のみ)と、8086用のLSI C-86がある。8086では機能限定(スモールモデルのプログラムしか開発できず、デバッガがない)の「試食版」がフリーソフトで公開され、広く使われた。
関連する主なプログラミング言語
先祖
- ALGOL
- ヨーロッパ生まれのアルゴリズム記述言語。PascalやC言語などに影響を与えたとされる。
- BCPL
- MULTICSで作成された高級言語。
- B言語
- 初期のUNIXで作成されたインタプリタ方式の高級言語。BCPLを元に作られ、Cの原型となった。
継承・拡張・サブセット
- C++
- C言語を拡張してオブジェクト指向化したもの。当初はC言語のスーパーセットだったが、現在は細かい部分において非互換仕様が増えている。
- Java
- C++よりも言語文法レベルでオブジェクト指向を重視した言語。バッファオーバーランなどの危険性が高いポインタといったローレベルな要素を言語文法から排除している。仮想マシン(Java VM, JVM)上で動作する。
- C#
- マイクロソフトが.NET Framework向けに開発した言語。文法はC言語およびC++に近い書式を持ち、Javaと似ている部分も存在するが、機能的にはDelphiがベースとなっている。
- Cg
- C言語をGPU上での3次元コンピュータグラフィックス処理用に特化させたもの(シェーダー言語、シェーディング言語)。NVIDIAによって開発された。
- Cyclone
- C言語の上位互換セキュア実装。ポインタの扱いを厳格化して安全面に配慮して拡張したもの。その他リージョンベースメモリ管理システム、正規表現、タグ付共用体などを追加している。
- Objective-C
- C言語を拡張してオブジェクト指向化したもの。C言語に Smalltalk のオブジェクトシステムを取り付けたような設計で、互換性は保たれている。C言語からの拡張部分がC++と干渉しないため、C++と混在した記述が可能。
- SystemC
- ハードウェア記述言語向けに拡張したもの。書式はC++。EEE 1666-2005。ISO 8866:1991。
- Impulse_C
- ハードウェア記述言語向けに拡張したもの。書式はC。
- Unified Parallel C
- 並列計算向けにC99を拡張して作られた言語。
その他にも、OpenGLシェーダー言語であるGLSL、DirectX(Direct3D)シェーダー言語であるHLSL、OpenCLカーネル記述言語であるOpenCL-Cなど、C言語の文法的特徴を取り入れた派生言語やDSLが多数存在する。
参考文献
2015年現在、初心者向けのイラスト入り入門書やサブルーチンのサンプル集の他、組み込み機器の制御や科学技術計算など目的を特化した専門書なども多数ある。便利な機能の説明はあっても、学習者の水準や目的にあった本を見つけるのは必ずしも容易でない。オープンソースのCコンパイラ、OSも大規模なものがあり、直接読み始めるのは困難になっている。オープンソースのOSの小規模なものから始めるとよい。
- プログラミング言語C
- ブライアン・カーニハン、デニス・リッチー 共著、石田晴久訳、共立出版。
- 「K&R」として知られている「The C Programming Language」の邦訳。入門書ではなく、特にプログラミングそのものが初めてという読者には不適である。初版と2版があり、2版が現在も時折増刷している(邦訳では事情により、原書2版を基とした版には旧版と改訂新版がある。旧版は装丁が緑地で新版は白地である)。標準の制定以前は本書初版を言語仕様の参考文献として扱っていたが、現在は規格表を参照すべきであり、本書の記述は参考にとどめるべきである。
- Cプログラムの落とし穴
- コーニグ、中村明訳、新紀元社
- Cプログラミングで嵌まるところを指摘している。MISRA Cでも参考文献になっている。
- Cパズルブック
- アラン・R. フューアー、田中和明訳、カットシステム
- Cプログラミングの芸当を示し、読み書きを推奨しない例を示している。
脚注
- ^ 他の言語、例えば、BASICやPascalではプログラム開始直後に実行するプログラム要素はサブルーチンや手続きや関数ではない。
- ^ ISO/IEC 14882:2003 3.6.1 「The function main shall not be used within a program.」
- ^ JIS X 3014:2003 3.6.1 「関数mainは、プログラムの中で挙用してはならない。」
- ^ EXP33-C. 未初期化のメモリを参照しない JPCERT/CC、2014年3月25日(2014年8月22日閲覧)。
- ^ Portability of C Programs and the UNIX Systems
- ^ The Evolution of the UNIX Time-sharing Ststem
- ^ http://japan.zdnet.com/glossary/exp/%E3%82%BD%E3%83%BC%E3%82%B9%E3%83%AC%E3%83%99%E3%83%AB%E4%BA%92%E6%8F%9B/?s=4
- ^ 「K&R」という通称がある
- ^ C89においては関数プロトタイプは必須ではない。
- ^ C89規格に準拠しないソースコードをGNU Cコンパイラでコンパイル失敗させるには、
gcc -ansi -pedantic -fstrict-aliasing -Wall -Wextra -Wmissing-declarations -Werror test.c
とすれば良い(→エイリアシング)。 - ^ Status of C99 features in GCC
- ^ 6.19 Arrays of Variable Length
- ^
setjmp.h
を参照。 - ^ “Microsoft Releases C Program Wares, Provides Rebates”. InfoWorld: p. 29. (November 9, 1987)
- ^ 脇英世(監修)、1987、『パソコンの常識事典』、日本実業出版社 pp. 339、342 - 普及率、解説書の多さについて。
- ^ 長沢英夫(編)、1988、『パソコンベストソフトカタログ』、JICC出版局 pp. 201 - Personal版、解説書の多さについて。
外部リンク
- ISO C Working Group
- The Development of the C Language - C言語がどのように開発されたかがわかる文書
- stdio.h on Coding Programmer Page / C Library Reference and Examples - C Reference