第1章: C言語の歴史と設計思想
1.1 C言語の誕生
前史: BCPL と B言語
C言語を理解するには、その前身となった言語の歴史を知る必要がある。
BCPL(Basic Combined Programming Language)は、1967年にMartin Richardsがケンブリッジ大学で開発した。BCPLは「システムプログラミング」のための言語として設計され、コンパイラを書くためのコンパイラを書く、というブートストラッピングの概念を実現した最初の言語の一つである。
BCPL の特徴:
- 型なし言語(全てがワード)
- ポインタ演算のサポート
- { } によるブロック構造
- // によるコメント(後にC++で復活)
1969年、Bell研究所のKen ThompsonはBCPLを簡略化したB言語を開発した。B言語はPDP-7上でUNIXを開発するために使われた。
/* B言語の例(1969年) */
main() {
extrn putchar;
auto c;
while ((c = getchar()) != '*e')
putchar(c);
}
B言語は型を持たず、全ての変数は機械語のワードサイズであった。
Dennis Ritchie と C言語の誕生
1971年から1973年にかけて、Bell研究所のDennis RitchieはB言語を拡張してC言語を開発した。
C言語が誕生した背景:
- 型システムの必要性: B言語は型を持たず、構造体やfloatを扱えなかった
- PDP-11への移植: PDP-11はバイトアドレッシングを持ち、型が必要だった
- UNIX書き直し: アセンブリ言語で書かれたUNIXを高級言語で書き直したかった
C言語の進化(Ritchieの論文より):
1971: 型の導入(int, char)
1972: 構造体(struct)の追加
1973: プリプロセッサの導入
1973: UNIXがCで書き直される
1973年、UNIX Version 4がC言語で書き直された。これは、オペレーティングシステムが高級言語で書かれた最初の例の一つとなった。
"The C Programming Language" (K&R)
1978年、Brian KernighanとDennis Ritchieは"The C Programming Language"(通称K&R)を出版した。この本は「プログラミング言語の教科書」の金字塔となり、「Hello, World」プログラムを広めた。
/* K&R 第1版(1978年)の Hello World */
main()
{
printf("hello, world\n");
}
K&Rスタイルの特徴:
- 関数の戻り値の型を省略可能(intがデフォルト)
- 引数の型は関数本体の前に宣言
- プロトタイプ宣言なし
/* K&R スタイルの関数定義 */
power(base, n)
int base, n;
{
int p;
for (p = 1; n > 0; --n)
p = p * base;
return p;
}
1.2 C言語の標準化
ANSI C (C89/C90)
1983年、ANSI(American National Standards Institute)はC言語の標準化委員会X3J11を設立した。1989年にANSI X3.159-1989(通称ANSI C または C89)が承認された。
1990年、ISOがこれを採用しISO/IEC 9899:1990(C90)となった。C89とC90は技術的に同一である。
ANSI C の主な変更点:
/* K&R スタイル */
int add(a, b)
int a, b;
{
return a + b;
}
/* ANSI C スタイル */
int add(int a, int b)
{
return a + b;
}
- void型の導入:
void do_nothing(void); /* 引数なし、戻り値なし */
- const修飾子:
const int MAX = 100;
const char *str = "constant string";
- volatile修飾子:
volatile int *hardware_register;
- 標準ライブラリの規定:
,,など- インライン関数:
C99
1999年、ISO/IEC 9899:1999(C99)が制定された。
C99 の主な追加機能:
inline int square(int x) { return x * x; }
- 変数宣言の自由化:
for (int i = 0; i < n; i++) { /* ブロック内で宣言可能 */
int temp = arr[i]; /* 使用直前で宣言可能 */
}
- 可変長配列(VLA):
void func(int n) {
int arr[n]; /* 実行時にサイズ決定 */
}
- // コメント:
// 1行コメント(BCPLから復活)
- long long int:
long long int big = 9223372036854775807LL;
- 複合リテラル:
struct point p = (struct point){.x = 10, .y = 20};
- 指定初期化子:
int arr[10] = {[5] = 100, [9] = 200};
- stdint.h:
#include <stdint.h>
int32_t fixed_size = 42;
uint64_t big_number = 0xFFFFFFFFFFFFFFFF;
C11
2011年、ISO/IEC 9899:2011(C11)が制定された。
C11 の主な追加機能:
- _Generic(型総称選択):
#define print_type(x) _Generic((x), \
int: "int", \
float: "float", \
double: "double", \
default: "unknown")
- マルチスレッドサポート:
#include <threads.h>
thrd_t thread;
thrd_create(&thread, my_func, NULL);
- 静的アサーション:
_Static_assert(sizeof(int) == 4, "int must be 4 bytes");
- 無名構造体・共用体:
struct {
union {
int i;
float f;
}; /* 無名共用体 */
} x;
x.i = 42; /* 直接アクセス可能 */
C17/C18
2018年、ISO/IEC 9899:2018(C17、正式にはC18)が制定された。これはC11の欠陥修正版であり、新機能は追加されていない。
C23
2024年、ISO/IEC 9899:2024(C23)が制定された。
C23 の主な追加機能:
- auto型推論:
auto x = 42; /* int */
auto y = 3.14; /* double */
- constexpr:
constexpr int SIZE = 100;
- nullptr:
int *p = nullptr; /* NULLの代替 */
- typeof演算子:
int x = 42;
typeof(x) y = 100; /* int y = 100 */
- 属性構文:
[[nodiscard]] int important_func(void);
1.3 C言語の設計思想
"Trust the Programmer"
C言語の設計思想は"Trust the Programmer"(プログラマを信頼する)である。これはBCPLから受け継がれた哲学である。
Dennis Ritchieの言葉: > "C is quirky, flawed, and an enormous success."
この思想の具体例:
- 境界チェックなし:
int arr[10];
arr[100] = 42; /* 未定義動作、しかしコンパイル可能 */
- 型キャストの自由:
int *p = (int *)0x12345678; /* 任意のアドレスにアクセス */
- メモリ管理の責任:
char *p = malloc(100);
/* freeを忘れてもエラーにならない */
抽象化と効率のバランス
C言語は「ポータブルアセンブリ」と呼ばれることがある。これは以下の特徴による:
- 機械に近い抽象化: ポインタ、ビット演算、直接メモリアクセス
- 最小限のランタイム: ガベージコレクタなし、例外処理なし
- 予測可能なコード生成: 各構文が生成するコードが予測可能
C言語の位置づけ:
アセンブリ ← C言語 ← C++ ← Java/Python
低レベル ←→ 高レベル
効率重視 ←→ 抽象化重視
UNIX哲学との関係
C言語はUNIX哲学と密接に関連している:
Ken Thompsonの言葉: > "When in doubt, use brute force."
1.4 C言語と他の言語
C言語の子孫たち
C言語は多くの言語に影響を与えた:
C言語の影響:
C (1972)
├── C++ (1983) - Bjarne Stroustrup
│ ├── Java (1995) - James Gosling
│ │ ├── C# (2000) - Anders Hejlsberg
│ │ └── Kotlin (2011) - JetBrains
│ └── D (2001) - Walter Bright
├── Objective-C (1984) - Brad Cox
│ └── Swift (2014) - Chris Lattner
├── Go (2009) - Rob Pike, Ken Thompson
└── Rust (2010) - Graydon Hoare
各言語との比較
C vs C++:
// C++: クラスとオーバーロード
class String {
public:
String operator+(const String& s);
};
/* C: 関数と構造体 */
struct String {
char *data;
};
struct String string_concat(struct String a, struct String b);
C vs Go:
// Go: ガベージコレクション、ゴルーチン
func main() {
go concurrent() // 軽量スレッド
}
/* C: 手動メモリ管理、pthread */
void *concurrent(void *arg);
pthread_create(&tid, NULL, concurrent, NULL);
C vs Rust:
// Rust: 所有権システム、ボローチェッカー
fn main() {
let s = String::from("hello");
let r = &s; // コンパイル時に安全性を保証
}
/* C: プログラマの責任 */
char *s = strdup("hello");
char *r = s; /* ダングリングポインタの可能性 */
1.5 なぜ今でもC言語を学ぶのか
システムプログラミングの基盤
現代のソフトウェアスタックにおいて、C言語は至る所に存在する:
- オペレーティングシステム: Linux, macOS, Windows(カーネル)
- 言語処理系: Python (CPython), Ruby, PHP
- データベース: PostgreSQL, MySQL, SQLite
- 組み込みシステム: 車載システム、IoTデバイス
- メモリモデル: スタック、ヒープ、ポインタ
- ABI: 関数呼び出し規約、レジスタの使用
- コンパイラ: 最適化、コード生成
- 基礎の理解: メモリ管理、ポインタの完全な理解
- 低レベルの視点: システムコール、OSとの対話
- 制約の中での創造: 限られた機能で問題を解決する力
- BCPL → B → C: 言語の進化
- Dennis Ritchie: C言語の創造者
- K&R: プログラミング教科書の原点
- 標準化: C89 → C99 → C11 → C17 → C23
- 設計思想: "Trust the Programmer"
- 影響: C++, Java, Go, Rustへの影響
- Ritchie, D. M. (1993). "The Development of the C Language", Second ACM SIGPLAN History of Programming Languages Conference
- Kernighan, B. W., & Ritchie, D. M. (1978). "The C Programming Language", Prentice Hall
- Kernighan, B. W., & Ritchie, D. M. (1988). "The C Programming Language", 2nd Edition, Prentice Hall
- ISO/IEC 9899:1990, Programming languages — C
- ISO/IEC 9899:1999, Programming languages — C
- ISO/IEC 9899:2011, Programming languages — C
- ISO/IEC 9899:2018, Programming languages — C
- Richards, M. (1969). "BCPL: A tool for compiler writing and system programming", Proc. AFIPS Spring Joint Computer Conference
- Thompson, K. (1972). "Users' Reference to B", Bell Telephone Laboratories
コンピュータの理解
C言語を学ぶことは、コンピュータそのものを理解することにつながる:
42カリキュラムとC言語
42のカリキュラムでC言語から始める理由:
1.6 まとめ
本章では、C言語の歴史と設計思想について学んだ:
次章では、C言語の基本文法について学ぶ。
---