コンテンツにスキップ

英文维基 | 中文维基 | 日文维基 | 草榴社区

「C言語」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
C言語に関数型の側面があるとかいう、まるでおかしな記述を削除
編集の要約なし
 
(77人の利用者による、間の136版が非表示)
1行目: 1行目:
{{Infobox プログラミング言語
{{Infobox プログラミング言語
| name = C言語
| fetchwikidata = ALL
| logo =
| onlysourced = false
| caption =
| name = C言語
| file ext =
| released = {{start date and age|1972}}.
| latest release version = ISO/IEC 9899:2024
| paradigm = [[手続き型プログラミング|手続き型]]
| latest release date = {{Start date and age|2024|10|31}}
| released = 1972年
| designer = [[デニス・リッチー]]
| typing = 弱い[[静的型付け]]
| implementations = [[GNUコンパイラコレクション|GCC]], [[Clang]], [[Microsoft Visual C++|Visual C++]], [[Intel C++ Compiler]]
| developer = [[ベル研究所]]
| influenced = [[awk]]、[[csh]]、[[C++]]、[[Objective-C]]、[[Rust (プログラミング言語)|Rust]]、[[D言語]]、[[Java]]、[[JavaScript]]、[[Limbo (プログラミング言語)|Limbo]]
| latest release version = ISO/IEC 9899:2011
| file ext = <code>.c</code>, <code>.h</code>
| latest release date = {{Start date and age|2011|12|08}}
| latest preview version =
| latest preview date = <!-- {{start date and age|YYYY|MM|DD}} -->
| typing = 弱い[[静的型付け]]
| implementations = [[GNUコンパイラコレクション|GCC]], [[Clang]], [[Microsoft Visual C++|Visual C++]]
| dialects = C89, [[C99]], [[C11 (C言語)|C11]]
| influenced by = [[B言語]]、{{lang|en|[[ALGOL]]}}、[[アセンブリ言語]]、{{lang|fr|[[pascal]]}}
| influenced = {{lang|en|[[awk]]}}、[[csh]]、{{lang|en|[[C++]]}}、{{lang|en|[[Objective-C]]}}、[[D言語]]、{{lang|en|[[Java]]}}、{{lang|en|[[JavaScript]]}}、{{lang|en|[[Limbo]]}}
| programming language =
| operating system =
| license =
| website =
| wikibooks =
}}
}}
{{プログラミング言語}}
{{プログラミング言語}}
{{Wikibooks|C言語|C言語}}
{{Wikibooks|C言語|C言語}}
'''C言語'''(シーげんご)は、[[1972年]]に[[ベル研究所|AT&Tベル研究所]]の[[デニス・リッチー]]が主体となって開発した[[プログラミング言語]]である。英語圏では単に '''C''' と呼んでおり、日本でも文書や文脈によっては同様に C と呼ぶことがある。
'''C言語'''(シーげんご、{{lang-en-short|C programming language}})は、[[1972年]]に[[ベル研究所|AT&Tベル研究所]]の[[デニス・リッチー]]が主体となって開発した汎用[[プログラミング言語]]である。英語圏では「C language」または単にCと呼ばれることが多い。[[日本]]でも文書や文脈によっては同様にCと呼ぶことがある。[[制御構文]]などに[[高水準言語]]の特徴を持ちながら、ハードウェア寄りの記述も可能な[[低水準言語]]の特徴も併せ持つ。基幹系システムや、動作環境の資源制約が厳しい、あるいは実行速度性能が要求されるソフトウェアの開発に用いられることが多い。後発の[[C++]]や[[Java]]、[[C Sharp|C#]]など、「C系」と呼ばれる派生言語の始祖でもある{{efn|英語では{{lang|en|C-family}}, {{lang|en|C-style}}, {{lang|en|C-like}}などと呼ばれる。「C系」の定義は明確ではないが、構文がCに類似しているものを指すことが多い。}}


[[米国国家規格協会|ANSI]]、[[国際標準化機構|ISO]]、また[[日本産業規格|JIS]]により言語仕様が標準規格化されている。
==特徴==
<!-- 万人が調べ物に使うwikipediaの特性上、少なくとも冒頭部分は厳密性をある程度犠牲にして「コンパイラとかエディタって、いったい何や?」みたいなプログラムの基礎知識ゼロの人にも配慮をした記述に書き換え -->


== 特徴 ==
* 汎用性が高い。プログラムの自由度や、目的に応じた拡張が容易であるため、[[オペレーティングシステム]]や[[アプリケーションソフトウェア]]・[[ファームウェア]]の記述、[[デバイスドライバー]]開発や機械制御など、あらゆる分野に適応している。
{{雑多な内容の箇条書き|section=1|date=2019年8月}}
* 対応する機器の範囲が広い。[[パーソナルコンピュータ]]はもちろん、自動車や家電の組み込み用マイコンからスーパーコンピュータまで、C言語を使用できるハードウェアは多様である。多目的性と、対応機器の多彩さのため、「コンピュータを使ってやること」は大抵、C言語で対応可能である。
* 商用・非商用を問わず、採用ソフトウェア分野が広い。作成や使用のための補助的なソフトウェアが豊富である。
* 機械語に変換するソフトなどの開発環境がCPUに付属していたり無償だったりするものもあるため、ライセンス料の支払いをしなくても使用が始められる。
* 開発時期が古く、文法に機械語の影響が強く、複雑である。この欠点を補正するためのちに開発された新言語に比較し、記述することが多く、面倒で習得しにくい[[低水準言語]]である。
* アマチュアからプロ技術者まで、プログラマ人口が多く、プログラマのコミュニティが充実している。C言語は使用者の多さから、正負の両面含め、プログラミング文化に大きな影響を及ぼしている。
* 言語の適用先である[[UNIX]]の場合、大抵のことが[[スクリプト言語]]・[[マクロ (コンピュータ用語)#マクロプロセッサ|マクロプロセッサ]]や[[フィルタ (ソフトウェア)|フィルタ]]やそれらの組み合わせで処理できるため、うまく分野の棲み分けができていた面があった。仕様規格・派生言語も多く幅広い領域への移植の結果、適切でない分野にC言語が使われている場合もある。
* C言語は[[手続き型言語]]である。[[コンパイラ|コンパイラ言語]]とOSを念頭に設計している。アセンブラのコードと同じことを実現できるようなコンピュータ寄りの言語仕様になっている。低水準な記述が出来る高級言語とも、高級言語の顔をした低級言語と言うことがある。
* Cコンパイラは、移植の容易性、自由度、実行速度、コンパイル速度などを追求した。代わりにコンパイル後のコードの安全性を犠牲にしている。セキュリティーの脆弱性や潜んだバグによる想定外の動作、コンパイラによる最適化の難しさがある。最適化するとコンパイル速度が遅くなるなどの欠点が生じることがある。自動車分野では[[MISRA C]]というC言語の部分集合(subset)を定義して、C言語の弱点を補っている。
* [[UNIX]]およびCコンパイラの移植性を高めるために開発してきた経緯から、[[オペレーティングシステム]][[カーネル]]およびコンパイラ向けの低水準記述ができる。


Cには他のプログラミング言語と比較して、特筆すべきいくつかの特徴がある。
===自由度===
* 文の区切りを終端記号 [[セミコロン]]「<code>;</code>」で表し、[[改行コード|改行文字]]にも[[スペース|空白]]にも[[字句解析|トークン]]の区切りとしての意味しか持たせない「[[フリーフォーマット (コンピュータ)|フリーフォーマット]]」という形式を採用している。
** 記述作法についてはしばしば議論の対象となり、書籍も多数出版されている。
* [[ALGOL]]の思想を受け継いで'''[[構造化プログラミング|構造化]]'''に対応している。手順を[[ネスティング|入れ子]]構造で示して見通しの良い記述をすることができる。原理的に'''無条件分岐(<code>[[goto文|goto]]</code>)'''を使用する必要はなく、MISRA Cでは当初goto文を禁止していた。goto文を使わなければ、'''[[スパゲティプログラム]]'''と呼ばれる読みにくいプログラムになりにくい。
* '''[[モジュール|モジュール化]]'''が[[ファイル (コンピュータ)|ファイル]]を単位として可能。モジュール内だけで有効な名前を使うことが出来る[[スコープ]]を持っている。
* プログラムを[[戻り値]]つきの[[サブルーチン]]に分離できる。C言語ではこれを'''[[関数 (プログラミング)|関数]]'''と呼び、関数内のプログラムコードでは、独立した変数が使用できる。これにより、データの流れがブロックごとに完結するのでデバッグが容易になり、また関数の再帰呼び出しも可能となる。また、多人数での共同開発の際にも変数名の衝突が回避しやすくなる。なお、C言語ではUNIXのようなOSを前提としたホスト環境と、割り込み制御のようなOSを前提としないフリースタンディング環境とがある。ホスト環境では、プログラム開始直後に実行するプログラム要素を <code>main</code> という名前の関数として定義する<ref>他の言語、例えば、[[BASIC]]や[[Pascal]]ではプログラム開始直後に実行するプログラム要素はサブルーチンや手続きや関数ではない。</ref>。プログラム中で再帰的に<code>main</code>関数を呼ぶことも可能(C++では不可能<ref>ISO/IEC 14882:2003 3.6.1 「{{lang|en|The function main shall not be used within a program.}}」</ref><ref>JIS X 3014:2003 3.6.1 「関数mainは、プログラムの中で挙用してはならない。」</ref>)。フリースタンディング環境では、エントリポイントと呼ばれるアドレスに置かれたコードをプログラムの開始点とするが、それがmain関数である必要はない。なお再帰呼び出しは、スタックオーバフローの原因となるため、MISRA Cでは禁止している。
<!--


=== 利点 ===
* C言語では、main関数と、標準ライブラリの[[printf]], [[scanf]]関数(およびその類型の関数)は、引数が可変という特殊な性格の関数である。K&Rでは、この特殊な関数mainとprintfを使った例を最初に示している。
* [[構造化プログラミング]]のパラダイムに対応した高水準の[[手続き型言語]]である。ハードウェアの直接的な制御ができる機能を備えつつ、[[機械語]]や[[アセンブリ言語]](アセンブラ)のような[[低水準言語]]と比較して、[[ソースコード]]の再利用性やメンテナンス性に優れており、目的に応じたプログラムの変更や拡張が容易である。
--><!--
* 汎用性およびプログラムの自由度が高く、[[計算資源|リソース]]や性能要求の厳しい用途にも耐えうるため、[[アプリケーションソフトウェア]]の開発だけでなく、[[オペレーティングシステム]](OS)や[[デバイスドライバ|デバイスドライバー]]、[[ファームウェア]]の記述、[[マイクロコントローラ|マイコン]]制御・機械制御など、上位層・下位層を問わず、あらゆる分野で利用されている。
mainはvarargじゃないですよ???????
* 対応する機器の範囲が広い。[[パーソナルコンピュータ]]や[[ワークステーション]]はもちろん、自動車や家電の[[組み込みシステム|組み込み]]用[[マイクロコントローラ|マイコン]]から[[スーパーコンピュータ]]まで、C言語を使用できるハードウェアは多様である。そのため、C言語のコード資産が蓄積されている環境・分野は多岐に渡る。
* 商用・非商用を問わず、採用ソフトウェア分野が広い。プログラム作成や[[デバッグ]]のための補助的なソフトウェア([[プログラミングツール]])が豊富である。
* ソースコードを機械語に変換するソフトウェア([[コンパイラ]])などの開発環境が[[CPU]]やOSに付属していたり無償だったりするものもあるため、ライセンス料の支払いをしなくても使用が始められる。


=== 欠点 ===
-->
* 開発時期が古いことから、言語構文(文法)に機械語の影響が強く、仕様自体は単純ではあるが明快ではなく難解である。この欠点を改良するためのちに開発された後発言語に比較し、プログラマが記述しなければならないことが多く、[[低水準言語]]のように面倒で習得しにくい側面を持つ。
* システム記述言語として開発されたため、高級言語であるが[[アセンブラ]]的な低水準の操作ができる。'''[[ポインタ (プログラミング)|ポインタ]]演算'''、[[ビット]]ごとの[[論理演算]]、シフト[[演算]]などの機能を持ち、[[ハードウェア]]に密着した処理を効率よく記述できる。これはオペレーティングシステムや[[デバイスドライバ|ドライバ]]などを記述する上では便利であるが、注意深く利用しないと発見しにくい[[バグ]]の原因となる。ライブラリ関数は、C言語規格が規定している関数と、OSが規定している関数との間の整合性、棲み分けなどが流動的である。MISRA Cのようないくつかの制約では、C言語規格が規定している関数の妥当性について指摘し、いくつかの関数を利用しないように規定している。
* Cは、移植の容易性、自由度、実行速度、コンパイル速度などを追求した。代わりにコンパイル後のコードの安全性を犠牲にしている。また、詳細を規格で規定せず処理系に委ねている部分が多く、Cで書かれたソフトウェアでは処理系依存のコードが氾濫する原因となった。セキュリティ上の脆弱性や潜在的バグによる想定外の動作、コンパイラによる最適化の難しさ{{efn|例えばポインタのエイリアシングは最適化やベクトル化を妨げる<ref>[https://www.isus.jp/products/c-compilers/pointer-aliasing-and-vectorization/ ポインター・エイリアシングとベクトル化 | iSUS]</ref>。}}といった問題を抱えており、最適化するとコンパイル速度が遅くなるなどの問題が生じることがある。

上記のように、利点でもあり、同時に欠点にもなる特徴を備えている。

もともと[[UNIX]]およびCコンパイラの移植性を高めるために開発されてきた経緯から、[[オペレーティングシステム]](OS)の[[カーネル]]およびコンパイラ向けの低水準な記述ができるなど、ハードウェアをある程度抽象化しつつも、必要に応じて低水準言語と同じことを実現できるようなコンピュータ寄りの言語仕様になっている。そのため、低水準な記述ができる高水準言語と言われたり、高水準言語の顔をした低水準言語(高級アセンブラ<ref>[https://www.grapecity.com/tools/support/powernews/column/clang/019/page01.htm もう一度基礎からC言語 第19回 いろいろな演算子~ビット演算子 Cは高級アセンブラ?]</ref>、汎用アセンブラ<ref>[https://gihyo.jp/dev/serial/01/c-programming-introduction/0001 第1回 Chapter 1 C言語の概要(1):Cプログラミング入門|gihyo.jp … 技術評論社]</ref>)と言われたりすることがある。

Cはアマチュアからプロ技術者まで、プログラマ人口が多く、プログラマのコミュニティが充実している。使用者の多さから、正負の両面含め、Cはプログラミング文化に大きな影響を及ぼしている。また、多目的性と、対応機器の多彩さのため、「コンピュータを使ってやること」は大抵、Cで対応可能である。ただし、Cで効率的かつ安全に記述できるかどうかはまた別の話である。[[スクリプト言語]]やコマンドラインシェルを使えば手軽に実現にできるような処理まで、わざわざCで記述する必要はない。また、[[Graphical User Interface|GUI]][[アプリケーションフレームワーク]]は、Cからは利用できず、[[統合開発環境]]と連携する新しいプログラミングツールやプログラミングパラダイムに対応した後発言語でなければ利用できないものもある。

[[MISRA C]]や[[CERT Secure Coding Standards|CERT C]]というコーディング標準(コーディング規約)を定義して、危険な機能の使用や記述を禁止するという制限を設けることでCを安全に利用するためのガイドラインが運用されている分野もある。特にプログラミングミスが人命に直結する自動車分野などでCを利用するには、このような制約が重要である。

=== 機能と自由度 ===
* 文の区切りを終端記号 [[セミコロン]]「<code>;</code>」で表し、[[改行コード|改行文字]]にも[[スペース|空白]]にも[[字句解析|トークン]]の区切りとしての意味しか持たせない「[[フリーフォーマット (コンピュータ)|フリーフォーマット]]」という形式を採用している。中括弧<code>{ }</code>によるブロック構造および[[スコープ (プログラミング)|スコープ]]をサポートする。
* [[ALGOL]]の思想を受け継いで'''[[構造化プログラミング]]'''に対応している。手順を[[ネスティング|入れ子]]構造で示して見通しの良い記述をすることができる。原理的に'''無条件分岐(<code>[[goto文|goto]]</code>)'''を使用する必要はなく、MISRA Cでは当初goto文を禁止していた。
* '''[[モジュール|モジュール化]]'''が[[ファイル (コンピュータ)|ファイル]]を単位として可能。モジュール内だけで有効な名前を使うことができる[[スコープ (プログラミング)|スコープ]]を持っている。
* プログラムを[[戻り値]]つきの[[サブルーチン]]に分離できる。C言語ではこれを'''[[関数 (プログラミング)|関数]]'''と呼び、関数内のプログラムコードでは、独立したスコープを持つ変数([[ローカル変数]])が使用できる。これにより、データの流れがブロックごとに完結するのでデバッグが容易になり、また関数の再帰呼び出しも可能となる。また、多人数での共同開発の際にも変数名の衝突が回避しやすくなる。なお、C言語ではUNIXのようなOSを前提とした[[ホスト環境]]と、割り込み制御のようなOSを前提としない[[フリースタンディング環境]]とがある。ホスト環境では、プログラム開始直後に実行するプログラム要素を <code>main</code> という名前の関数として定義する<ref group="注釈">他の言語、例えば、[[BASIC]]や[[Pascal]]ではプログラム開始直後に実行するプログラム要素はサブルーチンや手続きや関数ではない。</ref>。プログラム中で再帰的に<code>main</code>関数を呼ぶことも可能(C++では不可能<ref>ISO/IEC 14882:2003 §3.6.1 「The function main shall not be used within a program.」</ref><ref>{{cite jis|X|3014|2003|name=プログラム言語C++}} §3.6.1 「関数mainは、プログラムの中で挙用してはならない。」</ref>)。フリースタンディング環境では、[[エントリーポイント]]と呼ばれるアドレスに置かれたコードをプログラムの開始点とするが、それがmain関数である必要はない。なお再帰呼び出しそのものは、[[スタックオーバーフロー]]の原因となるため、MISRA Cでは禁止している。
* システム記述言語として開発されたため、高級言語であるが[[アセンブラ]]的な低水準の操作ができる。'''[[ポインタ (プログラミング)|ポインタ]]演算'''、[[ビット]]ごとの[[論理演算]]、[[シフト演算]]などの機能を持ち、[[ハードウェア]]に密着した処理を効率よく記述できる。これはオペレーティングシステムや[[デバイスドライバ|デバイスドライバー]]などを記述する上では便利であるが、注意深く利用しないと発見しにくい[[バグ]]の原因となる。ライブラリ関数は、C言語規格が規定している関数と、OSが規定している関数との間の整合性、棲み分けなどが流動的である。MISRA Cのようないくつかの制約では、C言語規格が規定している関数の妥当性について指摘し、いくつかの関数を利用しないように規定している。
<!--
<!--
* 配列とポインタとでは、宣言の仕方と領域確保の仕組みは異なっているが、配列アクセスそのものは、ポインタ演算および間接参照と同等である。
* 配列とポインタとでは、宣言の仕方と領域確保の仕組みは異なっているが、配列アクセスそのものは、ポインタ演算および間接参照と同等である。
75行目: 67行目:
確かに、*(a+2) は a[2] と同等であるというシンタクティックシュガーや、「配列を関数の実引数として渡そうとすると、配列が渡されるのではなく、その先頭要素を指すポインタが渡される」という仕様がありますが、ちゃんと理解していればそれを「配列アクセスそのものは、ポインタ演算および間接参照と同等」とは表現しないでしょう。
確かに、*(a+2) は a[2] と同等であるというシンタクティックシュガーや、「配列を関数の実引数として渡そうとすると、配列が渡されるのではなく、その先頭要素を指すポインタが渡される」という仕様がありますが、ちゃんと理解していればそれを「配列アクセスそのものは、ポインタ演算および間接参照と同等」とは表現しないでしょう。
-->
-->
<!--
* ソースコードの記述に使う文字集合はANSI-C:1989(ISO/IEC 9899:1990)では{{lang|en|[[ASCII]]}}を標準としている。他の[[ISO 646]]でも書けるように、3文字利用した[[トライグラフ]]と呼ばれる表記法も存在する。その後、ISO/IEC 9899:1995 AMDなどでは多バイト対応の拡張を規定している。さらに、その後トライグラフは複数のコードを利用したシステムでしか利用がないため、より分かり易い2文字による[[ダイグラフ]]を規定している。
上記は誤り。言語仕様を理解していない、完全に的外れの説明なので参考にしないように。
添字演算子 E1[E2] は *((E1)+(E2)) と同一。
E1 あるいは E2 が配列式であろうがポインタ式であろうが、オフセットしてからデリファレンス、となる。
https://ja.cppreference.com/w/c/language/operator_member_access
ポインタ式は変更可能な左辺値式になれるが、配列式は変更可能な左辺値式になれない。この点がポインタと配列の大きな違いのひとつ。
int* p = NULL; int* q = NULL; p = q; // Well-formed.
int a[10] = {0}; int b[10] = {0}; a = b; // Ill-formed.
https://ja.cppreference.com/w/c/language/value_category
-->
* ソースコードの記述に使う文字集合は[[ANSI C]] (C89) およびISO/IEC 9899:1990 (C90) では[[ASCII]]を標準としている。他の[[ISO 646]]でも書けるように、3文字利用した[[トライグラフ]]と呼ばれる表記法も存在する。その後、ISO/IEC 9899:1995 AMD (C95) などでは[[マルチバイト文字]]セット対応の拡張を規定している。さらに、その後トライグラフは複数のコードを利用したシステムでしか利用がない{{要説明|date=2020-01}}ため、より分かり易い2文字による[[ダイグラフ]]を規定している。
* 組み込みの[[整数型]]および[[浮動小数点数]]型のほか、[[構造体]]、[[共用体]]、列挙体([[列挙型]])によるユーザー定義のデータ型や列挙定数をサポートする。構造体および共用体は[[ビットフィールド]]をサポートする。


===アセンブラとのインタフェース===
===アセンブラとのインタフェース===
82行目: 85行目:


===コンパイラ仕様===
===コンパイラ仕様===
* コンパイラの処理が1パスで済む仕様になっている。歴史的な経緯から、[[変数 (プログラミング)|変数]]の宣言において型指定がない場合は<code>int</code>型とみなし、[[サブルーチン|関数]]の戻り値の型指定がない場合は<code>int</code>型とみなす。ANSI C (C89) ではコンパイル時型検査の強化のために[[関数プロトタイプ]]の機能が導入されたが、関数の宣言がない場合の[[戻り値]]は<code>int</code>型とみなし、引数は未知(任意)とみなす。しかし、このような暗黙の型指定は型安全性を損ない[[未定義動作]]を引き起こす危険性があるため、ISO/IEC C:1999 (C99) 以降では暗黙の型指定に関する仕様が標準規格の文面から削除された。いずれも使用(参照)するより前に適切に宣言する必要がある。ClangやGCCといったC99準拠のコンパイラは、このような暗黙の型指定について、C99モードであってもC89互換の動作を残してはいるものの、非標準の動作であるため警告を出すようになっている。なお、関数宣言において<code>()</code>のように引数を省略すると、引数を未知とする仕様はC99でも残されている。後継言語では完全なプロトタイプ宣言を必須とするか、あるいはプロトタイプ宣言自体を不要としているが、記述によっては先読みが必要になりうる。
* コンパイラの処理が1パスで済む仕様になっている。ANSI-C:1989では宣言のない変数はintを想定することになっていた。ISO/IEC C:1999以降では[[変数 (プログラミング)|変数]]はその使用より前に宣言する必要がある。[[関数 (プログラミング)|関数]]の宣言がないと、戻り値や引数をint型とみなす仕様は、自由な発想を促すプログラミングの視点で好ましいが、型検査・型証明の仕組みが十分にないと不具合の原因になることがある。後継言語では記述によって先読みが必要になりうる。
* マクロ記述やコンパイル条件の指定などが出来る前処理指令が標準化されている。前処理指令の解釈をする'''[[プリプロセッサ]]'''を持っている。プリプロセッサ(preprocessor)は、その名の通りコンパイル処理の前に自動的に実行される。コンパイラの機能として、プリプロセッサを通しただけの段階のソースコードを出力可能になっているものがある。前処理の結果を検査することで、設計者の意図と前処理の結果のずれがないか確認できる。
* マクロ記述やコンパイル条件の指定などができる前処理指令が標準化されている。前処理指令の解釈をする'''[[プリプロセッサ]]''' (preprocessor) を持っている。プリプロセッサは、その名の通りコンパイル処理の前に自動的に実行される。コンパイラの機能として、プリプロセッサを通しただけの段階のソースコードを出力可能になっているものがある。前処理の結果を検査することで、設計者の意図と前処理の結果のずれがないか確認できる。


===処理系の簡素化===
===処理系の簡素化===
ホスト環境やプログラムの内容によっては、以下に対して脆弱性対策を施しても実行速度の低下が無視できる程度であることも多く、欠点とみなされることも少なくない。
処理系の簡素化と効率のために、以下のように安全性を犠牲にした仕様が多い。なお、ホスト環境やプログラムの内容によっては、以下に対して脆弱性対策を施したとしても実行速度の低下が無視できる程度であることも多く、言語仕様側の欠点とみなされることも少なくない。
; [[配列]]参照時の自動的な添字のチェックをしない
; [[配列]]参照時添字の値が範囲内にあるか検査しない
: これを要因とする代表的なバグが[[バッファオーバーフロー]](固定長のバッファをはみだして書きが行われてしまう)である。標準ライブラリにはバッファオーバーフローを考慮していない関数があり、かつ多用されがちなため、しばしば[[脆弱性]]の原因となる。また、プログラムにより制御するで[[可変長配列]]を可能にしている。
: これを要因とする代表的なバグが固定長のバッファ領域をはみだしてデータの書き込みが行われてしまう「[[バッファオーバーフロー]]」([[バッファオーバーラン]])である。範囲外のアクセスは、書き込みだけでなく読み取りの場合も[[未定義動作]]を引き起こす。標準ライブラリにはバッファオーバーフローや範囲外アクセスを考慮していない関数があり、かつ多用されがちなため、しばしば[[脆弱性]]の原因となる。また、Cではプログラムにより明示的に制御([[動的メモリ確保]])することで[[可変長配列]]の実現を可能にしているが、確保した領域の範囲外にアクセスしても自動的な伸長は行なわれない
: 後継言語では、標準ライブラリまたは組み込み型により可変長配列をサポートしていたり、範囲外アクセス時には例外(実行時エラー)を送出するなどして安全性を優先していたりすることが多い。
; [[文字列]]を格納するための特別な型が存在しない
; [[文字列]]を格納するための特別な型が存在しない
: 文字列にはchar型の配列を利用する。言語仕様上に特別な扱いはないが、[[ヌル文字]](<code>\0</code>)を終端とする[[文字列]]表現を使い、その操作をする[[標準Cライブラリ|標準ライブラリ]]関数がある。これは実質的にメモリ領域のポインタアクセスそのもので、固定長バッファに対し、それより長い可変長の文字列を書き込んでしまうことがあり、[[バッファオーバーラン]]の元凶の1つとなっている。後継言語では文字列処理を特に強化している場合が多い。
: 文字列には<code>char</code>型の配列を利用する。言語仕様上に特別な扱いはないが、[[ヌル文字]](<code><nowiki>'\0'</nowiki></code>)を終端とする[[文字列]]表現を使い、その操作をする[[標準Cライブラリ|標準ライブラリ]]関数がある。これは実質的にメモリ領域のポインタアクセスそのものであり確保されいる領域の長さより長い文字列を書き込めてしまうために、[[バッファオーバーラン]]の元凶の1つとなっている。
: 後継言語では文字列処理を特に強化している場合が多く、標準ライブラリあるは言語仕様による組み込みの文字列型を提供している
; 自動変数の自動的な初期化をしない
; 自動変数(auto variable)の自動的な初期化をしない
: 自動変数(静的でないローカル変数)は変数の中でも最も頻繁に用いられる。初期化されていない変数を参照した場合値は不定となるが、不定な値へのアクセスは{{仮リンク|未定義動作|en|Undefined behavior}}であるので、[[コンパイラ最適化]]の過程で想定しない形に改変することもある<ref>[http://www.jpcert.or.jp/sc-rules/c-exp33-c.html EXP33-C. 未初期化のメモリを参照しない] [[JPCERT/CC]]、2014年3月25日(2014年8月22日閲覧)。</ref>。変数宣言・初期化の仕様による制限から、変数宣言の時点で初期化せず後で代入することで初期化代えることが日常的で、誤って不定の値の変数を読み出す[[バグ]]を作り込みやすい。なお自動変数の自動とは<!--[[スタック]]上に - 仕様上はスタックによる実装を強制していなかったはずです。-->変数の領域の確保と放が自動であるという意味であり、自動的に初期化されるという意味ではない。
: 自動変数(静的でないローカル変数)は変数の中でも最も頻繁に用いられる。初期化されていない変数を参照した場合にはその値は不定であるが、不定な値へのアクセスは[[未定義動作]]であるので、[[コンパイラ最適化]]の過程で想定しない形に改変することもある<ref>[https://www.jpcert.or.jp/sc-rules/c-exp33-c.html EXP33-C. 未初期化のメモリを参照しない] [[JPCERT/CC]]、2014年3月25日(2014年8月22日閲覧)。</ref>。変数宣言・初期化の仕様による制限から、変数宣言の時点で初期化せず後で代入より値を入れてつかうことが普通なので、誤って不定の値の変数を読み出す[[バグ]]を作り込みやすい。なお自動変数の自動とは<!--[[スタック]]上に - 仕様上はスタックによる実装を強制していなかったはずです。-->変数の領域の確保と放が自動であるという意味であり、自動的に初期化されるという意味ではない。
: 後継言語では、明示的な初期化が記述されていない変数は、不定値ではなくその変数の型の既定値(ゼロあるいはゼロ相当の値)で初期化される仕様になっていることが多い。


===その他===
===その他===
* 文字の大文字・小文字を区別する。
* ソースコード上の文字の大文字・小文字を区別する。
* [[入出力]]を含めほとんどの機能が、C言語自身で書かれた[[ライブラリ]]によって提供される。このことは、C言語の機種依存性が低く、入出力関係ライブラリをのぞいた部[[移植性]](ポータビリティ)が高いことを意味する{{要出典|date=2009年12月}}。さまざまな機種があるUNIXの世界でC言語が普及した理由のひとつである。
* [[入出力]]や[[動的メモリ確保]]を含めほとんどの機能が、C言語自身で書かれた[[ライブラリ]]によって提供される。このことは、C言語の機種や環境依存性が低く、それらに依存する箇所をライブラリ離することにより[[移植性]](ポータビリティ)が高いことを意味する{{要出典|date=2009年12月}}。さまざまな機種があるUNIXの世界でC言語が普及した理由のひとつである。
** 例として、[[POSIX]]環境での動的メモリ確保は<code>[[malloc]]</code>およびその類似関数にて提供される。一方、[[カーネル]]ではメモリ確保の際にスレッドがブロックされるとカーネル内のデータが他のスレッドにより変更され、予期せぬ動作を起こす恐れがあることや、メモリ内容の初期化が必要かどうかによって割当先のページを選択することによりシステムの効率が上がることから、多くの場合POSIXとは異なるAPIを使用している。[[Linuxカーネル]]の場合、前者はフラグ<code>GFP_KERNEL</code>と<code>GFP_ATOMIC</code>の使い分け、後者は関数<code>kmalloc</code>(割り当てたメモリの内容は不定)と<code>kzalloc</code>(割り当てたメモリの内容はゼロクリア済)の使い分けにより実装している<ref>
{{cite web
| url = https://www.kernel.org/doc/html/next/core-api/memory-allocation.html
| title = Memory Allocation Guide
| website = The Linux Kernel documentation
| access-date = 2023-11-08
}}
</ref>。
* プログラムの実行に必要とする[[ハードウェア]]資源が、アセンブラよりは多いが他の高級言語より少なくてすむため、現在さまざまな電化製品などの[[組み込みシステム]]でも使用されている。
* プログラムの実行に必要とする[[ハードウェア]]資源が、アセンブラよりは多いが他の高級言語より少なくてすむため、現在さまざまな電化製品などの[[組み込みシステム]]でも使用されている。
* 組み込み向けの場合は、プログラミング言語として、アセンブラ以外ではCとC++しか用意されていないことがある。その場合、他のプログラミング言語は、CやC++で書かれた処理系が存在すればコンパイルすることにより利用可能となることもあるが、メモリ制約などで動作しないことがある。
* 組み込み向けの場合は、プログラミング言語として、アセンブラ以外ではCとC++しか用意されていないことがある。その場合、他のプログラミング言語は、CやC++で書かれた処理系が存在すればコンパイルすることにより利用可能となることもあるが、メモリ制約などで動作しないことがある。
* ANSI/ISOにより規格が標準化された後は言語仕様の変化が小さく安定していること、C言語のプログラマ人口やコード資産が多いこと、[[C++]]や[[Objective-C]]からC言語関数を直接利用できること、また必要に応じて他のプログラミング言語からC言語関数を呼び出すためのバインディングを記述することが容易であることなどから、[[Application Programming Interface|API]]の外部仕様としてC言語の関数インターフェイスが選ばれることが多い。例えば[[OpenGL]]や[[OpenCL]]のようなオープン規格は第一級言語としてC言語を採用している。


===コード例===
===コード例===
* [[Hello world]]プログラム
====Hello worldプログラム====


C言語の{{lang|en|Hello world}}プログラムは、ホスト環境を前提とするか、フリースタンディング環境を前提とするかで、方向性が異なる。入門書によって趣が異なるいくらかの方向性が存在する。ホスト環境を前提とする場合には、[[標準入出力]]の利用により、動作をすぐに確かめることができる。[[標準Cライブラリ]]の<code>printf</code>関数 ([[ヘッダファイル]]<code>stdio.h</code>にて宣言) を利用したものを例示する場合、以下のようなものがある。
C言語の[[Hello world]]プログラムは、ホスト環境を前提とするか、フリースタンディング環境を前提とするかで、方向性が異なる。ホスト環境を前提とする場合には、[[標準入出力]]の利用により、動作をすぐに確かめることができる。以下では、[[標準Cライブラリ]]の[[ヘッダファイル|ヘッダ]]<code>stdio.h</code>にて宣言されている、<code>[[puts]]</code>関数あるいは<code>[[printf]]</code>関数を利用したものを例示する。


<source lang="c">
<syntaxhighlight lang="c">
/* int puts(const char* s) を使う場合。 */
#include <stdio.h>
#include <stdio.h>


int main(void)
int main(void)
{
puts("Hello, world!");
return 0;
}
</syntaxhighlight>

<syntaxhighlight lang="c">
/* int printf(const char* format, ...) を使う場合。 */
#include <stdio.h>

int main(int argc, char* argv[])
{
{
printf("Hello, world!\n");
printf("Hello, world!\n");
return 0;
return 0;
}
}
</syntaxhighlight>
</source>
ここでサンプルソース中の「<code>\n</code>」は改行を表す。なお、<code>printf</code> 関数は変数や書式化された文字列などが表示でき比較的高機能な出力関数である。C言語して可変引数である特殊なmainとprintfを使っていることにより、C言語の関数プロググに対る誤解を生む原因にもなっている
上記サンプルソース中の「<code>\n</code>」は、[[エスケープ文字]]<code>\</code>によ[[エスケープシーケンス]]のひであり、[[改行]](フィード)を表す。

<code>main</code>関数は標準的なプログラム[[エントリーポイント]]であり、プログラムを開始すると、ランタイムライブラリによるスタートアップ処理が実行された後にこの<code>main</code>関数が呼ばれる。引数のないバージョンと、コマンドライン引数をポインタ配列として受け取るバージョンどちらを使ってもよい<ref>[https://ja.cppreference.com/w/c/language/main_function main 関数 - cppreference.com]</ref>。

なお、<code>printf</code>関数は書式文字列とそれに対応する[[可変個引数]]を受け取り、書式化された文字列として表示できる高機能な標準出力関数であるが、序盤から例示に使用している入門書もある。

<code>main</code>関数と<code>printf</code>関数は、いずれも入門者や初学者にとっては最初の関門となる難解な関数であり、C言語によるプログラミングのハードルを高くしている一因でもある<ref>[https://atmarkit.itmedia.co.jp/ait/articles/1904/02/news024.html [Python入門]Pythonってどんな言語なの?:Python入門(1/2 ページ) - @IT]</ref><ref>[https://programming-place.net/ppp/contents/c/002.html Hello, Worldプログラム | Programming Place Plus C言語編 第2章]</ref><!-- 他の言語のエントリポイントおよび標準入出力と比べれば、Cのそれらが入門者にとって難解であるのは自明。後発言語だけでなく、同時代の他の言語と比べても。 -->。[[Java]]や[[C Sharp|C#]]のような後発言語では、文字列の扱いや、可変個引数の扱いがより簡潔で安全になっている。[[Python]]のような[[インタプリタ]]や対話環境上で動作することを前提とした言語では、<code>main</code>関数を定義する必要はない。


===主な制御構造===
===主な制御構造===
131行目: 164行目:
==歴史==
==歴史==
===誕生===
===誕生===
C言語は、AT&Tベル研究所の[[ケン・トンプソン]]が開発した[[B言語]]の改良として誕生した([[#外部リンク]]の「{{lang|en|The Development of the C Language}}」参照)。
C言語は、AT&Tベル研究所の[[ケン・トンプソン]]が開発した[[B言語]]の改良として誕生した([[#外部リンク]]の「The Development of the C Language」参照)。


[[1972年]]、トンプソンと{{lang|en|[[UNIX]]}}の開発を行っていた[[デニス・リッチー]]はB言語を改良し、実行可能な[[機械語]]を直接生成するC言語のコンパイラを開発した<ref>[https://www.bell-labs.com/usr/dmr/www/portpap.html Portability of C Programs and the UNIX Systems]</ref>。後に、{{lang|en|UNIX}}は大部分をC言語によって書き換えられ、C言語のコンパイラ自体も移植性の高い実装の{{lang|en|[[Portable C Compiler]]}}に置き換わったこともあり、UNIX上のプログラムはその後にC言語を広く利用するようになった。
[[1972年]]、トンプソンと[[UNIX]]の開発を行っていた[[デニス・リッチー]]はB言語を改良し、実行可能な[[機械語]]を直接生成するC言語のコンパイラを開発した<ref>[https://www.bell-labs.com/usr/dmr/www/portpap.html Portability of C Programs and the UNIX Systems]</ref>。後に、UNIXは大部分をC言語によって書き換えられ、C言語のコンパイラ自体も移植性の高い実装の[[Portable C Compiler]]に置き換わったこともあり、UNIX上のプログラムはその後にC言語を広く利用するようになった。


ちなみに、「UNIXを開発するためにC言語が作り出された」と言われることがあるが、「The Development of the C Language」によると、これは正しくなく、経緯は以下の通りである。C言語は、当初はあくまでもOS上で動くユーティリティを作成する目的で作り出されたものであり、OSのカーネルを記述するために使われるようになるのは後の展開である。
ちなみに、「UNIXを開発するためにC言語が作り出された」と言われることがあるが、「The Development of the C Language」によると、これは正しくなく、経緯は以下の通りである。C言語は、当初はあくまでもOS上で動くユーティリティを作成する目的で作り出されたものであり、OSのカーネルを記述するために使われるようになるのは後の展開である。
*UNIXの開発当初、[[Multics]]プロジェクトが目指していた高級言語によるOSの開発という目標は見送られた。
* UNIXの開発当初、[[Multics]]プロジェクトが目指していた高級言語によるOSの開発という目標は見送られた。
*アセンブリ言語でUNIXが作成されると、OS上で動くユーティリティを作成するためのプログラミング言語が必要とされた。
* アセンブリ言語でUNIXが作成されると、OS上で動くユーティリティを作成するためのプログラミング言語が必要とされた。
*ケン・トンプソンは、当初Fortranコンパイラを作ろうとしたが、途中で放棄し、新しい言語であるB言語を作成した。
* ケン・トンプソンは、当初Fortranコンパイラを作ろうとしたが、途中で放棄し、新しい言語であるB言語を作成した。
*B言語はインタプリタ言語であったため動作が遅く、B言語でユーティリティを作ることはあまりなかった。(開発者達は、コンパイラなどのユーティリティを「システムプログラム」と呼んでいたが、それらの作成に使われる「システムプログラミング言語」は、OSのカーネルを作成するための言語という意味ではない<ref>[http://www.bell-labs.com/usr/dmr/www/hist.html The Evolution of the UNIX Time-sharing Ststem]</ref>。
* B言語はインタプリタ言語であったため動作が遅く、B言語でユーティリティを作ることはあまりなかった。
: 開発者達は、コンパイラなどのユーティリティを「システムプログラム」と呼んでいたが、それらの作成に使われる「システムプログラミング言語」は、OSのカーネルを作成するための言語という意味ではない<ref name="evolution">[https://www.bell-labs.com/usr/dmr/www/hist.html The Evolution of the Unix Time-sharing System]</ref>。
*B言語の欠点を解消するため、1971年に改良作業を開始した。
* B言語の欠点を解消するため、1971年に改良作業を開始した。
*1972年にC言語のコンパイラができあがり、UNIXバージョン2において、いくつかのユーティリティを作成するために使用された。
* 1972年にC言語のコンパイラができあがり、UNIXバージョン2において、いくつかのユーティリティを作成するために使用された。


===UNIX環境とC言語===
===UNIX環境とC言語===
アセンブラとの親和性が高いために、ハードウェアに密着したコーディングがやりやすかったこと、言語仕様が小さいためコンパイラの開発が楽だったこと、小さな資源で動く実行プログラムを作りやすかったこと、UNIX環境での実績があり、後述の {{lang|en|K&R}} といった解説文書が存在していたことなど、さまざまな要因からC言語は業務開発や情報処理研究での利用者を増やしていった。特にメーカー間でオペレーティングシステムやCPUなどのアーキテクチャが違う {{lang|en|UNIX}}環境では再移植の必要性がしばしば生じて、プログラムをC言語で書いてソースレベル互換<ref>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</ref>を確保することが標準となった。
アセンブラとの親和性が高いために、ハードウェアに密着したコーディングがやりやすかったこと、言語仕様が小さいためコンパイラの開発が楽だったこと、小さな資源で動く実行プログラムを作りやすかったこと、UNIX環境での実績があり、後述のK&Rといった解説文書が存在していたことなど、さまざまな要因からC言語は業務開発や情報処理研究での利用者を増やしていった。特にメーカー間でオペレーティングシステムやCPUなどのアーキテクチャが違うUNIX環境では再移植の必要性がしばしば生じて、プログラムをC言語で書いてソースレベル互換<ref>[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 ソースレベル互換] - ZDNet Japan</ref>を確保することが標準となった。

===C言語誕生時の環境と他言語との比較===
C言語の開発当初に使われた入力端末は{{仮リンク|ASR-37|en|Teletype Model 37}}であったことが知られている<ref name="evolution" />。
ASR-37は1967年制定の旧ASCII ISO R646-7bitにもとづいており、「<code>{</code>」および「<code>}</code>」の入力を行うことができたが、当時は一般的に使われていた入力端末ではなかった。
当時[[PDP-11]]の入力端末として広く使われていたのは[[ASR-33]]であるが、これは1963年制定の旧ASCIIであるASA X3.4に準拠しており、「<code>{</code>」や「<code>}</code>」の入力を行うことはできなかった<ref>http://www.tohoho-web.com/ex/draft/kanji.htm</ref>。

このことは、ブロック構造に「<code>{</code>」や「<code>}</code>」を用いるC言語(さらに元をたどれば[[B言語]])は、当時の一般的な環境では使用不可能であったことを示している。
これは、C言語はその誕生当初にあっては一般に広く使われることを想定しておらず、ベル研究所内部で使われることを一義的に考えた言語であったという側面の表れである。

これに対し、[[Pascal]]や[[BASIC]]等の当初から広く使われることを想定した言語では、ブロック構造に記号を用いずに<code>begin</code>と<code>end</code>をトークンとして用いることや、コメント行を表す際に開始トークンとして<code>REM</code>という文字列を用いることなど、記号入力に制約がある多くの入力端末に対応できるように配慮されていた。この頃の他の言語やOSで大文字と小文字の区別をしないものが多いのも、当時は大文字しか入力できない環境も少なくなかったことの表れである。

このような事情のため、C言語が普及するのは、ASCII対応端末が一般化した1980年代に入ってからである。

現在、ブロック構造の書式等で、<code>{...}</code>形式のC言語と、<code>begin...end</code>等を使用する他の言語との比較において優劣を論じられることがあるが、開発時の環境等をふまえずに現時点での利便性のみで論じるのは適切ではない場合があることに留意が必要である。


===PCとC言語===
===PCとC言語===
[[1980年代]]に普及し始めた[[パーソナルコンピュータ]](PC)は当初、[[8ビット]]CPUで{{lang|en|ROM-BASIC}}を搭載していたものも多く、{{lang|en|BASIC}}が普及していたが、1980年代後半以降、[[16ビット]]CPUを採用しメモリも増えた({{lang|en|ROM-BASIC}} 非搭載の)PCが主流になりだすと、2万円前後の安価なコンパイラが存在したこともあり、ユーザーが急増した。8ビットや[[Intel 8086|8086]]系のPCへの移植は、ポインタなどに制限や拡張を加えることで解決していた。
[[1980年代]]に普及し始めた[[パーソナルコンピュータ]] (PC) は当初、[[8ビット]]CPUでROM-BASICを搭載していたものも多く、BASICが普及していたが、1980年代後半以降、[[16ビット]]CPUを採用しメモリも増えた(ROM-BASIC非搭載の)PCが主流になりだすと、Turbo CやQuick Cといった2万円程度比較的安価なコンパイラが存在したこともあり、ユーザーが急増した。8ビットや[[Intel 8086|8086]]系のPCへの移植は、ポインタなどに制限や拡張を加えることで解決していた。


===現在のC言語===
===現在のC言語===
1990年代中盤以降は、最初に学ぶプログラミング言語としても主流となった。また、90年代中盤にはゲーム専用機(ゲームコンソール)の性能向上とプログラムの大規模化、マルチプラットフォーム展開を受け、開発言語がアセンブラからC言語に移行した。[[グラフィカルユーザインタフェース|GUI]]環境の普及と[[オブジェクト指向]]の普及により {{lang|en|[[Java]]}}、{{lang|en|[[Objective-C]]}}、[[C++]]、{{lang|en|[[PHP (プログラミング言語)|PHP]]}}、{{lang|en|[[Microsoft Visual Basic|Visual Basic]]}}、などの言語の利用者も増加したため、広く利用されるプログラミング言語の数は増加傾向にある。現在でも[[Java]], [[C Sharp|C#]], [[C++]]などC言語派生の後発言語を含めて、C言語は比較的移植性に優れた言語であり、業務用開発や[[フリーソフトウェア]]開発、C++などの実装が困難な組み込みなどの小規模のシステムで、幅広く利用されている
1990年代中盤は、最初に学ぶプログラミング言語としても主流となった。また、同時期にはゲーム専用機(ゲームコンソール)の性能向上とプログラムの大規模化、マルチプラットフォーム展開を受け、メインの開発言語がアセンブラからC言語に移行した。

1990年代後半から2000年代以降は、PCのさらなる性能向上と普及、[[グラフィカルユーザインタフェース|GUI]]環境や[[オブジェクト指向]]の普及、インターネットおよびウェブブラウザの普及、[[スマートフォン]]の普及に伴い、より高水準で開発効率の高い言語やフレームワークを求める開発者が増えたことにより、[[C++]]、[[Microsoft Visual Basic|Visual Basic]]、[[Java]]、[[C Sharp|C#]]、[[Objective-C]]、[[PHP (プログラミング言語)|PHP]]、[[JavaScript]]などが台頭してきた。広く利用されるプログラミング言語の数は増加傾向にあり、相対的にC言語が使われる場面は減りつつある。特にアプリケーションソフトウェアなどの上位層の開発には、C言語よりも記述性に優れるC++、Java、C#などC言語派生の後発言語が利用されることが多くなっている。資源制約の厳しかったゲーム開発においても、ハードウェアの性能向上や[[ミドルウェア]]の普及により、C++やC#などが使われる場面が増えている。速度性能や省メモリが特に重視されるシステムプログラミングに関しても、伝統的にC/C++の独壇場だったが、新規コードではより安全性の高い[[Rust (プログラミング言語)|Rust]]を導入する事例が現れている<ref>[https://forest.watch.impress.co.jp/docs/news/1317183.html Rust言語でAndroidはより強固・安全に ~GoogleがOS開発への導入を進める - 窓の杜]</ref><ref>[https://news.mynavi.jp/techplus/article/20191205-933334/ Microsoft、Windows 10の一部をRustへ書き換えてセキュリティ強化狙う | TECH+]</ref>。

しかし、C言語は比較的移植性に優れた言語であり、個人開発/業務用開発/学術研究開発や[[プロプライエタリ]]/[[オープンソース]]を問わず、オペレーティングシステムやデバイスドライバーなどの下位層、クロスプラットフォームAPIの外部仕様、C++やJavaなどの高水準言語の処理系および実行環境の実装が困難な小規模の組み込みシステムなどを中心に、2021年現在でも幅広く利用されている。

プログラミング入門者にとっては、[[Python]]、JavaScript、[[Swift (プログラミング言語)|Swift]]、[[Kotlin]]などのように、インタラクティブな対話環境([[REPL]]、[[インタプリタ]])が利用でき、抽象化が進んでおり、煩雑なメモリ管理が不要で、危険な機能を制限した高水準言語のほうが学習・習得しやすいが、コンピュータの動作原理やハードウェア仕様を理解するには、Cのような原始的な言語を用いたほうがかえって分かりやすいケースもある。


==C言語の規格==
==規格==
==={{lang|en|K&R}}===
===K&R===
{{See also|プログラミング言語C}}
{{See also|プログラミング言語C}}
[[デニス・リッチー|リッチー]]と[[ブライアン・カーニハン|カーニハン]]の共著である「{{lang|en|[[プログラミング言語C|The C Programming Language]]}}」<ref>「{{lang|en|K&R}}」という通称ある</ref>[[1978年]]を出版。その後標準ができるまで実質的なC言語の標準として参照。C言語は発展可能な言語で、この本の記述も発展の可能性のある部分は厳密な記述をしておらず、曖昧な部分が存在していた。C言語が普及するとともに、[[方言 (プログラミング言語)|互換性のない処理系]]が数多く誕生した。これはプログラミング言語でしばしば起こる現象であり、C言語固有の現象ではない
[[米国国家規格協会]](ANSI)による標準化が行われるまで、[[1978年]]出版の[[デニス・リッチー]]と[[ブライアン・カーニハン]]の共著[[プログラミング言語C|The C Programming Language]]が実質的なC言語の標準として参照されてきた。この書籍は、著者らのイニシャルを取って「K&R」とも呼ばれている。C言語は発展可能な言語で、K&Rの記述も発展の可能性のある部分は厳密な記述をしておらず、曖昧な部分が存在していた。そのためC言語が普及するとともに、[[方言 (プログラミング言語)|互換性のない処理系]]が数多く誕生した。


===C89/C90===
===C89/C90===
{{main|ANSI C}}
{{main|ANSI C}}
そこで、[[国際標準化機構|ISO]]/IEC JTC1と{{lang|en|[[ANSI]]}}は協同でC言語の規格の標準化を進め、[[1989年]]12月に{{lang|en|ANSI}}
そこで、[[国際標準化機構|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 X 3010-1993 プログラム言語C』として、[[1993年]]10月に制定した。
{{lang|en|ANSI X3.159-1989, American National Standard for Information Systems -Programming Language-C}}を、[[1990年]]12月にISOが{{lang|en|INTERNATIONAL STANDARD ISO/IEC 9899 : 1990(E) Programming Languages-C}}を発行した。ISO/IEC規格のほうが章立てを追加しており、その後{{lang|en|ANSI}}もISO/IEC規格にならって章立てを追加した。それぞれC89 ({{lang|en|ANSI}} C89) 及びISO/IEC C90という通称で呼ぶことがある。


最大の特徴は、C++と同様の[[関数プロトタイプ]]<ref group="注釈">C89においては[[関数プロトタイプ]]は必須ではない。</ref>を導入して引数の型チェックを強化したことと、<code>[[void (コンピュータ)|void]]</code>や<code>enum</code>などの新しい型を導入したことである。一方、「処理系に依存するものとする」に留めた部分も幾つかある(<code>int</code>型のビット幅、<code>char</code>型の符号、[[ビットフィールド]]の[[エンディアン]]、シフト演算の挙動、構造体などへのパディング等)。
日本では、これを翻訳したものを[[日本工業規格]]『JIS X3010-1993 プログラム言語C』として、[[1993年]]10月に制定した。


規格では以下の3種類の自由を認めている部分がいくつかある<ref>[http://www.kouno.jp/home/c_faq/c11.html C FAQ 11]</ref>。
最大の特徴は、C++と同様の[[関数プロトタイプ]]<ref>C89においては[[関数プロトタイプ]]は必須ではない。</ref>を導入して引数の型チェックを強化したことと、<code>[[void (コンピュータ)|void]]</code>や<code>enum</code>などの新しい型を導入したことである。一方、処理系に依存するとするに留めた部分も幾つかある(<code>int</code>型のビット幅、<code>char</code>型の符号、[[ビットフィールド]]の[[エンディアン]]、シフト演算の挙動、構造体などへのパディング等)。
* 規格で定義しないことを決めている「[[未定義動作|未定義]]」 (undefined)
* 規格で選択肢を定義したもののどれにするかを決めておらず、処理系が選択する必要があるが、文書化の必要はない「未規定」 (unspecified)
* 処理系ごとに決めて文書化する必要のある「処理系定義」 (implementation-defined)
これにより、プラットフォームやプロセッサアーキテクチャとの相性による有利不利が生じないような仕様になっている。


[[8ビット]]/[[16ビット]]/[[32ビット]]など、レジスタ幅([[ワード]]サイズ)の異なるプロセッサ (CPU) に対応・最適化できるようにするため、組み込み型の情報量(大きさ)や内部表現にも処理系の自由を認めている。型のバイト数は<code>[[sizeof]]</code>演算子で取得し、各型の最小値・最大値は<code>limits.h</code>で定義されているマクロ定数で参照することとしている。ただし、1バイトあたりのビット数は規定されていない。<code>sizeof(char) == 1</code>すなわち<code>char</code>型が1バイトであることは常に保証されるが、8ビット([[オクテット (コンピュータ)|オクテット]])とは限らない。実際のビット数は<code>CHAR_BIT</code>マクロ定数で取得できる。とはいえ、現実の多くの処理系では<code>char</code>型は8ビットである。また、その他の[[整数型]]については、<code>sizeof(int) >= 2</code>、<code>sizeof(int) >= sizeof(short)</code>、<code>sizeof(long) >= sizeof(int)</code>、という大小関係が定められているだけである(符号無し型も同様)。多くの処理系では<code>short</code>型のサイズは2バイト(16ビット)であるが、<code>int</code>や<code>long</code>のサイズはCPUのレジスタ幅などによって決められることが多い。<code>int</code>型、<code>short</code>型、<code>long</code>型で符号を明示しない場合は<code>signed</code>を付けた符号付き型として扱われる。しかし<code>char</code>型に関しては、<code>signed</code>(符号付き)にするか、それとも<code>unsigned</code>(符号無し)にするかは処理系依存である。<code>char</code>型、<code>signed char</code>型、<code>unsigned char</code>型はそれぞれ異なる型として扱われる。
16ビット/[[32ビット]]CPUの両方に対応できるようにするため、定義しないことを決めている未定義、定義したもののどれにするかを決めていない未規定、処理系ごとに決めて文書化する処理系定義など、CPUとの相性による有利不利が生じないような規定になっている
型の大きさは16ビット/32ビットCPUの両方に対応できるように決めている。バイト数は<code>[[sizeof]]</code>演算子で取得し、最大最小値は<code>limits.h</code>で参照することとしている。多くの処理系では<code>char</code>型は8ビット、<code>short</code>型は16ビットである。<code>int</code>や<code>long</code>はCPUのレジスタの幅などによって決めている。またAPIなどの呼び出しには、ヘッダで<code>BYTE</code>や<code>WORD</code>などと<code>[[typedef]]</code>で定義した型を使用して回避することがある。<code>char</code>型以外で符号を明示しない場合は<code>signed</code>(符号付き)にするかどうかも処理系。


{{see also|整数型|typedef}}
規格上には、BCPL・C++タイプの一行コメント(「<code>//…</code>」)は無いが、オプションで対応した処理系も多く、gccやClangはGNU拡張<code>-std=gnu89</code>でサポートしている。


規格上には、BCPLやC++形式の1行コメント(<code>//…</code>)は無いが、オプションで対応した処理系も多く、gccやClangはGNU拡張<code>-std=gnu89</code>でサポートしている。
{{lang|en|GNU}} Cコンパイラ や [[Clang]] では、<code>-std=c89</code>(または<code>-ansi</code>もしくは<code>-std=c90</code>)をつけることにより、GNU拡張を使わないC89規格に準拠したコンパイルを行うことができる<ref>C89規格に準拠しないソースコードを{{lang|en|GNU}} Cコンパイラでコンパイル失敗させるには、<pre>gcc -ansi -pedantic -fstrict-aliasing -Wall -Wextra -Wmissing-declarations -Werror test.c</pre>とすれば良い(→[[エイリアシング]])。</ref>。加えて、<code>-pedantic</code>をつければ診断結果が出る。商用のコンパイラではWatcom Cコンパイラが規格適合の比率が高いと言われていた。現在Open Watcomとして公開している。

GNU Cコンパイラ や [[Clang]] では、<code>-std=c89</code>(または<code>-ansi</code>もしくは<code>-std=c90</code>)をつけることにより、GNU拡張を使わないC89規格に準拠したコンパイルを行うことができる<ref group="注釈">C89規格に準拠しないソースコードをGNU Cコンパイラでコンパイル失敗させるには、<pre>gcc -ansi -pedantic -fstrict-aliasing -Wall -Wextra -Wmissing-declarations -Werror test.c</pre>とすれば良い(→[[エイリアシング]])。</ref>。加えて、<code>-pedantic</code>をつければ診断結果が出る。商用のコンパイラではWatcom Cコンパイラが規格適合の比率が高いと言われていた。現在Open Watcomとして公開している。


C89には、下記の追加の訂正と追加を行った。
C89には、下記の追加の訂正と追加を行った。
* ISO/IEC 9899/COR1:1994
* ISO/IEC 9899/COR1:1994
* ISO/IEC 9899/AMD1:1995 - 英語圏での利用を想定して制定したC89に対して、国際化のため[[ワイド文字]]版ライブラリを追加した {{lang|en|Amendment1}} が[[1995年]]に発行された。
* ISO/IEC 9899/AMD1:1995 - 英語圏での利用を想定して制定したC89に対して、国際化のため[[ワイド文字]]版ライブラリを追加したAmendment1が[[1995年]]に発行された。
* ISO/IEC 9899/COR2:1996
* ISO/IEC 9899/COR2:1996


===C99===
===C99===
{{main|C99}}
{{main|C99}}
[[1999年]][[12月1日]]に、ISO/IEC JTC1 SC22 WG14 で規格の改を行い、C++の機能のいくつかを取り込むことを含め機能を拡張し{{lang|en|ISO/IEC 9899:1999(E) Programming Language--C (Second Edition)}}を制定した。この版のC言語の規格を、通称として[[C99]]と呼ぶ。{{lang|en|[[Intel C++ Compiler]]}}はC99に完全準拠していると公称している。{{lang|en|GNU}} Cコンパイラ([[GNUコンパイラコレクション|gcc]])はC99にほとんど対応しているが一部未対応部分も残っている<ref>[http://gcc.gnu.org/c99status.html Status of C99 features in GCC]</ref>
[[1999年]][[12月1日]]に、ISO/IEC JTC1 SC22 WG14 で規格の改を行い、C++の機能のいくつかを取り込むことを含め機能を拡張しISO/IEC 9899:1999(E) Programming Language--C (Second Edition) を制定した。この版のC言語の規格を、通称として[[C99]]と呼ぶ。


日本では、日本業規格 JIS X 3010:<!-- 1998(?)年以降はコロン -->2003「プログラム言語C」がある。
日本では、日本業規格 JIS X 3010:<!-- 1998(?)年以降はコロン -->2003「プログラム言語C」がある。


主な追加機能:
主な追加機能:
189行目: 248行目:
* ブール代数を扱うための<code>_Bool</code>型が予約語に追加され、標準ライブラリとして<code>stdbool.h</code>を追加した。
* ブール代数を扱うための<code>_Bool</code>型が予約語に追加され、標準ライブラリとして<code>stdbool.h</code>を追加した。
* 複素数を扱うための<code>_Complex</code>型や<code>_Imaginary</code>型を予約語に追加し、標準ライブラリとして、<code>complex.h</code>を追加した。
* 複素数を扱うための<code>_Complex</code>型や<code>_Imaginary</code>型を予約語に追加し、標準ライブラリとして、<code>complex.h</code>を追加した。
* [[64ビット]]整数値を保持できる <code>long long int</code>型の追加。
* 少なくとも[[64ビット]]整数値を保持できる <code>long long int</code>型の追加。
* オプションとして、固定幅かつ内部表現の規定された整数型の標準化(<code>stdint.h</code>)。
* <code>//</code>による1行コメント。
* <code>//</code>による1行コメント。
* インライン関数(<code>inline</code>キーワード)。
* インライン関数(<code>inline</code>キーワード)。
201行目: 261行目:
===C11===
===C11===
{{main|C11 (C言語)}}
{{main|C11 (C言語)}}
[[2011年]][[12月8日]]に改定された''ISO/IEC 9899:2011''(通称 '''C11''')が現在の最新規格である。gccや[[Clang]]などが部分的に対応している。定による変更・追加・削除機能の一部を以下に記述する
[[2011年]][[12月8日]]に''ISO/IEC 9899:2011''(通称 '''C11''')して改訂された


C11は{{lang|en|[[Unicode]]}}文字列([[UTF-32]]、[[UTF-16]]、[[UTF-8]]の各符号化方式)に標準で対応している。そのほか、<code>type-generic</code>式、C++と同様の無名構造体・無名共用体、排他的アクセスによるファイルオープン方法、quick_exitなどのいくつかの標準関数などを追加した。
C11は[[Unicode]]文字列([[UTF-32]]、[[UTF-16]]、[[UTF-8]]の各符号化方式)に標準で対応している。そのほか、<code>type-generic</code>式、C++と同様の無名構造体・無名共用体、排他的アクセスによるファイルオープン方法、quick_exitなどのいくつかの標準関数などを追加した。


また、<code>_Noreturn</code>関数指示子を追加した。<code>_Noreturn</code>は従来処理系に独自に加していた(たとえばgccでは<code>__attribute__((__noreturn__))</code>)もの共通化したもので、「呼び出し元に戻ることがない」という特殊な関数についてその特性を示すためにある。<code>return</code>文を持たない関数という意味ではなく(規格では<code>return</code>文を持たなくとも、関数の最後の文の実行が終われば制御は呼び出し元に戻る)、この指示が意味するものは、当該の関数、ないしその内部から呼び出している関数の実行中に、必ず<code>_exit</code>や<code>execve</code>を実行したり、例外などで終了する、あるいは、<code>longjmp</code>による大域ジャンプで抜け出す<ref><code>setjmp.h</code>を参照。</ref>、[[継続渡しスタイル]]変換されたコードである、などのために、絶対に制御が呼び出し元に戻らないいう関数示するためにある。そのような関数は、スタックに戻りアドレスを積む通常の呼び出しではなく、スタックを消費しないジャンプによって実行できる。
また、<code>_Noreturn</code>関数指示子を追加した。<code>_Noreturn</code>は従来処理系ごとに独自に加していた属性情報(たとえばgccでは<code>__attribute__((__noreturn__))</code>)を標準化したもので、「呼び出し元に戻ることがない」という特殊な関数についてその特性を示すためにある。<code>return</code>文を持たない関数という意味ではなく(規格では<code>return</code>文を持たなくとも、関数の最後の文の実行が終われば制御は呼び出し元に戻る)、<code>_exit</code>や<code>execve</code>を実行したり、例外、<code>longjmp</code>による大域ジャンプ<ref group="注釈"><code>setjmp.h</code>を参照。</ref>などのために、制御が呼び出し元に戻らないとを示するためにある。そのような関数は、スタックに戻りアドレスを積む通常の呼び出しではなく、スタックを消費しないジャンプによって実行できる。


[[データ構造アライメント|アラインメント]]機能<code>_Atomic</code>型C言語ネイティブの原始的なスレッド機能など省略可能な機能として規格に組み込んだ。また、C99では規格上必須要件とされていた機能のうち、複素数型と可変長配列を省略可能なものに変更した。これらの省略可能な機能C11規格合致の必須要件ではないので、仮に完全に規格合致の処理系であっても対応していないかもしれない。C11規格では省略可能な機能のうちコンパイラがどれを提供しているかを判別するために利用きる、テスト用のマクロを用意している。
C11規格では一部の機能を省略可能とした。すなわちコンパイラがC11に合致していても、一部機能は提供しないことがある。コンパイラがどの機能を提供しているかは、テスト用のマクロで判別できる。[[データ構造アライメント|アラインメント]]機能<code>_Atomic</code>型C言語ネイティブの原始的なスレッド機能などが、C11では省略可能な機能として追加された。また、複素数型と可変長配列はC99では必須機能であったが、C11では省略可能でる。


これにより、<code>gets</code>関数廃止されている
<code>[[gets]]</code>関数廃止され

===C17===
2018年に''ISO/IEC 9899:2018''(通称'''C17'''または'''C18''')として改訂された。仕様の欠陥修正がメインのマイナーアップデートである<ref>[https://ja.cppreference.com/w/c/language/history C の歴史 - cppreference.com]</ref>。

===C23===
{{main|C23}}


==主なC言語処理系==
==主なC言語処理系==
gcc、clang、Visual C++、C++Builderなど著名な4つがC言語とC++を一つの処理系で対応している。C言語とC++の共通部分を明確にし、二つの言語の違いに矛盾が生じないようにすることが課題になっている。
大抵の処理系はC言語とC++両方サポートしている。C言語とC++の共通部分を明確にし、二つの言語の違いに矛盾が生じないようにすることが課題になっている。


=== Linux、Windows、UNIX用 ===
=== Linux、Windows、UNIX用 ===
; {{lang|en|[[C++ Builder]]}}
; [[C++ Builder]]
: {{lang|en|Windows}}用の[[x86]]C言語・C++コンパイラ[[RAD (算機ロググ環境)|RAD]]。前身は {{lang|en|DOS}}、{{lang|en|Windows}}用の {{lang|en|[[ボーランド|Borland C/C++]]}}。さらに前身として{{lang|en|Turbo C/C++}}がある。
: Windows/[[macOS]]/[[iOS]]/[[Android (オペレーティングシステム)|Android]]対応のC/C++コンパイラBCCを含む、[[Rapid Application Development|RAD]]ツール。以前はWindowsおよびx86のみがメインターゲットだったが、Clang/LLVMをベースに再設され、多数のプラットフォームやアーキテクチャをサポートするようになった<ref>[http://docwiki.embarcadero.com/RADStudio/Rio/ja/Clang_%E6%8B%A1%E5%BC%B5_C%2B%2B_%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9 Clang 拡張 C++ コパイラ - RAD Studio]</ref>。前身はDOS/Windows用の[[ボーランド|Borland C/C++]]。さらに前身としてTurbo C/C++がある。
; {{lang|en|[[clang]]}}
; [[Clang]]
: {{lang|en|[[Low Level Virtual Machine|LLVM]]}}をバックエンドとして用いる[[オープンソース]]のC言語・C++・{{lang|en|Objective-C}}コンパイラ。多数のCPUに対応。
: [[Low Level Virtual Machine|LLVM]]をバックエンドとして用いる[[オープンソース]]のC/C++・Objective-Cコンパイラ。多数のCPUに対応。
; [[GNUコンパイラコレクション]] (GCC)

: C/C++以外の言語もサポートし、多数のCPUやオペレーティングシステムに対応、組み込み向けも含む多様な開発に広く使われる[[オープンソース]]のコンパイラ。独自拡張機能も多い。
; [[GNUコンパイラコレクション|{{lang|en|GNU}}コンパイラコレクション]](GCC)
: GCC 4.5で実質的にC99を完全サポートした<ref>[https://gcc.gnu.org/c99status.html Status of C99 features in GCC - GNU Project - Free Software Foundation (FSF)]</ref>。
: C/C++以外の言語もサポートし、多数のCPUやオペレーティングシステムに対応、組み込み向けも含む多様な開発に広く使われる[[オープンソース]]のコンパイラ。
: GCC 4.9で実質的にC11を完全サポートした<ref>[https://gcc.gnu.org/wiki/C11Status C11Status - GCC Wiki]</ref>。

; {{lang|en|[[Microsoft Visual C++]]}}
; [[Microsoft Visual C++]] (MSVC)
: {{lang|en|Windows}}系プラットフォーム用のC言語・C++コンパイラ。ANSI C準拠(バージョン2013にてC99ライブラリをほぼ実装したが、規格はサポートされていない)。x86・x64が主だが {{lang|en|[[Xbox 360]]}}{{lang|en|[[Microsoft Windows Embedded CE|Windows CE]]}}等向けに {{lang|en|[[PowerPC]]}}{{lang|en|[[ARMアーキテクチャ|ARM]]}}{{lang|en|[[MIPSアーキテクチャ|MIPS]]}}{{lang|en|[[Itanium]]}}等に対応した版もある。前身として{{lang|en|MS-DOS}}{{lang|en|Windows}}用の{{lang|en|Microsoft C Compiler}}がある。またその廉価版として{{lang|en|Quick C}}があった<ref>{{Cite news|title={{lang|en|Microsoft Releases C Program Wares, Provides Rebates}}|newspaper={{lang|en|InfoWorld}}|date=November 9, 1987|page=29|url=http://books.google.pl/books?id=Sj0EAAAAMBAJ}}</ref>。
: Windows系プラットフォーム用のC/C++コンパイラ。ANSI C準拠(バージョン2013にてC99ライブラリをほぼ実装したが、言語機能など規格自体はサポートされていない)。x86・x64が主だが[[Xbox 360]]、[[Microsoft Windows Embedded CE|Windows CE]]等向けに[[PowerPC]]、[[ARMアーキテクチャ|ARM]]、[[MIPSアーキテクチャ|MIPS]]、[[Itanium]]等に対応した版もある。前身としてMS-DOS・Windows用のMicrosoft C Compilerがある。またその廉価版としてQuick Cがあった<ref>{{Cite news|title=Microsoft Releases C Program Wares, Provides Rebates|newspaper=InfoWorld|date=November 9, 1987|page=29|url=https://books.google.pl/books?id=Sj0EAAAAMBAJ}}</ref>。
; {{lang|en|[[Intel C++ Compiler]]}}
; [[Intel C++ Compiler]] (ICL/ICC)
: [[インテル]]製のx86x64用のC言語・C++コンパイラ。{{lang|en|Windows}}・{{lang|en|Linux}}・{{lang|en|[[macOS]]}}向けがある。gcc互換。
: [[インテル]]製の[[IA-32]] ([[x86]]) および[[Intel 64]] ([[x64]]) 用のC/C++コンパイラ。Windows/Linux/[[macOS]]/[[Android (オペレーティングシステム)|Android]]向けがある。gcc互換。
: バージョン11.1までは[[IA-64]] ([[Itanium]]) をサポートするが、バージョン12.0以降ではサポートされない<ref>[http://registrationcenter-download.intel.com/akdlm/irc_nas/2371/w_ccompxe_2011.7.258_Release_Notes_ja_JP.pdf インテル® C++ Composer XE 2011 Windows* 版インストール・ガイドおよびリリースノート - w_ccompxe_2011.7.258_Release_Notes_ja_JP.pdf]</ref>。
; {{lang|en|Open Watcom C/C++}}
: C99<ref>[https://software.intel.com/en-us/articles/c99-support-in-intel-c-compiler C99 Support in Intel® C++ Compiler | Intel® Software]</ref>とC11<ref>[https://software.intel.com/en-us/articles/c11-support-in-intel-c-compiler C11 Support in Intel C++ Compiler | Intel® Software]</ref>の対応リストが公開されている。バージョン18.0でC11にほぼ対応している。
: {{lang|en|Windows}}・{{lang|en|Linux}}・{{lang|en|[[OS/2]]}}・{{lang|en|MS-DOS}}・[[DOSエクステンダ|{{lang|en|DOS}}エクステンダ]]を対象とするx86用C言語・C++コンパイラ。商用だった{{lang|en|Watcom C/C++}}がオープンソース化したもの。
; Open Watcom C/C++
; {{lang|en|[[Portable C Compiler]]}}
: gccが普及する以前の{{lang|en|UNIX}}における標準的C言語コンパイラ。現在は[[オープンソース]]
: Windows・Linux・[[OS/2]]・MS-DOS・[[DOSエクステンダ]]を対象とするx86用C言語・C++コンパイラ。商用だったWatcom C/C++がオープンソース化したもの
; [[Portable C Compiler]]
; {{lang|en|Digital Mars C/C++}}
: gccが普及する以前のUNIXにおける標準的C言語コンパイラ。現在は[[オープンソース]]。
: {{lang|en|Windows}}・{{lang|en|MS-DOS}}・{{lang|en|DOS}}エクステンダを対象とする x86用のC言語・C++コンパイラ。無料版もある。[[ウォルター・ブライト]]作で{{lang|en|Datalight C}}、{{lang|en|Zorland C}}、{{lang|en|Zortech C/C++}}、{{lang|en|Symantec C/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用(クロスコンパイラ)===
===組み込み用、8ビット・16ビット・32ビット・64ビットCPU用(クロスコンパイラ)===
; {{仮リンク|Green Hills Software C/C++|en|Green Hills Software}}
; {{lang|en|[[GreenHILS|GreenHILS C/C++]]}}
: 組み込み向けのC言語・C++コンパイラ。 {{lang|en|Windows}}用・{{lang|en|[[Solaris]]}}用・{{lang|en|[[Linux]]}}用があり、{{lang|en|HP/UX}}用がver4ではあった。
: 組み込み向けのC言語・C++コンパイラ。 Windows用・[[Solaris]]用・[[Linux]]用があり、HP/UX用がver4ではあった。
; {{lang|en|[[CodeWarrior|CodeWarrior C/C++]]}}
; [[CodeWarrior|CodeWarrior C/C++]]
: 組み込み向けやゲーム機開発向けのC言語・C++コンパイラ。{{lang|en|[[Classic Mac OS]]}}用として発祥、かっては{{lang|en|Windows}}用・{{lang|en|[[BeOS]]}}用・{{lang|en|[[Palm]]}}用もあった。
: 組み込み向けやゲーム機開発向けのC言語・C++コンパイラ。[[Classic Mac OS]]用として発祥、かってはWindows用・[[BeOS]]用・[[Palm (PDA)|Palm]]用もあった。
; {{lang|en|[[ARMアーキテクチャ|ARM C/C++]]}}
; [[ARMアーキテクチャ|ARM C/C++]]
: ARM CPU用C言語・C++コンパイラ。
: ARM CPU用C言語・C++コンパイラ。
; {{lang|en|[[IARシステムズ|IAR C/C++]]}}
; [[IARシステムズ|IAR C/C++]]
: 新旧の組み込み向けCPU各種を広くカバーする現在は統合開発環境EW・SWに移行。ARM CPU用C言語・C++コンパイラが著名。ARMをコアにした各社のCPUに対応している。
: 新旧の組み込み向けCPU各種を広くカバーしていた後に統合開発環境EW・SWに移行。使用には付属の[[ドングル]]が必要だった。ARM CPU用C言語・C++コンパイラが著名。ARMをコアにした各社のCPUに対応している。
; {{lang|en|High C}}
; High C
: 元はx86向けで[[PC/AT互換機]]用だが[[Intel 80386|80386]]のネイティブモードに対応したため{{lang|en|[[FM TOWNS]]}}でも標準開発環境、「{{lang|en|High C 386}}」として使用された。現在は各社[[RISC]]向け。
: 元はx86向けで[[PC/AT互換機]]用だが[[Intel 80386|80386]]のネイティブモードに対応したため[[FM TOWNS]]でも標準開発環境、「High C 386」として使用された。後に各社[[RISC]]向けとなる
; [[BDS-C]]
; [[BDS-C]]
: [[CP/M]](8080・Z80)用のサブセット(整数のみ)の{{lang|en|K&R}}系のC言語コンパイラ。現在は[[パブリックドメインソフトウェア]]。
: [[CP/M]](8080・Z80)用のサブセット(整数のみ)のK&R系のC言語コンパイラ。現在は[[パブリックドメインソフトウェア]]。
; {{lang|en|Hitech-C}}
; Hitech-C
: [[Z80]]、[[PIC (コントローラ)|PIC]]など。
: [[Z80]]、[[PIC (コントローラ)|PIC]]など。
; {{lang|en|Lattice C}}
; Lattice C
: 1980年代に、日本で高い普及率を見せたコンパイラ。解説書も多く出版されていた。日本での発売はライフボート。初期版はマイクロソフトCコンパイラ1.0として発売された。商用利用のできない個人向けの「{{lang|en|personal}}」版も販売されており、これの価格は19,800円であった<ref>{{Cite book ja-jp|year=1987|author=脇英世(監修)|title=パソコンの常識事典|publisher=日本実業出版社|pages=339、342}} - 普及率、解説書の多さについて。</ref><ref>{{Cite book ja-jp|title=パソコンベストソフトカタログ|editor=長沢英夫|year=1988|publisher=JICC出版局|pages=201}} - {{lang|en|Personal}}版、解説書の多さについて。</ref>
: 1980年代に、日本で高い普及率を見せたコンパイラ。解説書も多く出版されていた。日本での発売はライフボート。初期版はマイクロソフトCコンパイラ1.0として発売された。商用利用のできない個人向けの「personal」版も販売されており、これの価格は19,800円であった<ref>{{Cite book ja-jp|year=1987|author=脇英世(監修)|title=パソコンの常識事典|publisher=日本実業出版社|pages=339、342}} - 普及率、解説書の多さについて。</ref><ref>{{Cite book ja-jp|title=パソコンベストソフトカタログ|editor=長沢英夫|year=1988|publisher=JICC出版局|pages=201}} - Personal版、解説書の多さについて。</ref>
; LSI C
; LSI C
: [[Intel 8080|8080]]・[[Z80]]用のLSI C-80(セルフ版・クロス版。現在はクロス版のみ)と、8086用の[[LSI C-86]]がある。8086では機能限定([[Intel 8086#プログラミングモデル|スモールモデル]]のプログラムしか開発できず、[[デバッガ]]がない)の「試食版」が[[フリーウェア|フリーソフト]]で公開され、広く使われた。
: [[Intel 8080|8080]]・[[Z80]]用のLSI C-80(セルフ版・クロス版。現在はクロス版のみ)と、8086用の[[LSI C-86]]がある。8086では機能限定([[Intel 8086#プログラミングモデル|スモールモデル]]のプログラムしか開発できず、[[デバッガ]]がない)の「試食版」が[[フリーウェア|フリーソフト]]で公開され、広く使われた。
; micro-C
: 8ビット・マイクロプロセッサ[[MC6809]]用C言語サブセット・コンパイラ{{Sfn |ucom10 |1983 |p=80}}。
; Small-C
: 元は8080向けの小型のC言語コンパイラだが派生版のクロスコンパイラとしてcc65([[MOS6502]]用)や、[[z88dk]]などがある。
; SDCC
: 各種8ビット・マイクロプロセッサ向けのフリーソフトウェア([[GPL]])のC言語クロスコンパイラ。


== 関連する主なプログラミング言語 ==
== 関連する主なプログラミング言語 ==
=== 先祖 ===
=== 先祖 ===
; {{lang|en|[[ALGOL]]}}
; [[ALGOL]]
: ヨーロッパ生まれのアルゴリズム記述言語。{{lang|fr|[[Pascal]]}}やC言語などに影響を与えたとされる。
: ヨーロッパ生まれのアルゴリズム記述言語。[[Pascal]]やC言語などに影響を与えたとされる。
; [[BCPL]]
; [[BCPL]]
: {{lang|en|[[MULTICS]]}}で作成された高級言語。
: [[MULTICS]]で作成された高級言語。
; [[B言語]]
; [[B言語]]
: 初期の{{lang|en|UNIX}}で作成されたインタプリタ方式の高級言語。BCPLを元に作られ、Cの原型となった。
: 初期のUNIXで作成されたインタプリタ方式の高級言語。BCPLを元に作られ、Cの原型となった。


=== 継承・拡張・[[サブセット]] ===
=== 継承・拡張・サブセット ===
; [[C++]]
; [[C++]]
: C言語を拡張して[[オブジェクト指向]]化したもの。当初はC言語の[[スーパーセット]]だったが、現在は細かい部分において非互換仕様が増えている。
: C言語を拡張して[[オブジェクト指向]]化したもの。[[Simula]]の影響を強く受けている。当初はC言語の[[スーパーセット]]だったが、現在は細かい部分において非互換仕様が増えている。
; {{lang|en|[[Java]]}}
; [[Objective-C]]
: C++よりも言語文法レベルでオブジェクト指向を重視した言語[[バッファオーバーラン]]など危険性が高いポインタといっローレベル要素を言語文法から排除る。[[仮想マシン]](Java VM, JVM)上で動作する
: C言語を拡張してオブジェクト指向したもの。C言語[[Smalltalk]] オブジェクトシステムを取り付けよう設計で、互換性は保たれている。C言語からの拡張部分がC++と干渉ため、C++と混在した記述が可能
; {{lang|en|[[C Sharp|C#]]}}
; [[Java]]
: C++よりも言語文法レベルでオブジェクト指向を重視した言語。[[バッファオーバーラン]]などの危険性が高いポインタといったローレベルな要素を言語文法から排除している。[[仮想マシン]]([[Java VM]], JVM)上で動作する。
; [[C Sharp|C#]]
: [[マイクロソフト]]が[[.NET Framework]]向けに開発した言語。文法はC言語およびC++に近い書式を持ち、Javaと似ている部分も存在するが、機能的には[[Delphi]]がベースとなっている。
: [[マイクロソフト]]が[[.NET Framework]]向けに開発した言語。文法はC言語およびC++に近い書式を持ち、Javaと似ている部分も存在するが、機能的には[[Delphi]]がベースとなっている。
; [[Cg (プログラミング言語)|Cg]]
; [[Rust (プログラミング言語)|Rust]]
: C言語およびC++に代わる[[システムプログラミング言語]]を目指している言語。言語レベルでの[[RAII]]の強制による自動メモリ管理機構を持ち、[[ガベージコレクション]]無しでも手動のメモリ管理が不要であり、実行性能はC/C++と同等である。
:C言語を[[Graphics Processing Unit|GPU]]上での[[3次元コンピュータグラフィックス]]処理用に特化させたもの([[シェーダー]]言語、[[シェーディング言語]])。[[NVIDIA]]によって開発された。
; {{lang|en|[[Cyclone (プログラミング言語)|Cyclone]]}}
; {{仮リンク|Cyclone (プログラミング言語)|label=Cyclone|en|Cyclone (programming language)}}
:C言語の上位互換セキュア実装。ポインタの扱いを厳格化して安全面に配慮して拡張したもの。その他リージョンベースメモリ管理システム、[[正規表現]]、タグ付共用体などを追加している。
: C言語の上位互換セキュア実装。ポインタの扱いを厳格化して安全面に配慮して拡張したもの。その他リージョンベースメモリ管理システム、[[正規表現]]、タグ付共用体などを追加している。
; {{lang|en|[[Objective-C]]}}
; [[SystemC]]
: [[ハードウェア記述言語]]向けに拡張したもの。書式はC++。IEEE 1666-2005。ISO 8866:1991。
:C言語を拡張してオブジェクト指向化したもの。C言語に {{lang|en|[[Smalltalk]]}} のオブジェクトシステムを取り付けたような設計で、互換性は保たれている。C言語からの拡張部分がC++と干渉しないため、C++と混在した記述が可能。
; {{lang|en|[[SystemC]]}}
; {{仮リンク|Impulse C|en|Impulse C}}
: [[ハードウェア記述言語]]向けに拡張したもの。書式はC++。EEE 1666-2005。ISO 8866:1991。
; {{lang|en|[[Impulse_C]]}}
: [[ハードウェア記述言語]]向けに拡張したもの。書式はC。
: [[ハードウェア記述言語]]向けに拡張したもの。書式はC。
; {{lang|en|[[Unified Parallel C]]}}
; [[Unified Parallel C]]
: [[並列計算]]向けに[[C99]]を拡張して作られた言語。
: [[並列計算]]向けに[[C99]]を拡張して作られた言語。
; [[Cg (プログラミング言語)|Cg]]
: C言語を[[Graphics Processing Unit|GPU]]上での[[3次元コンピュータグラフィックス]]処理用に特化させたもの([[シェーダー]]言語、[[シェーディング言語]])。[[NVIDIA]]によって開発された。


その他にも、[[OpenGL]]シェーダー言語である[[GLSL]]、[[DirectX]]([[Direct3D]])シェーダー言語である[[HLSL]]、[[OpenCL]]カーネル記述言語であるOpenCL-Cなど、C言語の文法的特徴を取り入れた派生言語や[[ドメイン固有言語|DSL]]が多数存在する。
その他にも、[[OpenGL]]シェーダー言語である[[GLSL]]、[[DirectX]]([[Direct3D]])シェーダー言語である[[HLSL]]、[[OpenCL]]カーネル記述言語であるOpenCL-Cなど、C言語の文法的特徴を取り入れた派生言語や[[ドメイン固有言語|DSL]]が多数存在する。

==注釈・出典==
===注釈===
{{Notelist}}
===出典===
{{Reflist}}


==参考文献==
==参考文献==
290行目: 372行目:
; [[プログラミング言語C]]
; [[プログラミング言語C]]
: ブライアン・カーニハン、デニス・リッチー 共著、[[石田晴久]]訳、[[共立出版]]。
: ブライアン・カーニハン、デニス・リッチー 共著、[[石田晴久]]訳、[[共立出版]]。
: 「{{lang|en|K&R}}」として知られている「{{lang|en|The C Programming Language}}」の邦訳。入門書ではなく、特にプログラミングそのものが初めてという読者には不適である。初版と2版があり、2版が現在も時折増刷ている(邦訳では事情により、原書2版を基とした版には旧版と改訂新版がある。旧版は装丁が緑地で新版は白地である)。標準の制定以前は本書初版を言語仕様の参考文献として扱っていたが、現在は規格を参照すべきであり、本書の記述は参考にとどめるべきである。
: 「K&R」として知られている「The C Programming Language」の邦訳。入門書ではなく、特にプログラミングそのものが初めてという読者には不適である。初版と2版があり、2版が現在も時折増刷されている(邦訳では事情により、原書2版を基とした版には旧版と改訂新版がある。旧版は装丁が緑地で新版は白地である)。標準の制定以前は本書初版を言語仕様の参考文献として扱っていたが、現在はISOなどの標準規格を参照すべきであり、本書の記述は参考にとどめるべきである。なお、日本工業規格(現・日本産業規格)のJIS X 3010:2003「プログラム言語C」は、ISO/IEC JTC1 SC22 WG14+ISO/IEC 9899:1999 Cor. 1:2001(E)つまりC99の和訳相当で、2021年8月現在の最新規格であるISO/IEC 9899:2018との乖離を生じている。
; [[Cプログラの落とし穴]]
; {{仮リンク|Cプログラミングの落とし穴|en|C Traps and Pitfalls}}
: コーニグ、中村明訳、新紀元社
: コーニグ、中村明訳、新紀元社
: Cプログラミングで嵌まるところを指摘している。MISRA Cでも参考文献になっている。
: Cプログラミングで嵌まるところを指摘している。MISRA Cでも参考文献になっている。
297行目: 379行目:
: アラン・R. フューアー、田中和明訳、カットシステム
: アラン・R. フューアー、田中和明訳、カットシステム
: Cプログラミングの芸当を示し、読み書きを推奨しない例を示している。
: Cプログラミングの芸当を示し、読み書きを推奨しない例を示している。
; {{Cite book|和書

| author=
==脚注==
|title=マイコンピュータ No.10
{{Reflist}}
| year=1983
| date=1983-9-1
|publisher=[[CQ出版社]]|isbn =
| ref={{Sfnref |ucom10 |1983}} }}
: 入門特集 C言語の研究


==外部リンク==
==外部リンク==
{{Commons-inline}}
* {{lang|en|[http://www.open-std.org/jtc1/sc22/wg14/ ISO C Working Group]}}
; 日本語
* {{lang|en|[https://www.bell-labs.com/usr/dmr/www/chist.html The Development of the C Language]}} - C言語がどのように開発されたかがわかる文書
* [https://ja.cppreference.com/w/c C言語リファレンス - cppreference.com] - 標準C/C++のオンライン言語リファレンス{{Ja icon}}
* {{lang|en|[http://code-reference.com/c/stdio.h stdio.h on Coding Programmer Page / C Library Reference and Examples] }} - C Reference
; 英語
* [https://www.open-std.org/jtc1/sc22/wg14/ ISO C Working Group]{{En icon}}
* [https://www.bell-labs.com/usr/dmr/www/chist.html The Development of the C Language] - C言語がどのように開発されたかがわかる英文の文書
* [https://code-reference.com/c/stdio.h stdio.h on Coding Programmer Page / C Library Reference and Examples] - C Reference{{En icon}}


{{CProLang}}
{{CProLang}}
{{プログラミング言語一覧}}
{{プログラミング言語一覧}}
{{authority control}}

{{DEFAULTSORT:Cけんこ}}
{{DEFAULTSORT:Cけんこ}}
[[Category:C言語|*]]
[[Category:C言語|*]]
[[Category:UNIX]]
[[Category:UNIX]]
[[Category:JIS|X3010]]
[[Category:JIS]]
[[Category:基本情報技術者試験]]
[[Category:デニス・リッチー]]

2024年11月10日 (日) 04:00時点における最新版

C言語
C言語
C言語のロゴ
パラダイム 命令型プログラミング構造化プログラミング手続き型プログラミング ウィキデータを編集
登場時期 1972年 (52年前) (1972).
開発者 ベル研究所デニス・リッチー米国国家規格協会国際標準化機構ケン・トンプソン ウィキデータを編集
最新リリース ISO/IEC 9899:2024/ 2024年10月31日 (45日前) (2024-10-31)
型付け 弱い静的型付け
主な処理系 GCC, Clang, Visual C++, Intel C++ Compiler
影響を受けた言語 ALGOL 68、B言語アセンブリ言語FORTRANPL/ICPLBCPL、ALGOL 60、ALGOL ウィキデータを編集
影響を与えた言語 awkcshC++Objective-CRustD言語JavaJavaScriptLimbo
プラットフォーム Microsoft WindowsUnix系 ウィキデータを編集
ウェブサイト
拡張子 .c, .h
テンプレートを表示

C言語(シーげんご、: C programming language)は、1972年AT&Tベル研究所デニス・リッチーが主体となって開発した汎用プログラミング言語である。英語圏では「C language」または単に「C」と呼ばれることが多い。日本でも文書や文脈によっては同様に「C」と呼ぶことがある。制御構文などに高水準言語の特徴を持ちながら、ハードウェア寄りの記述も可能な低水準言語の特徴も併せ持つ。基幹系システムや、動作環境の資源制約が厳しい、あるいは実行速度性能が要求されるソフトウェアの開発に用いられることが多い。後発のC++JavaC#など、「C系」と呼ばれる派生言語の始祖でもある[注釈 1]

ANSIISO、またJISにより言語仕様が標準規格化されている。

特徴

[編集]

Cには他のプログラミング言語と比較して、特筆すべきいくつかの特徴がある。

利点

[編集]

欠点

[編集]
  • 開発時期が古いことから、言語構文(文法)に機械語の影響が強く、仕様自体は単純ではあるが明快ではなく難解である。この欠点を改良するためのちに開発された後発言語に比較し、プログラマが記述しなければならないことが多く、低水準言語のように面倒で習得しにくい側面を持つ。
  • Cは、移植の容易性、自由度、実行速度、コンパイル速度などを追求した。代わりにコンパイル後のコードの安全性を犠牲にしている。また、詳細を規格で規定せず処理系に委ねている部分が多く、Cで書かれたソフトウェアでは処理系依存のコードが氾濫する原因となった。セキュリティ上の脆弱性や潜在的バグによる想定外の動作、コンパイラによる最適化の難しさ[注釈 2]といった問題を抱えており、最適化するとコンパイル速度が遅くなるなどの問題が生じることがある。

上記のように、利点でもあり、同時に欠点にもなる特徴を備えている。

もともとUNIXおよびCコンパイラの移植性を高めるために開発されてきた経緯から、オペレーティングシステム(OS)のカーネルおよびコンパイラ向けの低水準な記述ができるなど、ハードウェアをある程度抽象化しつつも、必要に応じて低水準言語と同じことを実現できるようなコンピュータ寄りの言語仕様になっている。そのため、低水準な記述ができる高水準言語と言われたり、高水準言語の顔をした低水準言語(高級アセンブラ[2]、汎用アセンブラ[3])と言われたりすることがある。

Cはアマチュアからプロ技術者まで、プログラマ人口が多く、プログラマのコミュニティが充実している。使用者の多さから、正負の両面含め、Cはプログラミング文化に大きな影響を及ぼしている。また、多目的性と、対応機器の多彩さのため、「コンピュータを使ってやること」は大抵、Cで対応可能である。ただし、Cで効率的かつ安全に記述できるかどうかはまた別の話である。スクリプト言語やコマンドラインシェルを使えば手軽に実現にできるような処理まで、わざわざCで記述する必要はない。また、GUIアプリケーションフレームワークは、Cからは利用できず、統合開発環境と連携する新しいプログラミングツールやプログラミングパラダイムに対応した後発言語でなければ利用できないものもある。

MISRA CCERT Cというコーディング標準(コーディング規約)を定義して、危険な機能の使用や記述を禁止するという制限を設けることでCを安全に利用するためのガイドラインが運用されている分野もある。特にプログラミングミスが人命に直結する自動車分野などでCを利用するには、このような制約が重要である。

機能と自由度

[編集]
  • 文の区切りを終端記号 セミコロン;」で表し、改行文字にも空白にもトークンの区切りとしての意味しか持たせない「フリーフォーマット」という形式を採用している。中括弧{ }によるブロック構造およびスコープをサポートする。
  • ALGOLの思想を受け継いで構造化プログラミングに対応している。手順を入れ子構造で示して見通しの良い記述をすることができる。原理的に無条件分岐(gotoを使用する必要はなく、MISRA Cでは当初goto文を禁止していた。
  • モジュール化ファイルを単位として可能。モジュール内だけで有効な名前を使うことができるスコープを持っている。
  • プログラムを戻り値つきのサブルーチンに分離できる。C言語ではこれを関数と呼び、関数内のプログラムコードでは、独立したスコープを持つ変数(ローカル変数)が使用できる。これにより、データの流れがブロックごとに完結するのでデバッグが容易になり、また関数の再帰呼び出しも可能となる。また、多人数での共同開発の際にも変数名の衝突が回避しやすくなる。なお、C言語ではUNIXのようなOSを前提としたホスト環境と、割り込み制御のようなOSを前提としないフリースタンディング環境とがある。ホスト環境では、プログラム開始直後に実行するプログラム要素を main という名前の関数として定義する[注釈 3]。プログラム中で再帰的にmain関数を呼ぶことも可能(C++では不可能[4][5])。フリースタンディング環境では、エントリーポイントと呼ばれるアドレスに置かれたコードをプログラムの開始点とするが、それがmain関数である必要はない。なお再帰呼び出しそのものは、スタックオーバーフローの原因となるため、MISRA Cでは禁止している。
  • システム記述言語として開発されたため、高級言語であるがアセンブラ的な低水準の操作ができる。ポインタ演算ビットごとの論理演算シフト演算などの機能を持ち、ハードウェアに密着した処理を効率よく記述できる。これはオペレーティングシステムやデバイスドライバーなどを記述する上では便利であるが、注意深く利用しないと発見しにくいバグの原因となる。ライブラリ関数は、C言語規格が規定している関数と、OSが規定している関数との間の整合性、棲み分けなどが流動的である。MISRA Cのようないくつかの制約では、C言語規格が規定している関数の妥当性について指摘し、いくつかの関数を利用しないように規定している。
  • ソースコードの記述に使う文字集合はANSI C (C89) およびISO/IEC 9899:1990 (C90) ではASCIIを標準としている。他のISO 646でも書けるように、3文字利用したトライグラフと呼ばれる表記法も存在する。その後、ISO/IEC 9899:1995 AMD (C95) などではマルチバイト文字セット対応の拡張を規定している。さらに、その後トライグラフは複数のコードを利用したシステムでしか利用がない[要説明]ため、より分かり易い2文字によるダイグラフを規定している。
  • 組み込みの整数型および浮動小数点数型のほか、構造体共用体、列挙体(列挙型)によるユーザー定義のデータ型や列挙定数をサポートする。構造体および共用体はビットフィールドをサポートする。

アセンブラとのインタフェース

[編集]
  • 多くの処理系がインラインアセンブラを搭載しているほか、アセンブラで出力したオブジェクトとのリンクが容易になっている。これにより速度が要求される部分だけをアセンブリ言語で記述するということが容易に行えることが多い。アセンブラとのインタフェースは#pragma asmなどを用いて局所化を図る努力はあるが、コンパイラごとに定義があり、CPUが同一であっても移植性が低い場合がある。

コンパイラ仕様

[編集]
  • コンパイラの処理が1パスで済む仕様になっている。歴史的な経緯から、変数の宣言において型指定がない場合はint型とみなし、関数の戻り値の型指定がない場合はint型とみなす。ANSI C (C89) ではコンパイル時型検査の強化のために関数プロトタイプの機能が導入されたが、関数の宣言がない場合の戻り値int型とみなし、引数は未知(任意)とみなす。しかし、このような暗黙の型指定は型安全性を損ない未定義動作を引き起こす危険性があるため、ISO/IEC C:1999 (C99) 以降では暗黙の型指定に関する仕様が標準規格の文面から削除された。いずれも使用(参照)するより前に適切に宣言する必要がある。ClangやGCCといったC99準拠のコンパイラは、このような暗黙の型指定について、C99モードであってもC89互換の動作を残してはいるものの、非標準の動作であるため警告を出すようになっている。なお、関数宣言において()のように引数を省略すると、引数を未知とする仕様はC99でも残されている。後継言語では完全なプロトタイプ宣言を必須とするか、あるいはプロトタイプ宣言自体を不要としているが、記述によっては先読みが必要になりうる。
  • マクロ記述やコンパイル条件の指定などができる前処理指令が標準化されている。前処理指令の解釈をするプリプロセッサ (preprocessor) を持っている。プリプロセッサは、その名の通りコンパイル処理の前に自動的に実行される。コンパイラの機能として、プリプロセッサを通しただけの段階のソースコードを出力可能になっているものがある。前処理の結果を検査することで、設計者の意図と前処理の結果のずれがないか確認できる。

処理系の簡素化

[編集]

処理系の簡素化と効率のために、以下のように安全性を犠牲にした仕様が多い。なお、ホスト環境やプログラムの内容によっては、以下に対して脆弱性対策を施したとしても実行速度の低下が無視できる程度であることも多く、言語仕様側の欠点とみなされることも少なくない。

配列の参照時に添字の値が範囲内にあるかを検査しない
これを要因とする代表的なバグが、固定長のバッファ領域をはみだしてデータの書き込みが行われてしまう「バッファオーバーフロー」(バッファオーバーラン)である。範囲外のアクセスは、書き込みだけでなく読み取りの場合も未定義動作を引き起こす。標準ライブラリにはバッファオーバーフローや範囲外アクセスを考慮していない関数があり、かつ多用されがちなため、しばしば脆弱性の原因となる。また、Cではプログラムにより明示的に制御(動的メモリ確保)することで可変長配列の実現を可能にしているが、確保した領域の範囲外にアクセスしても自動的な伸長は行なわれない。
後継言語では、標準ライブラリまたは組み込み型により可変長配列をサポートしていたり、範囲外アクセス時には例外(実行時エラー)を送出するなどして安全性を優先していたりすることが多い。
文字列を格納するための特別な型が存在しない
文字列にはchar型の配列を利用する。言語仕様上に特別な扱いはないが、ヌル文字'\0')を終端とする文字列表現を使い、その操作をする標準ライブラリ関数がある。これは実質的にメモリ領域へのポインタアクセスそのものであり、確保されている領域の長さよりも長い文字列を書き込めてしまうために、バッファオーバーランの元凶の1つとなっている。
後継言語では文字列処理を特に強化している場合が多く、標準ライブラリあるいは言語仕様による組み込みの文字列型を提供している。
自動変数(auto variable)の自動的な初期化をしない
自動変数(静的でないローカル変数)は変数の中でも最も頻繁に用いられる。初期化されていない変数を参照した場合にはその値は不定であるが、不定な値へのアクセスは未定義動作であるので、コンパイラ最適化の過程で想定しない形に改変することもある[6]。変数宣言・初期化の仕様による制限から、変数宣言の時点では初期化をせずに後で代入等により値を入れてつかうことが普通なので、誤って不定の値の変数を読み出すバグを作り込みやすい。なお自動変数の自動とは変数の領域の確保と解放が自動であるという意味であり、自動的に初期化されるという意味ではない。
後継言語では、明示的な初期化が記述されていない変数は、不定値ではなくその変数の型の既定値(ゼロあるいはゼロ相当の値)で初期化される仕様になっていることが多い。

その他

[編集]
  • ソースコード上の文字の大文字・小文字を区別する。
  • 入出力動的メモリ確保を含めほとんどの機能が、C言語自身で書かれたライブラリによって提供される。このことは、C言語の機種や環境依存性が低く、それらに依存する箇所をライブラリへ分離することにより移植性(ポータビリティ)が高いことを意味する[要出典]。さまざまな機種があるUNIXの世界でC言語が普及した理由のひとつである。
    • 例として、POSIX環境での動的メモリ確保はmallocおよびその類似関数にて提供される。一方、カーネルではメモリ確保の際にスレッドがブロックされるとカーネル内のデータが他のスレッドにより変更され、予期せぬ動作を起こす恐れがあることや、メモリ内容の初期化が必要かどうかによって割当先のページを選択することによりシステムの効率が上がることから、多くの場合POSIXとは異なるAPIを使用している。Linuxカーネルの場合、前者はフラグGFP_KERNELGFP_ATOMICの使い分け、後者は関数kmalloc(割り当てたメモリの内容は不定)とkzalloc(割り当てたメモリの内容はゼロクリア済)の使い分けにより実装している[7]
  • プログラムの実行に必要とするハードウェア資源が、アセンブラよりは多いが他の高級言語より少なくてすむため、現在さまざまな電化製品などの組み込みシステムでも使用されている。
  • 組み込み向けの場合は、プログラミング言語として、アセンブラ以外ではCとC++しか用意されていないことがある。その場合、他のプログラミング言語は、CやC++で書かれた処理系が存在すればコンパイルすることにより利用可能となることもあるが、メモリ制約などで動作しないことがある。
  • ANSI/ISOにより規格が標準化された後は言語仕様の変化が小さく安定していること、C言語のプログラマ人口やコード資産が多いこと、C++Objective-CからC言語関数を直接利用できること、また必要に応じて他のプログラミング言語からC言語関数を呼び出すためのバインディングを記述することが容易であることなどから、APIの外部仕様としてC言語の関数インターフェイスが選ばれることが多い。例えばOpenGLOpenCLのようなオープン規格は第一級言語としてC言語を採用している。

コード例

[編集]

Hello worldプログラム

[編集]

C言語のHello worldプログラムは、ホスト環境を前提とするか、フリースタンディング環境を前提とするかで、方向性が異なる。ホスト環境を前提とする場合には、標準入出力の利用により、動作をすぐに確かめることができる。以下では、標準Cライブラリヘッダstdio.hにて宣言されている、puts関数あるいはprintf関数を利用したものを例示する。

/* int puts(const char* s) を使う場合。 */
#include <stdio.h>

int main(void)
{
    puts("Hello, world!");
    return 0;
}
/* int printf(const char* format, ...) を使う場合。 */
#include <stdio.h>

int main(int argc, char* argv[])
{
    printf("Hello, world!\n");
    return 0;
}

上記サンプルソース中の「\n」は、エスケープ文字\によるエスケープシーケンスのひとつであり、改行(ラインフィード)を表す。

main関数は標準的なプログラムエントリーポイントであり、プログラムを開始すると、ランタイムライブラリによるスタートアップ処理が実行された後にこのmain関数が呼ばれる。引数のないバージョンと、コマンドライン引数をポインタ配列として受け取るバージョンどちらを使ってもよい[8]

なお、printf関数は書式文字列とそれに対応する可変個引数を受け取り、書式化された文字列として表示できる高機能な標準出力関数であるが、序盤から例示に使用している入門書もある。

main関数とprintf関数は、いずれも入門者や初学者にとっては最初の関門となる難解な関数であり、C言語によるプログラミングのハードルを高くしている一因でもある[9][10]JavaC#のような後発言語では、文字列の扱いや、可変個引数の扱いがより簡潔で安全になっている。Pythonのようなインタプリタや対話環境上で動作することを前提とした言語では、main関数を定義する必要はない。

主な制御構造

[編集]

主な標準ライブラリ関数

[編集]

歴史

[編集]

誕生

[編集]

C言語は、AT&Tベル研究所のケン・トンプソンが開発したB言語の改良として誕生した(#外部リンクの「The Development of the C Language」参照)。

1972年、トンプソンとUNIXの開発を行っていたデニス・リッチーはB言語を改良し、実行可能な機械語を直接生成するC言語のコンパイラを開発した[11]。後に、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のカーネルを作成するための言語という意味ではない[12]
  • B言語の欠点を解消するため、1971年に改良作業を開始した。
  • 1972年にC言語のコンパイラができあがり、UNIXバージョン2において、いくつかのユーティリティを作成するために使用された。

UNIX環境とC言語

[編集]

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

C言語誕生時の環境と他言語との比較

[編集]

C言語の開発当初に使われた入力端末はASR-37英語版であったことが知られている[12]。 ASR-37は1967年制定の旧ASCII ISO R646-7bitにもとづいており、「{」および「}」の入力を行うことができたが、当時は一般的に使われていた入力端末ではなかった。 当時PDP-11の入力端末として広く使われていたのはASR-33であるが、これは1963年制定の旧ASCIIであるASA X3.4に準拠しており、「{」や「}」の入力を行うことはできなかった[14]

このことは、ブロック構造に「{」や「}」を用いるC言語(さらに元をたどればB言語)は、当時の一般的な環境では使用不可能であったことを示している。 これは、C言語はその誕生当初にあっては一般に広く使われることを想定しておらず、ベル研究所内部で使われることを一義的に考えた言語であったという側面の表れである。

これに対し、PascalBASIC等の当初から広く使われることを想定した言語では、ブロック構造に記号を用いずにbeginendをトークンとして用いることや、コメント行を表す際に開始トークンとしてREMという文字列を用いることなど、記号入力に制約がある多くの入力端末に対応できるように配慮されていた。この頃の他の言語やOSで大文字と小文字の区別をしないものが多いのも、当時は大文字しか入力できない環境も少なくなかったことの表れである。

このような事情のため、C言語が普及するのは、ASCII対応端末が一般化した1980年代に入ってからである。

現在、ブロック構造の書式等で、{...}形式のC言語と、begin...end等を使用する他の言語との比較において優劣を論じられることがあるが、開発時の環境等をふまえずに現時点での利便性のみで論じるのは適切ではない場合があることに留意が必要である。

PCとC言語

[編集]

1980年代に普及し始めたパーソナルコンピュータ (PC) は当初、8ビットCPUでROM-BASICを搭載していたものも多く、BASICが普及していたが、1980年代後半以降、16ビットCPUを採用しメモリも増えた(ROM-BASIC非搭載の)PCが主流になりだすと、Turbo CやQuick Cといった2万円程度の比較的安価なコンパイラが存在したこともあり、ユーザーが急増した。8ビットや8086系のPCへの移植は、ポインタなどに制限や拡張を加えることで解決していた。

現在のC言語

[編集]

1990年代中盤には、最初に学ぶプログラミング言語としても主流となった。また、同時期にはゲーム専用機(ゲームコンソール)の性能向上とプログラムの大規模化、マルチプラットフォーム展開を受け、メインの開発言語がアセンブラからC言語に移行した。

1990年代後半から2000年代以降は、PCのさらなる性能向上と普及、GUI環境やオブジェクト指向の普及、インターネットおよびウェブブラウザの普及、スマートフォンの普及に伴い、より高水準で開発効率の高い言語やフレームワークを求める開発者が増えたことにより、C++Visual BasicJavaC#Objective-CPHPJavaScriptなどが台頭してきた。広く利用されるプログラミング言語の数は増加傾向にあり、相対的にC言語が使われる場面は減りつつある。特にアプリケーションソフトウェアなどの上位層の開発には、C言語よりも記述性に優れるC++、Java、C#などC言語派生の後発言語が利用されることが多くなっている。資源制約の厳しかったゲーム開発においても、ハードウェアの性能向上やミドルウェアの普及により、C++やC#などが使われる場面が増えている。速度性能や省メモリが特に重視されるシステムプログラミングに関しても、伝統的にC/C++の独壇場だったが、新規コードではより安全性の高いRustを導入する事例が現れている[15][16]

しかし、C言語は比較的移植性に優れた言語であり、個人開発/業務用開発/学術研究開発やプロプライエタリオープンソースを問わず、オペレーティングシステムやデバイスドライバーなどの下位層、クロスプラットフォームAPIの外部仕様、C++やJavaなどの高水準言語の処理系および実行環境の実装が困難な小規模の組み込みシステムなどを中心に、2021年現在でも幅広く利用されている。

プログラミング入門者にとっては、Python、JavaScript、SwiftKotlinなどのように、インタラクティブな対話環境(REPLインタプリタ)が利用でき、抽象化が進んでおり、煩雑なメモリ管理が不要で、危険な機能を制限した高水準言語のほうが学習・習得しやすいが、コンピュータの動作原理やハードウェア仕様を理解するには、Cのような原始的な言語を用いたほうがかえって分かりやすいケースもある。

規格

[編集]

K&R

[編集]

米国国家規格協会(ANSI)による標準化が行われるまで、1978年出版のデニス・リッチーブライアン・カーニハンの共著『The C Programming Language』が実質的なC言語の標準として参照されてきた。この書籍は、著者らのイニシャルを取って「K&R」とも呼ばれている。C言語は発展可能な言語で、K&Rの記述も発展の可能性のある部分は厳密な記述をしておらず、曖昧な部分が存在していた。そのため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 X 3010-1993 プログラム言語C』として、1993年10月に制定した。

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

規格では以下の3種類の自由を認めている部分がいくつかある[17]

  • 規格で定義しないことを決めている「未定義」 (undefined)
  • 規格で選択肢を定義したもののどれにするかを決めておらず、処理系が選択する必要があるが、文書化の必要はない「未規定」 (unspecified)
  • 処理系ごとに決めて文書化する必要のある「処理系定義」 (implementation-defined)

これにより、プラットフォームやプロセッサアーキテクチャとの相性による有利不利が生じないような仕様になっている。

8ビット/16ビット/32ビットなど、レジスタ幅(ワードサイズ)の異なるプロセッサ (CPU) に対応・最適化できるようにするため、組み込み型の情報量(大きさ)や内部表現にも処理系の自由を認めている。型のバイト数はsizeof演算子で取得し、各型の最小値・最大値はlimits.hで定義されているマクロ定数で参照することとしている。ただし、1バイトあたりのビット数は規定されていない。sizeof(char) == 1すなわちchar型が1バイトであることは常に保証されるが、8ビット(オクテット)とは限らない。実際のビット数はCHAR_BITマクロ定数で取得できる。とはいえ、現実の多くの処理系ではchar型は8ビットである。また、その他の整数型については、sizeof(int) >= 2sizeof(int) >= sizeof(short)sizeof(long) >= sizeof(int)、という大小関係が定められているだけである(符号無し型も同様)。多くの処理系ではshort型のサイズは2バイト(16ビット)であるが、intlongのサイズはCPUのレジスタ幅などによって決められることが多い。int型、short型、long型で符号を明示しない場合はsignedを付けた符号付き型として扱われる。しかしchar型に関しては、signed(符号付き)にするか、それともunsigned(符号無し)にするかは処理系依存である。char型、signed char型、unsigned char型はそれぞれ異なる型として扱われる。

規格上には、BCPLやC++形式の1行コメント(//…)は無いが、オプションで対応した処理系も多く、gccやClangはGNU拡張-std=gnu89でサポートしている。

GNU Cコンパイラ や Clang では、-std=c89(または-ansiもしくは-std=c90)をつけることにより、GNU拡張を使わないC89規格に準拠したコンパイルを行うことができる[注釈 5]。加えて、-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と呼ぶ。

日本では、日本産業規格 JIS X 3010:2003「プログラム言語C」がある。

主な追加機能:

  • 変数宣言がブロックの先頭でなくても良くなった。
  • ブール代数を扱うための_Bool型が予約語に追加され、標準ライブラリとしてstdbool.hを追加した。
  • 複素数を扱うための_Complex型や_Imaginary型を予約語に追加し、標準ライブラリとして、complex.hを追加した。
  • 少なくとも64ビットの整数値を保持できる long long int型の追加。
  • オプションとして、固定幅かつ内部表現の規定された整数型の標準化(stdint.h)。
  • //による1行コメント。
  • インライン関数(inlineキーワード)。
  • 可変長配列alloca関数の代替)[18]

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)として改訂された。

C11はUnicode文字列(UTF-32UTF-16UTF-8の各符号化方式)に標準で対応している。そのほか、type-generic式、C++と同様の無名構造体・無名共用体、排他的アクセスによるファイルオープン方法、quick_exitなどのいくつかの標準関数などを追加した。

また、_Noreturn関数指示子を追加した。_Noreturnは従来処理系ごとに独自に付加していた属性情報(たとえばgccでは__attribute__((__noreturn__)))を標準化したもので、「呼び出し元に戻ることがない」という特殊な関数についてその特性を示すためにある。return文を持たない関数という意味ではなく(規格ではreturn文を持たなくとも、関数の最後の文の実行が終われば制御は呼び出し元に戻る)、_exitexecveを実行したり、例外、longjmpによる大域ジャンプ[注釈 6]などのために、制御が呼び出し元に戻らないことを明示するためにある。そのような関数は、スタックに戻りアドレスを積む通常の呼び出しではなく、スタックを消費しないジャンプによって実行できる。

C11規格では一部の機能を省略可能とした。すなわちコンパイラがC11に合致していても、一部機能は提供しないことがある。コンパイラがどの機能を提供しているかは、テスト用のマクロで判別できる。アラインメント機能や_Atomic型、C言語ネイティブの原始的なスレッド機能などが、C11では省略可能な機能として追加された。また、複素数型と可変長配列はC99では必須機能であったが、C11では省略可能である。

gets関数が廃止された。

C17

[編集]

2018年にISO/IEC 9899:2018(通称C17またはC18)として改訂された。仕様の欠陥修正がメインのマイナーアップデートである[19]

C23

[編集]

主なC言語処理系

[編集]

大抵の処理系はC言語とC++両方をサポートしている。C言語とC++の共通部分を明確にし、二つの言語の違いに矛盾が生じないようにすることが課題になっている。

Linux、Windows、UNIX用

[編集]
C++ Builder
Windows/macOS/iOS/Android対応のC/C++コンパイラBCCを含む、RADツール。以前はWindowsおよびx86のみがメインターゲットだったが、Clang/LLVMをベースに再設計され、多数のプラットフォームやアーキテクチャをサポートするようになった[20]。前身はDOS/Windows用のBorland C/C++。さらに前身としてTurbo C/C++がある。
Clang
LLVMをバックエンドとして用いるオープンソースのC/C++・Objective-Cコンパイラ。多数のCPUに対応。
GNUコンパイラコレクション (GCC)
C/C++以外の言語もサポートし、多数のCPUやオペレーティングシステムに対応、組み込み向けも含む多様な開発に広く使われるオープンソースのコンパイラ。独自拡張機能も多い。
GCC 4.5で実質的にC99を完全サポートした[21]
GCC 4.9で実質的にC11を完全サポートした[22]
Microsoft Visual C++ (MSVC)
Windows系プラットフォーム用のC/C++コンパイラ。ANSI C準拠(バージョン2013にてC99ライブラリをほぼ実装したが、言語機能など規格自体はサポートされていない)。x86・x64が主だが、Xbox 360Windows CE等向けにPowerPCARMMIPSItanium等に対応した版もある。前身としてMS-DOS・Windows用のMicrosoft C Compilerがある。またその廉価版としてQuick Cがあった[23]
Intel C++ Compiler (ICL/ICC)
インテル製のIA-32 (x86) およびIntel 64 (x64) 用のC/C++コンパイラ。Windows/Linux/macOS/Android向けがある。gcc互換。
バージョン11.1まではIA-64 (Itanium) をサポートするが、バージョン12.0以降ではサポートされない[24]
C99[25]とC11[26]の対応リストが公開されている。バージョン18.0でC11にほぼ対応している。
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用(クロスコンパイラ)

[編集]
Green Hills Software 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
Z80PICなど。
Lattice C
1980年代に、日本で高い普及率を見せたコンパイラ。解説書も多く出版されていた。日本での発売はライフボート。初期版はマイクロソフトCコンパイラ1.0として発売された。商用利用のできない個人向けの「personal」版も販売されており、これの価格は19,800円であった[27][28]
LSI C
8080Z80用のLSI C-80(セルフ版・クロス版。現在はクロス版のみ)と、8086用のLSI C-86がある。8086では機能限定(スモールモデルのプログラムしか開発できず、デバッガがない)の「試食版」がフリーソフトで公開され、広く使われた。
micro-C
8ビット・マイクロプロセッサMC6809用C言語サブセット・コンパイラ[29]
Small-C
元は8080向けの小型のC言語コンパイラだが派生版のクロスコンパイラとしてcc65(MOS6502用)や、z88dkなどがある。
SDCC
各種8ビット・マイクロプロセッサ向けのフリーソフトウェア(GPL)のC言語クロスコンパイラ。

関連する主なプログラミング言語

[編集]

先祖

[編集]
ALGOL
ヨーロッパ生まれのアルゴリズム記述言語。PascalやC言語などに影響を与えたとされる。
BCPL
MULTICSで作成された高級言語。
B言語
初期のUNIXで作成されたインタプリタ方式の高級言語。BCPLを元に作られ、Cの原型となった。

継承・拡張・サブセット

[編集]
C++
C言語を拡張してオブジェクト指向化したもの。Simulaの影響を強く受けている。当初はC言語のスーパーセットだったが、現在は細かい部分において非互換仕様が増えている。
Objective-C
C言語を拡張してオブジェクト指向化したもの。C言語に Smalltalk のオブジェクトシステムを取り付けたような設計で、互換性は保たれている。C言語からの拡張部分がC++と干渉しないため、C++と混在した記述が可能。
Java
C++よりも言語文法レベルでオブジェクト指向を重視した言語。バッファオーバーランなどの危険性が高いポインタといったローレベルな要素を言語文法から排除している。仮想マシンJava VM, JVM)上で動作する。
C#
マイクロソフト.NET Framework向けに開発した言語。文法はC言語およびC++に近い書式を持ち、Javaと似ている部分も存在するが、機能的にはDelphiがベースとなっている。
Rust
C言語およびC++に代わるシステムプログラミング言語を目指している言語。言語レベルでのRAIIの強制による自動メモリ管理機構を持ち、ガベージコレクション無しでも手動のメモリ管理が不要であり、実行性能はC/C++と同等である。
Cyclone英語版
C言語の上位互換セキュア実装。ポインタの扱いを厳格化して安全面に配慮して拡張したもの。その他リージョンベースメモリ管理システム、正規表現、タグ付共用体などを追加している。
SystemC
ハードウェア記述言語向けに拡張したもの。書式はC++。IEEE 1666-2005。ISO 8866:1991。
Impulse C英語版
ハードウェア記述言語向けに拡張したもの。書式はC。
Unified Parallel C
並列計算向けにC99を拡張して作られた言語。
Cg
C言語をGPU上での3次元コンピュータグラフィックス処理用に特化させたもの(シェーダー言語、シェーディング言語)。NVIDIAによって開発された。

その他にも、OpenGLシェーダー言語であるGLSLDirectXDirect3D)シェーダー言語であるHLSLOpenCLカーネル記述言語であるOpenCL-Cなど、C言語の文法的特徴を取り入れた派生言語やDSLが多数存在する。

注釈・出典

[編集]

注釈

[編集]
  1. ^ 英語ではC-family, C-style, C-likeなどと呼ばれる。「C系」の定義は明確ではないが、構文がCに類似しているものを指すことが多い。
  2. ^ 例えばポインタのエイリアシングは最適化やベクトル化を妨げる[1]
  3. ^ 他の言語、例えば、BASICPascalではプログラム開始直後に実行するプログラム要素はサブルーチンや手続きや関数ではない。
  4. ^ C89においては関数プロトタイプは必須ではない。
  5. ^ C89規格に準拠しないソースコードをGNU Cコンパイラでコンパイル失敗させるには、
    gcc -ansi -pedantic -fstrict-aliasing -Wall -Wextra -Wmissing-declarations -Werror test.c
    とすれば良い(→エイリアシング)。
  6. ^ setjmp.hを参照。

出典

[編集]
  1. ^ ポインター・エイリアシングとベクトル化 | iSUS
  2. ^ もう一度基礎からC言語 第19回 いろいろな演算子~ビット演算子 Cは高級アセンブラ?
  3. ^ 第1回 Chapter 1 C言語の概要(1):Cプログラミング入門|gihyo.jp … 技術評論社
  4. ^ ISO/IEC 14882:2003 §3.6.1 「The function main shall not be used within a program.」
  5. ^ JIS X 3014:2003「プログラム言語C++」日本産業標準調査会経済産業省) §3.6.1 「関数mainは、プログラムの中で挙用してはならない。」
  6. ^ EXP33-C. 未初期化のメモリを参照しない JPCERT/CC、2014年3月25日(2014年8月22日閲覧)。
  7. ^ Memory Allocation Guide”. The Linux Kernel documentation. 2023年11月8日閲覧。
  8. ^ main 関数 - cppreference.com
  9. ^ [Python入門]Pythonってどんな言語なの?:Python入門(1/2 ページ) - @IT
  10. ^ Hello, Worldプログラム | Programming Place Plus C言語編 第2章
  11. ^ Portability of C Programs and the UNIX Systems
  12. ^ a b The Evolution of the Unix Time-sharing System
  13. ^ ソースレベル互換 - ZDNet Japan
  14. ^ http://www.tohoho-web.com/ex/draft/kanji.htm
  15. ^ Rust言語でAndroidはより強固・安全に ~GoogleがOS開発への導入を進める - 窓の杜
  16. ^ Microsoft、Windows 10の一部をRustへ書き換えてセキュリティ強化狙う | TECH+
  17. ^ C FAQ 11
  18. ^ 6.19 Arrays of Variable Length
  19. ^ C の歴史 - cppreference.com
  20. ^ Clang 拡張 C++ コンパイラ - RAD Studio
  21. ^ Status of C99 features in GCC - GNU Project - Free Software Foundation (FSF)
  22. ^ C11Status - GCC Wiki
  23. ^ “Microsoft Releases C Program Wares, Provides Rebates”. InfoWorld: p. 29. (November 9, 1987). https://books.google.pl/books?id=Sj0EAAAAMBAJ 
  24. ^ インテル® C++ Composer XE 2011 Windows* 版インストール・ガイドおよびリリースノート - w_ccompxe_2011.7.258_Release_Notes_ja_JP.pdf
  25. ^ C99 Support in Intel® C++ Compiler | Intel® Software
  26. ^ C11 Support in Intel C++ Compiler | Intel® Software
  27. ^ 脇英世(監修)、1987、『パソコンの常識事典』、日本実業出版社 pp. 339、342 - 普及率、解説書の多さについて。
  28. ^ 長沢英夫(編)、1988、『パソコンベストソフトカタログ』、JICC出版局 pp. 201 - Personal版、解説書の多さについて。
  29. ^ ucom10 1983, p. 80.

参考文献

[編集]

2015年現在、初心者向けのイラスト入り入門書やサブルーチンのサンプル集の他、組み込み機器の制御や科学技術計算など目的を特化した専門書なども多数ある。便利な機能の説明はあっても、学習者の水準や目的にあった本を見つけるのは必ずしも容易でない。オープンソースのCコンパイラ、OSも大規模なものがあり、直接読み始めるのは困難になっている。オープンソースのOSの小規模なものから始めるとよい。

プログラミング言語C
ブライアン・カーニハン、デニス・リッチー 共著、石田晴久訳、共立出版
「K&R」として知られている「The C Programming Language」の邦訳。入門書ではなく、特にプログラミングそのものが初めてという読者には不適である。初版と第2版があり、第2版が現在も時折増刷されている(邦訳では事情により、原書第2版を基とした版には旧版と改訂新版がある。旧版は装丁が緑地で新版は白地である)。標準の制定以前は本書初版を言語仕様の参考文献として扱っていたが、現在はISOなどの標準規格を参照すべきであり、本書の記述は参考にとどめるべきである。なお、日本工業規格(現・日本産業規格)のJIS X 3010:2003「プログラム言語C」は、ISO/IEC JTC1 SC22 WG14+ISO/IEC 9899:1999 Cor. 1:2001(E)つまりC99の和訳相当で、2021年8月現在の最新規格であるISO/IEC 9899:2018との乖離を生じている。
Cプログラミングの落とし穴英語版
コーニグ、中村明訳、新紀元社
Cプログラミングで嵌まるところを指摘している。MISRA Cでも参考文献になっている。
Cパズルブック
アラン・R. フューアー、田中和明訳、カットシステム
Cプログラミングの芸当を示し、読み書きを推奨しない例を示している。
『マイコンピュータ No.10』CQ出版社、1983年9月1日。 
入門特集 C言語の研究

外部リンク

[編集]

ウィキメディア・コモンズには、C言語に関するメディアがあります。

日本語
英語