第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デバイス
  • コンピュータの理解

    C言語を学ぶことは、コンピュータそのものを理解することにつながる:

  • メモリモデル: スタック、ヒープ、ポインタ
  • ABI: 関数呼び出し規約、レジスタの使用
  • コンパイラ: 最適化、コード生成
  • 42カリキュラムとC言語

    42のカリキュラムでC言語から始める理由:

  • 基礎の理解: メモリ管理、ポインタの完全な理解
  • 低レベルの視点: システムコール、OSとの対話
  • 制約の中での創造: 限られた機能で問題を解決する力
  • 1.6 まとめ

    本章では、C言語の歴史と設計思想について学んだ:

  • BCPL → B → C: 言語の進化
  • Dennis Ritchie: C言語の創造者
  • K&R: プログラミング教科書の原点
  • 標準化: C89 → C99 → C11 → C17 → C23
  • 設計思想: "Trust the Programmer"
  • 影響: C++, Java, Go, Rustへの影響
  • 次章では、C言語の基本文法について学ぶ。

    ---

    参考文献

  • 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