Cは、Unix というOSを書くために1972年にベル研究所のデニス・リッチーが作った、コンパイル型の汎用プログラミング言語です。同時代のほとんどすべてより長生きしており、理由は単純です。Cは機械のすぐ1枚上の薄い層に座っています。メモリとCPUの本当の能力に直接アクセスさせながら、なお人が書いたもののように読めるのです。
半世紀のち、それは今なお他の言語がその中で作られる言語であり続けています。
完全なCのプログラム
この言語の姿の全体が6行にあります。Run を押してみてください。
#include <stdio.h> は標準入出力の宣言を取り込み、printf が分かるようにします。main はどのCプログラムも始まる場所です。printf はテキストを書き、\n は改行、return 0 はプログラムが正常に終わったことをOSに伝えます。これで完全でコンパイル可能なプログラムです - 包むクラスも、下に敷くフレームワークもありません。
Cを他と分けるもの
現代の言語のほとんどは機械をあなたから隠します。Cは意図的にそうしません。
- ネイティブコードにコンパイルされる。 Cのプログラムは1つのCPUのための機械命令になり、間にインタプリタも仮想マシンも挟まずに直接走ります。
- メモリは自分で管理する。 ガベージコレクタはありません。メモリを要求し、そして返します。手間は増えますが、だからこそCのプログラムはメモリ使用量が少なく、タイミングが予測しやすいのです。
- 小さい。 Cのキーワードは約32個です。言語全体を頭の中に収められます - C++、Java、Pythonではそうはいきません。
- ランタイムがほとんどない。 Cのプログラムは数キロバイトのRAMしかなくOSもないマイコン上で走れます。
その取引は、安全性よりも正直さです。Cは配列の末尾を越えて読むことも、すでに解放したメモリを使うことも許し、止めてくれません。それらの間違いには名前があります - セグメンテーション違反、メモリリーク、未定義動作 - そしてCを学ぶとは、おおむねそれらを避けられるようになることです。
Cが実際に動いている場所
Cは歴史上の珍品ではありません。あなたがこれを読んでいる機器の上で、何重にも走っています。
- OS。 Linuxカーネルはおよそ3000万行のCです。WindowsやAppleのカーネルの大きな部分もCです。
- 組み込みシステム。 自動車、サーモスタット、医療機器、ルーター、洗濯機の中のマイコンは圧倒的にCでプログラムされています。チップ全体でメモリが 32 KB しかないとき、Cが唯一現実的な選択肢であることも多いのです。
- データベース。 SQLite、PostgreSQL、MySQL、Redis はCのプログラムです。
- 言語ランタイム。 Pythonの参照実装 CPython はCで書かれています。Rubyの MRI、PHPの Zend エンジン、Lua の中核も同じです。Pythonが「遅すぎる」とき、その解決策はたいていCの拡張です。
- ツールとライブラリ。 Git、curl、FFmpeg、OpenSSL、zlib、そしてまた SQLite - コンピューティングの基盤層はCです。
だからこそCのアプリケーションバイナリインターフェースが重要なのです。ほぼすべての言語がCの関数を呼べます。Python、Rust、Go、Java、JavaScript のどれにもCのライブラリへ手を伸ばす方法があります。Cは言語どうしの共通語なのです。
Cを学ぶ理由
正直な答えが2つあり、それぞれ違う人に向いています。
システム - カーネル、ドライバ、組み込みファームウェア、データベース - の仕事をしたいなら、Cはその分野の実務言語であり、その領域の求人のほとんどが(多くはC++やRustと並べて)Cを直接名指しします。Linux や PostgreSQL、マイクロコントローラのコードベースに貢献するのは、Cを苦もなく読めなければ難しいことです。
すでに使っている言語でもっと上達したいなら、Cはその下に何があるかを教えてくれます。Cのあとでは、配列の添字がなぜ0から始まるのか、文字列とは本当は何なのか、大きなオブジェクトを値で渡すのがなぜ高くつくのか、スタックとヒープとは何か、ヌルポインタは実際に何を指しているのかが分かります。これらの概念はどの言語にも現れます。Cはそれらが隠されずに見えている場所なのです。
このプログラムはCの3行であり、同時に変数とは何かの完全な実演でもあります。アドレスにある名前の付いた箱です。ほとんどの言語では、そもそもその問いを立てることすらできません。
CとC++
C++は1979年に「クラス付きのC」として始まり、現存する最大級の言語へと育ちました。クラス、テンプレート、例外、演算子多重定義、STL、スマートポインタ、そしてCの仕様全体を小さく見せる標準ライブラリ。
実際の関係はこうです。
- C++はCの構文を保ったので、
if、for、while、演算子、ポインタ、配列はどちらでも同じに見えます。 - きちんと書かれたCのほとんどはC++としてコンパイルできます(いくつか例外はあり、たとえばC++では
mallocの結果をキャストする必要があります)。 - C++のコードが妥当なCであることはほとんどありません。
両方を学ぶつもりなら、先にCを学ぶのは本当に有利です。C++はCのメモリモデルの上に直接築かれており、C++で最も人を混乱させる部分 - ポインタ、参照、コピーの意味論、デストラクタ - はどれも、Cが平明に見せてくれる問題への答えだからです。
とはいえCは、公式にはC++の部分集合ではありません。別々に発展する別々の規格であり、現代のCにはC++にない機能があります(C99で登場した指示付き初期化子、restrict ポインタ、可変長配列)。
どのC:規格のバージョン
Cは標準化されており、古いコードを読むときにはそのバージョンが効いてきます。
| 規格 | 年 | 知っておく価値 |
|---|---|---|
| C89 / C90 | 1989 | 古の基準。変数はブロックの先頭でしか宣言できない。 |
| C99 | 1999 | // コメント、どこでも変数宣言、stdbool.h による bool、long long |
| C11 | 2011 | スレッド、アトミック、より安全なライブラリ関数 |
| C17 | 2018 | C11のバグ修正版 - 今日の一般的な既定 |
| C23 | 2024 | キーワードとしての true/false/bool、nullptr、2進リテラル |
このドキュメントは C17 を対象とし、C99以降の機能は重要な箇所で明示します。コンパイラの既定は現代的なものですが、明示することもできます。
gcc -std=c17 -Wall -Wextra hello.c -o hello
Cにないもの
Cを理解することの一部は、何が欠けているかを知ることです。ほぼすべての「どうやって…?」という問いが、現代の言語とは違う答えを持つからです。
- 文字列がない。 Cの文字列はゼロバイトで終わる
charの配列です。2つをつなぐとは、関数を呼び、格納先が十分大きいか心配することです。 - コレクションがない。 リストもマップも集合もありません。あるのは固定長の配列とポインタで、ハッシュ表は自分で書くかライブラリをリンクするものです。
- 例外がない。 関数は特別な値 -
-1、NULL、ステータスコード - を返して失敗を報告し、呼び出し元が確認することが期待されます。 - ジェネリクスも多重定義もない。 1つの関数名は1つの関数を意味します。だから標準ライブラリには3つの異なる型のために
abs、labs、fabsがあるのです。 - 名前空間もモジュールもない。
staticでないすべての関数が1つのグローバル名前空間を共有するので、Cのライブラリはすべてに接頭辞を付けます(sqlite3_open、png_read_info)。 - ガベージコレクタがない。 どの
mallocにも対応するfreeが必要で、忘れればメモリリークです。
これらはどれも見落としではありません。一部はCが背負うことを拒んだ実行時の仕掛け(ガベージコレクタ、例外の巻き戻し、伸長する文字列)であり、RAMが 2 KB のチップに収まる理由の大きな部分がそこにあります。名前空間やジェネリクスのような他のものは、単にCの設計より後に生まれた言語機能で、言語を小さく保つために取り込まれなかったのです。
バッファが32バイトなのは、あなたがそれで足りると決めたからです。Cは確かめてくれませんし、その決断こそこの言語の性格のすべてを1行で表しています。
Cは難しいか?
Cは小さく、そして容赦がありません。覚えるべき構文は多くなく、言語全体を1週間で読めます。時間がかかるのは規律のほうです。どのメモリを誰が所有しているかを追い、文字列がゼロで終わるただのバイト列だと覚えておき、ポインタをたどる前にヌルでないか確認すること。
Cの難しさの大半は、概念ではなくガードレールの無さにあります。コンパイラは範囲外への書き込みやダングリングポインタから救ってくれないので、正確であることを学ぶのです。(ポインタそのものは、最初は本当に骨が折れます - それが普通で、ポインタの章はゆっくり進みます。)その正確さは、あとで使うどの言語にも引き継がれる技能です。
よくある質問
C言語とは何ですか?
Cは1972年にベル研究所のデニス・リッチーが作った、コンパイル型の汎用プログラミング言語です。メモリを直接制御でき、CPUが実際に行うことに近く対応づいているので、OS、デバイスドライバ、データベースが今なおCで書かれています。
C言語は今日どこで使われていますか?
OSのカーネル(Linux、WindowsやmacOSの一部)、自動車・家電・マイコンの組み込みファームウェア、SQLite や PostgreSQL といったデータベース、CPython や Redis のような言語ランタイム、そして他の言語から呼ばれる性能が重要なライブラリです。
2026年にC言語を学ぶ価値はありますか?
はい、2つの理由で。今もシステムと組み込みの仕事の言語であり、そこは大きく報酬も良い分野です。そしてメモリ、ポインタ、スタックが実際にどう動くかを教えてくれます - 他のほとんどの言語がCで実装されているので、この知識はどの言語でもあなたを上達させます。
C言語とC++の違いは何ですか?
C++は「クラス付きのC」として始まり、Cの構文の大半を保ったまま、オブジェクト指向、テンプレート、標準ライブラリなどを加えました。Cははるかに小さく、クラスも例外もジェネリクスもありません。妥当なCのほとんどはC++としてコンパイルできますが、その逆はできません。